@homebridge-plugins/homebridge-tuya 3.0.0-beta.2 → 3.0.0-beta.21

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 (298) hide show
  1. package/README.md +354 -142
  2. package/config.schema.json +1221 -893
  3. package/dist/cloud/api/TuyaOpenAPI.js +108 -60
  4. package/dist/cloud/api/TuyaOpenAPI.js.map +1 -1
  5. package/dist/cloud/api/TuyaOpenMQ.js +45 -22
  6. package/dist/cloud/api/TuyaOpenMQ.js.map +1 -1
  7. package/dist/cloud/device/{TuyaDeviceManager.js → TuyaCloudDeviceManager.js} +146 -96
  8. package/dist/cloud/device/TuyaCloudDeviceManager.js.map +1 -0
  9. package/dist/cloud/device/TuyaCustomDeviceManager.js +75 -5
  10. package/dist/cloud/device/TuyaCustomDeviceManager.js.map +1 -1
  11. package/dist/cloud/device/TuyaDevice.js.map +1 -1
  12. package/dist/cloud/device/TuyaHomeDeviceManager.js +81 -13
  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 +16 -3
  19. package/dist/local/LocalDevice.js.map +1 -1
  20. package/dist/local/LocalDeviceManager.js +361 -164
  21. package/dist/local/LocalDeviceManager.js.map +1 -1
  22. package/dist/local/TuyaDiscovery.js +16 -7
  23. package/dist/local/TuyaDiscovery.js.map +1 -1
  24. package/dist/local/ZigbeeGatewayDetection.js +7 -4
  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 +253 -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 +147 -0
  41. package/dist/shared/TuyaDeviceManager.js.map +1 -0
  42. package/dist/shared/TuyaHybridDeviceManager.js +215 -0
  43. package/dist/shared/TuyaHybridDeviceManager.js.map +1 -0
  44. package/dist/shared/accessory/AccessoryFactory.js +350 -0
  45. package/dist/shared/accessory/AccessoryFactory.js.map +1 -0
  46. package/dist/shared/{accessories → accessory}/AirConditionerAccessory.js +21 -15
  47. package/dist/shared/accessory/AirConditionerAccessory.js.map +1 -0
  48. package/dist/shared/{accessories → accessory}/AirPurifierAccessory.js.map +1 -1
  49. package/dist/shared/accessory/AirQualitySensorAccessory.js.map +1 -0
  50. package/dist/shared/{accessories → accessory}/BaseAccessory.js +16 -95
  51. package/dist/shared/accessory/BaseAccessory.js.map +1 -0
  52. package/dist/shared/{accessories → accessory}/BlindsAccessory.js.map +1 -1
  53. package/dist/shared/{accessories → accessory}/CameraAccessory.js +2 -2
  54. package/dist/shared/accessory/CameraAccessory.js.map +1 -0
  55. package/dist/shared/{accessories → accessory}/CarbonDioxideSensorAccessory.js.map +1 -1
  56. package/dist/shared/{accessories → accessory}/CarbonMonoxideSensorAccessory.js.map +1 -1
  57. package/dist/shared/{accessories → accessory}/ContactSensorAccessory.js.map +1 -1
  58. package/dist/shared/{accessories → accessory}/DehumidifierAccessory.js.map +1 -1
  59. package/dist/shared/{accessories → accessory}/DiffuserAccessory.js.map +1 -1
  60. package/dist/shared/{accessories → accessory}/DimmerAccessory.js.map +1 -1
  61. package/dist/shared/{accessories → accessory}/DoorbellAccessory.js.map +1 -1
  62. package/dist/shared/{accessories → accessory}/ExtractionHoodAccessory.js.map +1 -1
  63. package/dist/shared/{accessories → accessory}/FanAccessory.js.map +1 -1
  64. package/dist/shared/{accessories → accessory}/GarageDoorAccessory.js +19 -2
  65. package/dist/shared/accessory/GarageDoorAccessory.js.map +1 -0
  66. package/dist/shared/{accessories → accessory}/HeaterAccessory.js.map +1 -1
  67. package/dist/shared/{accessories → accessory}/HeaterAccessory_old.js.map +1 -1
  68. package/dist/shared/accessory/HumanPresenceSensorAccessory.js.map +1 -0
  69. package/dist/shared/{accessories → accessory}/HumidifierAccessory.js.map +1 -1
  70. package/dist/shared/accessory/IRAdapter.js +167 -0
  71. package/dist/shared/accessory/IRAdapter.js.map +1 -0
  72. package/dist/shared/accessory/IRAirConditionerAccessory.js.map +1 -0
  73. package/dist/shared/accessory/IRControlHubAccessory.js.map +1 -0
  74. package/dist/shared/accessory/IRControlHubSubAccessory.js.map +1 -0
  75. package/dist/shared/accessory/IRFanAccessory.js +90 -0
  76. package/dist/shared/accessory/IRFanAccessory.js.map +1 -0
  77. package/dist/shared/accessory/IRGenericAccessory.js.map +1 -0
  78. package/dist/shared/{accessories → accessory}/LeakSensorAccessory.js.map +1 -1
  79. package/dist/shared/{accessories → accessory}/LightAccessory.js.map +1 -1
  80. package/dist/shared/{accessories → accessory}/LightSensorAccessory.js.map +1 -1
  81. package/dist/shared/{accessories → accessory}/LocationWeatherAccessory.js +1 -1
  82. package/dist/shared/accessory/LocationWeatherAccessory.js.map +1 -0
  83. package/dist/shared/{accessories → accessory}/LockAccessory.js +3 -3
  84. package/dist/shared/{accessories → accessory}/LockAccessory.js.map +1 -1
  85. package/dist/shared/accessory/MotionSensorAccessory.js.map +1 -0
  86. package/dist/shared/accessory/OutletAccessory.js.map +1 -0
  87. package/dist/shared/{accessories → accessory}/PetFeederAccessory.js.map +1 -1
  88. package/dist/shared/{accessories → accessory}/SceneAccessory.js +1 -1
  89. package/dist/shared/accessory/SceneAccessory.js.map +1 -0
  90. package/dist/shared/accessory/SceneSwitchAccessory.js.map +1 -0
  91. package/dist/shared/accessory/SecuritySystemAccessory.js.map +1 -0
  92. package/dist/shared/{accessories → accessory}/SmokeSensorAccessory.js.map +1 -1
  93. package/dist/shared/{accessories → accessory}/SwitchAccessory.js +1 -45
  94. package/dist/shared/accessory/SwitchAccessory.js.map +1 -0
  95. package/dist/shared/accessory/TemperatureHumiditySensorAccessory.js.map +1 -0
  96. package/dist/shared/{accessories → accessory}/ThermostatAccessory.js.map +1 -1
  97. package/dist/shared/{accessories → accessory}/TowerRackAccessory.js.map +1 -1
  98. package/dist/shared/{accessories → accessory}/ValveAccessory.js.map +1 -1
  99. package/dist/shared/{accessories → accessory}/VibrationSensorAccessory.js.map +1 -1
  100. package/dist/shared/accessory/WeatherStationAccessory.js.map +1 -0
  101. package/dist/shared/accessory/WetBulbGlobeTemperatureAccessory.js.map +1 -0
  102. package/dist/shared/{accessories → accessory}/WhiteNoiseLightAccessory.js +1 -0
  103. package/dist/shared/accessory/WhiteNoiseLightAccessory.js.map +1 -0
  104. package/dist/shared/accessory/WindowAccessory.js.map +1 -0
  105. package/dist/shared/{accessories → accessory}/WindowCoveringAccessory.js.map +1 -1
  106. package/dist/shared/{accessories → accessory}/WirelessSwitchAccessory.js.map +1 -1
  107. package/dist/shared/accessory/characteristic/Active.js.map +1 -0
  108. package/dist/shared/accessory/characteristic/AirQuality.js.map +1 -0
  109. package/dist/shared/{accessories → accessory}/characteristic/CurrentRelativeHumidity.js +3 -0
  110. package/dist/shared/accessory/characteristic/CurrentRelativeHumidity.js.map +1 -0
  111. package/dist/shared/accessory/characteristic/CurrentTemperature.js.map +1 -0
  112. package/dist/shared/accessory/characteristic/CurrentWeather.js.map +1 -0
  113. package/dist/shared/accessory/characteristic/CurrentWeatherByOpenMeteo.js.map +1 -0
  114. package/dist/shared/{accessories → accessory}/characteristic/CurrentWetBulbGlobeTemperature.js +3 -2
  115. package/dist/shared/accessory/characteristic/CurrentWetBulbGlobeTemperature.js.map +1 -0
  116. package/dist/shared/{accessories → accessory}/characteristic/EnergyUsage.js +0 -5
  117. package/dist/shared/accessory/characteristic/EnergyUsage.js.map +1 -0
  118. package/dist/shared/{accessories → accessory}/characteristic/Light.js +28 -5
  119. package/dist/shared/accessory/characteristic/Light.js.map +1 -0
  120. package/dist/shared/accessory/characteristic/LightSensor.js.map +1 -0
  121. package/dist/shared/{accessories → accessory}/characteristic/LockPhysicalControls.js +3 -0
  122. package/dist/shared/accessory/characteristic/LockPhysicalControls.js.map +1 -0
  123. package/dist/shared/accessory/characteristic/MotionDetected.js.map +1 -0
  124. package/dist/shared/accessory/characteristic/Name.js.map +1 -0
  125. package/dist/shared/accessory/characteristic/OccupancyDetected.js.map +1 -0
  126. package/dist/shared/{accessories → accessory}/characteristic/On.js +1 -0
  127. package/dist/shared/accessory/characteristic/On.js.map +1 -0
  128. package/dist/shared/accessory/characteristic/OutletInUse.js.map +1 -0
  129. package/dist/shared/accessory/characteristic/ProgrammableSwitchEvent.js.map +1 -0
  130. package/dist/shared/{accessories → accessory}/characteristic/RelativeHumidityDehumidifierThreshold.js +3 -0
  131. package/dist/shared/accessory/characteristic/RelativeHumidityDehumidifierThreshold.js.map +1 -0
  132. package/dist/shared/accessory/characteristic/RotationSpeed.js.map +1 -0
  133. package/dist/shared/accessory/characteristic/SecuritySystemState.js.map +1 -0
  134. package/dist/shared/{accessories → accessory}/characteristic/SwingMode.js +3 -0
  135. package/dist/shared/accessory/characteristic/SwingMode.js.map +1 -0
  136. package/dist/shared/accessory/characteristic/TargetTemperature.js.map +1 -0
  137. package/dist/shared/accessory/characteristic/TemperatureDisplayUnits.js.map +1 -0
  138. package/dist/shared/util/ConfigHash.js +2 -2
  139. package/dist/shared/util/ConfigHash.js.map +1 -1
  140. package/dist/shared/util/ConfigMigrator.js +222 -0
  141. package/dist/shared/util/ConfigMigrator.js.map +1 -0
  142. package/dist/shared/util/FfmpegStreamingProcess.js +62 -0
  143. package/dist/shared/util/FfmpegStreamingProcess.js.map +1 -1
  144. package/dist/shared/util/InfraredTool.js +0 -2
  145. package/dist/shared/util/InfraredTool.js.map +1 -1
  146. package/dist/shared/util/Logger.js +85 -10
  147. package/dist/shared/util/Logger.js.map +1 -1
  148. package/dist/shared/util/TuyaStreamDelegate.js +194 -97
  149. package/dist/shared/util/TuyaStreamDelegate.js.map +1 -1
  150. package/dist/shared/util/util.js +59 -4
  151. package/dist/shared/util/util.js.map +1 -1
  152. package/docs/ADVANCED_OPTIONS.md +603 -0
  153. package/docs/CONFIG_GUIDE.md +616 -0
  154. package/docs/Get-Local-Keys-for-Your-Devices.md +246 -0
  155. package/{SUPPORTED_DEVICES.md → docs/SUPPORTED_DEVICES.md} +24 -3
  156. package/eslint.config.mjs +0 -1
  157. package/{jest.config.js → jest.config.ts} +5 -2
  158. package/package.json +12 -9
  159. package/test/ConfigMigrator.test.ts +1060 -0
  160. package/test/Logger.test.ts +482 -0
  161. package/test/accessoryFactory.data.test.ts +172 -0
  162. package/test/accessoryFactory.test.ts +64 -35
  163. package/test/airConditioner.test.ts +742 -0
  164. package/test/config.test.ts +17 -13
  165. package/test/custom.test.ts +2 -2
  166. package/test/errorHandling.test.ts +12 -12
  167. package/test/home.test.ts +1 -1
  168. package/test/hybridDeviceManager.test.ts +808 -0
  169. package/test/light.test.ts +250 -0
  170. package/test/localDevice.test.ts +21 -50
  171. package/test/localDeviceManager.behavior.test.ts +196 -31
  172. package/test/localDeviceManager.test.ts +124 -41
  173. package/test/mqttMessages.test.ts +33 -14
  174. package/test/platform.test.ts +337 -814
  175. package/test/platform.validation.local.test.ts +58 -119
  176. package/test/tuyaCustomDeviceManager.test.ts +106 -16
  177. package/test/tuyaDeviceManager.test.ts +636 -639
  178. package/test/tuyaDiscovery.test.ts +21 -33
  179. package/test/tuyaHomeDeviceManager.test.ts +109 -18
  180. package/test/tuyaOpenAPI.test.ts +25 -44
  181. package/test/tuyaOpenMQ.test.ts +15 -23
  182. package/test/util.test.ts +107 -7
  183. package/test/zigbee/LocalDevice.zigbee.test.ts +14 -18
  184. package/test/zigbee/LocalDeviceManager.cloud-discovery.test.ts +19 -20
  185. package/test/zigbee/LocalDeviceManager.zigbee.reconnect.test.ts +19 -20
  186. package/test/zigbee/LocalDeviceManager.zigbee.test.ts +73 -35
  187. package/test/zigbee/ZigbeeGatewayDetection.test.ts +2 -2
  188. package/ADVANCED_OPTIONS.md +0 -267
  189. package/dist/cloud/device/TuyaDeviceManager.js.map +0 -1
  190. package/dist/local/CloudLocalReconciliation.js +0 -180
  191. package/dist/local/CloudLocalReconciliation.js.map +0 -1
  192. package/dist/shared/AccessoryFactory.js +0 -276
  193. package/dist/shared/AccessoryFactory.js.map +0 -1
  194. package/dist/shared/accessories/AccessoryFactory.js +0 -305
  195. package/dist/shared/accessories/AccessoryFactory.js.map +0 -1
  196. package/dist/shared/accessories/AirConditionerAccessory.js.map +0 -1
  197. package/dist/shared/accessories/AirQualitySensorAccessory.js.map +0 -1
  198. package/dist/shared/accessories/BaseAccessory.js.map +0 -1
  199. package/dist/shared/accessories/CameraAccessory.js.map +0 -1
  200. package/dist/shared/accessories/GarageDoorAccessory.js.map +0 -1
  201. package/dist/shared/accessories/HumanPresenceSensorAccessory.js.map +0 -1
  202. package/dist/shared/accessories/IRAirConditionerAccessory.js.map +0 -1
  203. package/dist/shared/accessories/IRControlHubAccessory.js.map +0 -1
  204. package/dist/shared/accessories/IRControlHubSubAccessory.js.map +0 -1
  205. package/dist/shared/accessories/IRGenericAccessory.js.map +0 -1
  206. package/dist/shared/accessories/LocationWeatherAccessory.js.map +0 -1
  207. package/dist/shared/accessories/MotionSensorAccessory.js.map +0 -1
  208. package/dist/shared/accessories/OutletAccessory.js.map +0 -1
  209. package/dist/shared/accessories/SceneAccessory.js.map +0 -1
  210. package/dist/shared/accessories/SceneSwitchAccessory.js.map +0 -1
  211. package/dist/shared/accessories/SecuritySystemAccessory.js.map +0 -1
  212. package/dist/shared/accessories/SwitchAccessory.js.map +0 -1
  213. package/dist/shared/accessories/TemperatureHumiditySensorAccessory.js.map +0 -1
  214. package/dist/shared/accessories/WeatherStationAccessory.js.map +0 -1
  215. package/dist/shared/accessories/WetBulbGlobeTemperatureAccessory.js.map +0 -1
  216. package/dist/shared/accessories/WhiteNoiseLightAccessory.js.map +0 -1
  217. package/dist/shared/accessories/WindowAccessory.js.map +0 -1
  218. package/dist/shared/accessories/characteristic/Active.js.map +0 -1
  219. package/dist/shared/accessories/characteristic/AirQuality.js.map +0 -1
  220. package/dist/shared/accessories/characteristic/CurrentRelativeHumidity.js.map +0 -1
  221. package/dist/shared/accessories/characteristic/CurrentTemperature.js.map +0 -1
  222. package/dist/shared/accessories/characteristic/CurrentWeather.js.map +0 -1
  223. package/dist/shared/accessories/characteristic/CurrentWeatherByOpenMeteo.js.map +0 -1
  224. package/dist/shared/accessories/characteristic/CurrentWetBulbGlobeTemperature.js.map +0 -1
  225. package/dist/shared/accessories/characteristic/EnergyUsage.js.map +0 -1
  226. package/dist/shared/accessories/characteristic/Light.js.map +0 -1
  227. package/dist/shared/accessories/characteristic/LightSensor.js.map +0 -1
  228. package/dist/shared/accessories/characteristic/LockPhysicalControls.js.map +0 -1
  229. package/dist/shared/accessories/characteristic/MotionDetected.js.map +0 -1
  230. package/dist/shared/accessories/characteristic/Name.js.map +0 -1
  231. package/dist/shared/accessories/characteristic/OccupancyDetected.js.map +0 -1
  232. package/dist/shared/accessories/characteristic/On.js.map +0 -1
  233. package/dist/shared/accessories/characteristic/OutletInUse.js.map +0 -1
  234. package/dist/shared/accessories/characteristic/ProgrammableSwitchEvent.js.map +0 -1
  235. package/dist/shared/accessories/characteristic/RelativeHumidityDehumidifierThreshold.js.map +0 -1
  236. package/dist/shared/accessories/characteristic/RotationSpeed.js.map +0 -1
  237. package/dist/shared/accessories/characteristic/SecuritySystemState.js.map +0 -1
  238. package/dist/shared/accessories/characteristic/SwingMode.js.map +0 -1
  239. package/dist/shared/accessories/characteristic/TargetTemperature.js.map +0 -1
  240. package/dist/shared/accessories/characteristic/TemperatureDisplayUnits.js.map +0 -1
  241. package/test/zigbee/CloudLocalReconciliation.test.ts +0 -284
  242. package/tuya-local-configs/dev-1.hash +0 -1
  243. package/tuya-local-configs/device1.hash +0 -1
  244. package/wiki/Get-Local-Keys-for-Your-Devices.md +0 -85
  245. /package/dist/shared/{accessories → accessory}/AirPurifierAccessory.js +0 -0
  246. /package/dist/shared/{accessories → accessory}/AirQualitySensorAccessory.js +0 -0
  247. /package/dist/shared/{accessories → accessory}/BlindsAccessory.js +0 -0
  248. /package/dist/shared/{accessories → accessory}/CarbonDioxideSensorAccessory.js +0 -0
  249. /package/dist/shared/{accessories → accessory}/CarbonMonoxideSensorAccessory.js +0 -0
  250. /package/dist/shared/{accessories → accessory}/ContactSensorAccessory.js +0 -0
  251. /package/dist/shared/{accessories → accessory}/DehumidifierAccessory.js +0 -0
  252. /package/dist/shared/{accessories → accessory}/DiffuserAccessory.js +0 -0
  253. /package/dist/shared/{accessories → accessory}/DimmerAccessory.js +0 -0
  254. /package/dist/shared/{accessories → accessory}/DoorbellAccessory.js +0 -0
  255. /package/dist/shared/{accessories → accessory}/ExtractionHoodAccessory.js +0 -0
  256. /package/dist/shared/{accessories → accessory}/FanAccessory.js +0 -0
  257. /package/dist/shared/{accessories → accessory}/HeaterAccessory.js +0 -0
  258. /package/dist/shared/{accessories → accessory}/HeaterAccessory_old.js +0 -0
  259. /package/dist/shared/{accessories → accessory}/HumanPresenceSensorAccessory.js +0 -0
  260. /package/dist/shared/{accessories → accessory}/HumidifierAccessory.js +0 -0
  261. /package/dist/shared/{accessories → accessory}/IRAirConditionerAccessory.js +0 -0
  262. /package/dist/shared/{accessories → accessory}/IRControlHubAccessory.js +0 -0
  263. /package/dist/shared/{accessories → accessory}/IRControlHubSubAccessory.js +0 -0
  264. /package/dist/shared/{accessories → accessory}/IRGenericAccessory.js +0 -0
  265. /package/dist/shared/{accessories → accessory}/LeakSensorAccessory.js +0 -0
  266. /package/dist/shared/{accessories → accessory}/LightAccessory.js +0 -0
  267. /package/dist/shared/{accessories → accessory}/LightSensorAccessory.js +0 -0
  268. /package/dist/shared/{accessories → accessory}/MotionSensorAccessory.js +0 -0
  269. /package/dist/shared/{accessories → accessory}/OutletAccessory.js +0 -0
  270. /package/dist/shared/{accessories → accessory}/PetFeederAccessory.js +0 -0
  271. /package/dist/shared/{accessories → accessory}/SceneSwitchAccessory.js +0 -0
  272. /package/dist/shared/{accessories → accessory}/SecuritySystemAccessory.js +0 -0
  273. /package/dist/shared/{accessories → accessory}/SmokeSensorAccessory.js +0 -0
  274. /package/dist/shared/{accessories → accessory}/TemperatureHumiditySensorAccessory.js +0 -0
  275. /package/dist/shared/{accessories → accessory}/ThermostatAccessory.js +0 -0
  276. /package/dist/shared/{accessories → accessory}/TowerRackAccessory.js +0 -0
  277. /package/dist/shared/{accessories → accessory}/ValveAccessory.js +0 -0
  278. /package/dist/shared/{accessories → accessory}/VibrationSensorAccessory.js +0 -0
  279. /package/dist/shared/{accessories → accessory}/WeatherStationAccessory.js +0 -0
  280. /package/dist/shared/{accessories → accessory}/WetBulbGlobeTemperatureAccessory.js +0 -0
  281. /package/dist/shared/{accessories → accessory}/WindowAccessory.js +0 -0
  282. /package/dist/shared/{accessories → accessory}/WindowCoveringAccessory.js +0 -0
  283. /package/dist/shared/{accessories → accessory}/WirelessSwitchAccessory.js +0 -0
  284. /package/dist/shared/{accessories → accessory}/characteristic/Active.js +0 -0
  285. /package/dist/shared/{accessories → accessory}/characteristic/AirQuality.js +0 -0
  286. /package/dist/shared/{accessories → accessory}/characteristic/CurrentTemperature.js +0 -0
  287. /package/dist/shared/{accessories → accessory}/characteristic/CurrentWeather.js +0 -0
  288. /package/dist/shared/{accessories → accessory}/characteristic/CurrentWeatherByOpenMeteo.js +0 -0
  289. /package/dist/shared/{accessories → accessory}/characteristic/LightSensor.js +0 -0
  290. /package/dist/shared/{accessories → accessory}/characteristic/MotionDetected.js +0 -0
  291. /package/dist/shared/{accessories → accessory}/characteristic/Name.js +0 -0
  292. /package/dist/shared/{accessories → accessory}/characteristic/OccupancyDetected.js +0 -0
  293. /package/dist/shared/{accessories → accessory}/characteristic/OutletInUse.js +0 -0
  294. /package/dist/shared/{accessories → accessory}/characteristic/ProgrammableSwitchEvent.js +0 -0
  295. /package/dist/shared/{accessories → accessory}/characteristic/RotationSpeed.js +0 -0
  296. /package/dist/shared/{accessories → accessory}/characteristic/SecuritySystemState.js +0 -0
  297. /package/dist/shared/{accessories → accessory}/characteristic/TargetTemperature.js +0 -0
  298. /package/dist/shared/{accessories → accessory}/characteristic/TemperatureDisplayUnits.js +0 -0
@@ -1,284 +0,0 @@
1
- import { describe, expect, it, beforeEach, jest } from '@jest/globals';
2
- import {
3
- reconcileDeviceSources,
4
- getPreferredSource,
5
- filterDevicesBySource,
6
- markDeviceConnected,
7
- shouldHideFromSource,
8
- logReconciliationSummary,
9
- DeviceSourceInfo,
10
- } from '../../src/local/CloudLocalReconciliation';
11
- import TuyaDevice from '../../src/cloud/device/TuyaDevice';
12
- import Logger from '../../src/shared/util/Logger';
13
-
14
- function makeMockLog(): Logger {
15
- return {
16
- debug: jest.fn(),
17
- info: jest.fn(),
18
- warn: jest.fn(),
19
- error: jest.fn(),
20
- log: jest.fn(),
21
- } as unknown as Logger;
22
- }
23
-
24
- function createMockDevice(id: string, uuid: string): TuyaDevice {
25
- return {
26
- id,
27
- uuid,
28
- name: `Device ${id}`,
29
- } as TuyaDevice;
30
- }
31
-
32
- describe('CloudLocalReconciliation - Phase 4', () => {
33
- let log: Logger;
34
-
35
- beforeEach(() => {
36
- log = makeMockLog();
37
- });
38
-
39
- describe('reconcileDeviceSources', () => {
40
- it('reconciles cloud-only devices', () => {
41
- const cloudDevices = [
42
- createMockDevice('cloud_001', 'uuid_001'),
43
- createMockDevice('cloud_002', 'uuid_002'),
44
- ];
45
-
46
- const result = reconcileDeviceSources(cloudDevices, [], log);
47
-
48
- expect(result.size).toBe(2);
49
- expect(result.get('uuid_001')).toEqual({
50
- cloud: true,
51
- local: false,
52
- connectedTo: 'cloud',
53
- });
54
- });
55
-
56
- it('reconciles local-only devices', () => {
57
- const localDevices = [
58
- createMockDevice('local_001', 'uuid_101'),
59
- ];
60
-
61
- const result = reconcileDeviceSources([], localDevices, log);
62
-
63
- expect(result.size).toBe(1);
64
- expect(result.get('uuid_101')).toEqual({
65
- cloud: false,
66
- local: true,
67
- localIP: undefined,
68
- localVersion: undefined,
69
- connectedTo: 'local',
70
- });
71
- });
72
-
73
- it('reconciles hybrid devices (same UUID, both sources)', () => {
74
- const cloudDevices = [createMockDevice('device_a', 'uuid_hybrid')];
75
- const localDevices = [createMockDevice('device_a', 'uuid_hybrid')];
76
-
77
- const result = reconcileDeviceSources(cloudDevices, localDevices, log);
78
-
79
- expect(result.size).toBe(1);
80
- const info = result.get('uuid_hybrid');
81
- expect(info?.cloud).toBe(true);
82
- expect(info?.local).toBe(true);
83
- expect(info?.connectedTo).toBe('both');
84
-
85
- const infoSpy = log.info as jest.MockedFunction<typeof log.info>;
86
- expect(infoSpy).toHaveBeenCalledWith(expect.stringContaining('available via cloud AND local'));
87
- });
88
-
89
- it('handles mixed cloud-only, local-only, and hybrid devices', () => {
90
- const cloudDevices = [
91
- createMockDevice('cloud_only', 'uuid_cloud'),
92
- createMockDevice('hybrid', 'uuid_hybrid'),
93
- ];
94
- const localDevices = [
95
- createMockDevice('local_only', 'uuid_local'),
96
- createMockDevice('hybrid', 'uuid_hybrid'),
97
- ];
98
-
99
- const result = reconcileDeviceSources(cloudDevices, localDevices, log);
100
-
101
- expect(result.size).toBe(3);
102
- expect(result.get('uuid_cloud')?.cloud).toBe(true);
103
- expect(result.get('uuid_cloud')?.local).toBe(false);
104
- expect(result.get('uuid_local')?.cloud).toBe(false);
105
- expect(result.get('uuid_local')?.local).toBe(true);
106
- expect(result.get('uuid_hybrid')?.cloud).toBe(true);
107
- expect(result.get('uuid_hybrid')?.local).toBe(true);
108
- });
109
-
110
- it('logs hybrid device detection', () => {
111
- const cloudDevices = [createMockDevice('device', 'uuid_123')];
112
- const localDevices = [createMockDevice('device', 'uuid_123')];
113
-
114
- reconcileDeviceSources(cloudDevices, localDevices, log);
115
-
116
- const infoSpy = log.info as jest.MockedFunction<typeof log.info>;
117
- expect(infoSpy).toHaveBeenCalledWith(expect.stringContaining('available via cloud AND local'));
118
- });
119
- });
120
-
121
- describe('getPreferredSource', () => {
122
- it('prefers local when available', () => {
123
- const sourceInfo: DeviceSourceInfo = { cloud: true, local: true };
124
- expect(getPreferredSource(sourceInfo)).toBe('local');
125
- });
126
-
127
- it('uses cloud when local unavailable', () => {
128
- const sourceInfo: DeviceSourceInfo = { cloud: true, local: false };
129
- expect(getPreferredSource(sourceInfo)).toBe('cloud');
130
- });
131
-
132
- it('always prefers local when both available (ignores default param)', () => {
133
- const sourceInfo: DeviceSourceInfo = { cloud: true, local: true };
134
- // The defaultSource param is only used when local is unavailable
135
- // When both are available, local is always preferred
136
- expect(getPreferredSource(sourceInfo, 'local')).toBe('local');
137
- expect(getPreferredSource(sourceInfo, 'cloud')).toBe('local');
138
- });
139
- });
140
-
141
- describe('filterDevicesBySource', () => {
142
- let sourceMap: Map<string, DeviceSourceInfo>;
143
-
144
- beforeEach(() => {
145
- sourceMap = new Map([
146
- ['uuid_cloud', { cloud: true, local: false }],
147
- ['uuid_local', { cloud: false, local: true }],
148
- ['uuid_hybrid', { cloud: true, local: true }],
149
- ]);
150
- });
151
-
152
- it('filters to local-only devices', () => {
153
- const devices = [
154
- createMockDevice('cloud', 'uuid_cloud'),
155
- createMockDevice('local', 'uuid_local'),
156
- createMockDevice('hybrid', 'uuid_hybrid'),
157
- ];
158
-
159
- const result = filterDevicesBySource(devices, 'local', sourceMap);
160
-
161
- expect(result.length).toBe(2);
162
- expect(result.map(d => d.uuid)).toContain('uuid_local');
163
- expect(result.map(d => d.uuid)).toContain('uuid_hybrid');
164
- expect(result.map(d => d.uuid)).not.toContain('uuid_cloud');
165
- });
166
-
167
- it('filters to cloud-only devices', () => {
168
- const devices = [
169
- createMockDevice('cloud', 'uuid_cloud'),
170
- createMockDevice('local', 'uuid_local'),
171
- createMockDevice('hybrid', 'uuid_hybrid'),
172
- ];
173
-
174
- const result = filterDevicesBySource(devices, 'cloud', sourceMap);
175
-
176
- expect(result.length).toBe(2);
177
- expect(result.map(d => d.uuid)).toContain('uuid_cloud');
178
- expect(result.map(d => d.uuid)).toContain('uuid_hybrid');
179
- expect(result.map(d => d.uuid)).not.toContain('uuid_local');
180
- });
181
-
182
- it('returns all devices for both source filter', () => {
183
- const devices = [
184
- createMockDevice('cloud', 'uuid_cloud'),
185
- createMockDevice('local', 'uuid_local'),
186
- createMockDevice('hybrid', 'uuid_hybrid'),
187
- ];
188
-
189
- const result = filterDevicesBySource(devices, 'both', sourceMap);
190
-
191
- expect(result.length).toBe(3);
192
- });
193
-
194
- it('excludes unknown devices from filter', () => {
195
- const devices = [
196
- createMockDevice('cloud', 'uuid_cloud'),
197
- createMockDevice('unknown', 'uuid_unknown'),
198
- ];
199
-
200
- const result = filterDevicesBySource(devices, 'cloud', sourceMap);
201
-
202
- expect(result.length).toBe(1);
203
- expect(result[0].uuid).toBe('uuid_cloud');
204
- });
205
- });
206
-
207
- describe('markDeviceConnected', () => {
208
- let sourceMap: Map<string, DeviceSourceInfo>;
209
-
210
- beforeEach(() => {
211
- sourceMap = new Map([
212
- ['uuid_001', { cloud: true, local: true, connectedTo: 'cloud' }],
213
- ]);
214
- });
215
-
216
- it('updates device connection state to local', () => {
217
- markDeviceConnected('uuid_001', 'local', sourceMap, log);
218
-
219
- expect(sourceMap.get('uuid_001')?.connectedTo).toBe('both');
220
- });
221
-
222
- it('warns if marking unknown device as connected', () => {
223
- markDeviceConnected('uuid_unknown', 'local', sourceMap, log);
224
-
225
- const warnSpy = log.warn as jest.MockedFunction<typeof log.warn>;
226
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('unknown device'));
227
- });
228
-
229
- it('warns if marking device connected to unavailable source', () => {
230
- const sourceInfo: DeviceSourceInfo = {
231
- cloud: true,
232
- local: false,
233
- };
234
- sourceMap.set('uuid_002', sourceInfo);
235
-
236
- markDeviceConnected('uuid_002', 'local', sourceMap, log);
237
-
238
- const warnSpy = log.warn as jest.MockedFunction<typeof log.warn>;
239
- expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('not available locally'));
240
- });
241
- });
242
-
243
- describe('shouldHideFromSource', () => {
244
- it('does not hide when source is both', () => {
245
- const device = createMockDevice('test', 'uuid_test');
246
- expect(shouldHideFromSource(device, 'cloud', 'both')).toBe(false);
247
- expect(shouldHideFromSource(device, 'local', 'both')).toBe(false);
248
- });
249
-
250
- it('hides cloud devices when source is local-only', () => {
251
- const device = createMockDevice('test', 'uuid_test');
252
- expect(shouldHideFromSource(device, 'cloud', 'local')).toBe(true);
253
- });
254
-
255
- it('hides local devices when source is cloud-only', () => {
256
- const device = createMockDevice('test', 'uuid_test');
257
- expect(shouldHideFromSource(device, 'local', 'cloud')).toBe(true);
258
- });
259
-
260
- it('defaults to cloud-only when source undefined', () => {
261
- const device = createMockDevice('test', 'uuid_test');
262
- expect(shouldHideFromSource(device, 'local', undefined)).toBe(true);
263
- expect(shouldHideFromSource(device, 'cloud', undefined)).toBe(false);
264
- });
265
- });
266
-
267
- describe('logReconciliationSummary', () => {
268
- it('logs reconciliation counts', () => {
269
- const sourceMap = new Map<string, DeviceSourceInfo>([
270
- ['uuid_1', { cloud: true, local: true }],
271
- ['uuid_2', { cloud: true, local: false }],
272
- ['uuid_3', { cloud: false, local: true }],
273
- ]);
274
-
275
- logReconciliationSummary(sourceMap, log);
276
-
277
- const infoSpy = log.info as jest.MockedFunction<typeof log.info>;
278
- const call = String(infoSpy.mock.calls[0][0]);
279
- expect(call).toContain('1 hybrid');
280
- expect(call).toContain('1 cloud-only');
281
- expect(call).toContain('1 local-only');
282
- });
283
- });
284
- });
@@ -1 +0,0 @@
1
- 85778e1add80c517
@@ -1 +0,0 @@
1
- 35d2f400f4ef8c0f
@@ -1,85 +0,0 @@
1
- # Get Local Keys for Your Devices
2
-
3
- To get the local keys for your devices, you'll need an account on Tuya's IoT site. Don't be overwhelmed, there's a lot on that site but it's pretty easy to get what you need out of it. The free trial will give you enough access to the Tuya API to get the information you need, on up to 50 devices.
4
-
5
- ## 1 - Tuya Smart App
6
-
7
- As a prerequisite, add all of your devices to the Tuya Smart app ([iOS](https://apps.apple.com/au/app/tuya-smart/id1034649547) / [Android](https://play.google.com/store/apps/details?id=com.tuya.smart&hl=en_AU&gl=US&pli=1))
8
-
9
- ## 2 - Sign up for an IoT account
10
-
11
- Go to https://iot.tuya.com and click Sign Up
12
-
13
- ![signup](https://user-images.githubusercontent.com/82495132/120384295-d2c95100-c2da-11eb-930d-75eaad628f4f.png)
14
-
15
- * Fill in your information
16
- * Make up a company name if you need to
17
-
18
- ![signup-info](https://user-images.githubusercontent.com/82495132/120384453-099f6700-c2db-11eb-8cbc-20f3bc5bb17f.png)
19
-
20
- * Check Agree to Terms
21
- * Click Agree
22
- * You'll be emailed a code, enter it
23
-
24
- ## 3 - Sign in at iot.tuya.com
25
-
26
- ## 4 - Create a cloud project
27
-
28
- * Click through the intro
29
- * On the sidebar click cloud, then projects
30
- * Click Free Trial under TRIAL EDITION
31
-
32
- ![freetrial](https://user-images.githubusercontent.com/82495132/120384723-60a53c00-c2db-11eb-8f79-f2a2f38dbc8a.png)
33
-
34
- * Click Buy now in the new tab
35
-
36
- ![buynow](https://user-images.githubusercontent.com/82495132/120384754-69960d80-c2db-11eb-802c-7067dff3274a.png)
37
-
38
- * Close the Tuya Value Added Service tab/popup
39
- * In the Tuya IoT Platform tab, click Subscribed to be taken back to Cloud -> Projects
40
- * Click create
41
-
42
- ![create](https://user-images.githubusercontent.com/82495132/120384789-7a468380-c2db-11eb-9770-8bdd41d65a3a.png)
43
-
44
- * Make sure you pick smart home PAAS and the correct region, this affects whether you will be able to access your devices in the following steps. Click create
45
-
46
- ![createproject](https://user-images.githubusercontent.com/82495132/120386067-04431c00-c2dd-11eb-93ff-27371397e1e2.png)
47
-
48
- * Click Authorize for the recommended APIs
49
-
50
- ![authorize](https://user-images.githubusercontent.com/82495132/120384846-87637280-c2db-11eb-8a3c-b2fd256f68d5.png)
51
-
52
- ## 5 - Link devices registered in Tuya app to the IoT site
53
-
54
- * From your project, click the link devices tab, then Link devices by App Account, then Add App Account
55
-
56
- ![addappaccount](https://user-images.githubusercontent.com/82495132/120385095-d7dad000-c2db-11eb-9e4c-595af4502154.png)
57
-
58
- * In the Tuya Smart app, click me at the bottom, then the scan button, then scan your QR code
59
-
60
- ![scan2](https://user-images.githubusercontent.com/82495132/120385375-2f793b80-c2dc-11eb-9343-c579fc288962.png)
61
-
62
- * Confirm the sign in
63
-
64
- ## 6 - Get the keys for your devices
65
-
66
- * Go to the device list tab
67
- * Copy the device ID for your device
68
-
69
- ![devices](https://user-images.githubusercontent.com/484912/204113199-a7ffd1c6-7f22-4295-a3a1-948ba15643b2.png)
70
-
71
- * In the sidebar, hover over "Cloud" and click on "API Explorer"
72
-
73
- ![apiexplorer](https://user-images.githubusercontent.com/484912/204113419-3d106164-eff8-4ff3-a4f5-c7f2a025de96.png)
74
-
75
- * In the sidebar, search for "get device information" endpoint and click on the highlighted option. (It should be under "General Devices management" section. Note: there is also another endpoint called "Get _the_ device information" which will not work.)
76
-
77
- * In the "device_id" text field, paste in the device ID you copied and click "Submit Request"
78
-
79
- * In the "Response" section, there should be a property called `local_key` which is your local key.
80
-
81
- ![localkey](https://user-images.githubusercontent.com/484912/204113337-81ebe3c3-5f3a-4854-a069-aa929bfb145d.png)
82
-
83
- ## 7 - Video Tutorial
84
-
85
- * [YouTube](https://youtu.be/FpY-xsY-pZ8)