@rentlydev/rently-tuya 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +281 -0
  3. package/android/build.gradle +182 -0
  4. package/android/gradle.properties +7 -0
  5. package/android/libs/airbrake-android-1.4.0.jar +0 -0
  6. package/android/src/main/AndroidManifest.xml +1 -0
  7. package/android/src/main/AndroidManifestNew.xml +25 -0
  8. package/android/src/main/java/com/rentlytuya/RentlyTuyaModule.kt +503 -0
  9. package/android/src/main/java/com/rentlytuya/RentlyTuyaPackage.kt +18 -0
  10. package/android/src/main/java/com/rentlytuya/TuyaActivity.kt +45 -0
  11. package/android/src/main/java/com/rentlytuya/alerts/FormatSDCardAlert.kt +83 -0
  12. package/android/src/main/java/com/rentlytuya/alerts/PermissionAlert.kt +91 -0
  13. package/android/src/main/java/com/rentlytuya/alerts/RemoveDoorbellAlert.kt +83 -0
  14. package/android/src/main/java/com/rentlytuya/alerts/RemoveDoorbellFailureAlert.kt +71 -0
  15. package/android/src/main/java/com/rentlytuya/alerts/ResetWifiAlert.kt +83 -0
  16. package/android/src/main/java/com/rentlytuya/alerts/SuccessAlert.kt +74 -0
  17. package/android/src/main/java/com/rentlytuya/components/Alert.kt +47 -0
  18. package/android/src/main/java/com/rentlytuya/components/AnchorButton.kt +125 -0
  19. package/android/src/main/java/com/rentlytuya/components/Button.kt +147 -0
  20. package/android/src/main/java/com/rentlytuya/components/CustomDatePicker.kt +275 -0
  21. package/android/src/main/java/com/rentlytuya/components/Divider.kt +53 -0
  22. package/android/src/main/java/com/rentlytuya/components/EncryptedImageView.kt +59 -0
  23. package/android/src/main/java/com/rentlytuya/components/Label.kt +155 -0
  24. package/android/src/main/java/com/rentlytuya/components/LoadingIndicator.kt +75 -0
  25. package/android/src/main/java/com/rentlytuya/components/Slider.kt +66 -0
  26. package/android/src/main/java/com/rentlytuya/components/Switch.kt +51 -0
  27. package/android/src/main/java/com/rentlytuya/components/VideoView.kt +45 -0
  28. package/android/src/main/java/com/rentlytuya/dashboard/AdvancedSettings.kt +259 -0
  29. package/android/src/main/java/com/rentlytuya/dashboard/Dashboard.kt +551 -0
  30. package/android/src/main/java/com/rentlytuya/dashboard/DoorbellSettings.kt +874 -0
  31. package/android/src/main/java/com/rentlytuya/dashboard/Messages.kt +463 -0
  32. package/android/src/main/java/com/rentlytuya/dashboard/NavController.kt +358 -0
  33. package/android/src/main/java/com/rentlytuya/dashboard/OfflineScreen.kt +160 -0
  34. package/android/src/main/java/com/rentlytuya/dashboard/Playback.kt +685 -0
  35. package/android/src/main/java/com/rentlytuya/tuya/Messages.kt +234 -0
  36. package/android/src/main/java/com/rentlytuya/tuya/Playback.kt +385 -0
  37. package/android/src/main/java/com/rentlytuya/tuya/ScreenCapture.kt +244 -0
  38. package/android/src/main/java/com/rentlytuya/tuya/Settings.kt +809 -0
  39. package/android/src/main/java/com/rentlytuya/tuya/Tuya.kt +497 -0
  40. package/android/src/main/java/com/rentlytuya/ui/theme/LocalColor.kt +80 -0
  41. package/android/src/main/java/com/rentlytuya/ui/theme/LocalFont.kt +35 -0
  42. package/android/src/main/java/com/rentlytuya/ui/theme/Theme.kt +34 -0
  43. package/android/src/main/java/com/rentlytuya/ui/theme/Type.kt +34 -0
  44. package/android/src/main/java/com/rentlytuya/util/Airbrake.kt +40 -0
  45. package/android/src/main/java/com/rentlytuya/util/DpConstants.kt +53 -0
  46. package/android/src/main/java/com/rentlytuya/util/FrescoManager.kt +86 -0
  47. package/android/src/main/java/com/rentlytuya/util/HeapAnalytics.kt +16 -0
  48. package/android/src/main/java/com/rentlytuya/util/KeylessModule.kt +81 -0
  49. package/android/src/main/java/com/rentlytuya/util/PermissionHandler.kt +75 -0
  50. package/android/src/main/java/com/rentlytuya/util/ReactParamsCheck.kt +152 -0
  51. package/android/src/main/java/com/rentlytuya/util/Util.kt +128 -0
  52. package/android/src/main/res/drawable/ic_close.xml +12 -0
  53. package/android/src/main/res/drawable/ic_launcher_background.xml +170 -0
  54. package/android/src/main/res/drawable/ic_launcher_foreground.xml +30 -0
  55. package/android/src/main/res/drawable/img_place_holder.png +0 -0
  56. package/android/src/main/res/drawable-hdpi/ic_action_arrow_backward.png +0 -0
  57. package/android/src/main/res/drawable-hdpi/ic_arrow_backward_white.png +0 -0
  58. package/android/src/main/res/drawable-hdpi/ic_arrow_blue_right.png +0 -0
  59. package/android/src/main/res/drawable-hdpi/ic_calendar.png +0 -0
  60. package/android/src/main/res/drawable-hdpi/ic_camera.png +0 -0
  61. package/android/src/main/res/drawable-hdpi/ic_message.png +0 -0
  62. package/android/src/main/res/drawable-hdpi/ic_pause.png +0 -0
  63. package/android/src/main/res/drawable-hdpi/ic_play.png +0 -0
  64. package/android/src/main/res/drawable-hdpi/ic_play_back.png +0 -0
  65. package/android/src/main/res/drawable-hdpi/ic_record.png +0 -0
  66. package/android/src/main/res/drawable-hdpi/ic_retry.png +0 -0
  67. package/android/src/main/res/drawable-hdpi/ic_setting.png +0 -0
  68. package/android/src/main/res/drawable-hdpi/ic_sound_off.png +0 -0
  69. package/android/src/main/res/drawable-hdpi/ic_sound_on.png +0 -0
  70. package/android/src/main/res/drawable-mdpi/ic_action_arrow_backward.png +0 -0
  71. package/android/src/main/res/drawable-mdpi/ic_arrow_backward_white.png +0 -0
  72. package/android/src/main/res/drawable-mdpi/ic_arrow_blue_right.png +0 -0
  73. package/android/src/main/res/drawable-mdpi/ic_battery_average.png +0 -0
  74. package/android/src/main/res/drawable-mdpi/ic_battery_charging.png +0 -0
  75. package/android/src/main/res/drawable-mdpi/ic_battery_full.png +0 -0
  76. package/android/src/main/res/drawable-mdpi/ic_battery_good.png +0 -0
  77. package/android/src/main/res/drawable-mdpi/ic_battery_low.png +0 -0
  78. package/android/src/main/res/drawable-mdpi/ic_calendar.png +0 -0
  79. package/android/src/main/res/drawable-mdpi/ic_camera.png +0 -0
  80. package/android/src/main/res/drawable-mdpi/ic_message.png +0 -0
  81. package/android/src/main/res/drawable-mdpi/ic_pause.png +0 -0
  82. package/android/src/main/res/drawable-mdpi/ic_play.png +0 -0
  83. package/android/src/main/res/drawable-mdpi/ic_play_back.png +0 -0
  84. package/android/src/main/res/drawable-mdpi/ic_record.png +0 -0
  85. package/android/src/main/res/drawable-mdpi/ic_retry.png +0 -0
  86. package/android/src/main/res/drawable-mdpi/ic_setting.png +0 -0
  87. package/android/src/main/res/drawable-mdpi/ic_sound_off.png +0 -0
  88. package/android/src/main/res/drawable-mdpi/ic_sound_on.png +0 -0
  89. package/android/src/main/res/drawable-xhdpi/ic_action_arrow_backward.png +0 -0
  90. package/android/src/main/res/drawable-xhdpi/ic_arrow_backward_white.png +0 -0
  91. package/android/src/main/res/drawable-xhdpi/ic_arrow_blue_right.png +0 -0
  92. package/android/src/main/res/drawable-xhdpi/ic_battery_average.png +0 -0
  93. package/android/src/main/res/drawable-xhdpi/ic_battery_charging.png +0 -0
  94. package/android/src/main/res/drawable-xhdpi/ic_battery_full.png +0 -0
  95. package/android/src/main/res/drawable-xhdpi/ic_battery_good.png +0 -0
  96. package/android/src/main/res/drawable-xhdpi/ic_battery_low.png +0 -0
  97. package/android/src/main/res/drawable-xhdpi/ic_calendar.png +0 -0
  98. package/android/src/main/res/drawable-xhdpi/ic_camera.png +0 -0
  99. package/android/src/main/res/drawable-xhdpi/ic_message.png +0 -0
  100. package/android/src/main/res/drawable-xhdpi/ic_pause.png +0 -0
  101. package/android/src/main/res/drawable-xhdpi/ic_play.png +0 -0
  102. package/android/src/main/res/drawable-xhdpi/ic_play_back.png +0 -0
  103. package/android/src/main/res/drawable-xhdpi/ic_record.png +0 -0
  104. package/android/src/main/res/drawable-xhdpi/ic_retry.png +0 -0
  105. package/android/src/main/res/drawable-xhdpi/ic_setting.png +0 -0
  106. package/android/src/main/res/drawable-xhdpi/ic_sound_off.png +0 -0
  107. package/android/src/main/res/drawable-xhdpi/ic_sound_on.png +0 -0
  108. package/android/src/main/res/drawable-xxhdpi/ic_action_arrow_backward.png +0 -0
  109. package/android/src/main/res/drawable-xxhdpi/ic_arrow_backward_white.png +0 -0
  110. package/android/src/main/res/drawable-xxhdpi/ic_arrow_blue_right.png +0 -0
  111. package/android/src/main/res/drawable-xxhdpi/ic_battery_average.png +0 -0
  112. package/android/src/main/res/drawable-xxhdpi/ic_battery_charging.png +0 -0
  113. package/android/src/main/res/drawable-xxhdpi/ic_battery_full.png +0 -0
  114. package/android/src/main/res/drawable-xxhdpi/ic_battery_good.png +0 -0
  115. package/android/src/main/res/drawable-xxhdpi/ic_battery_low.png +0 -0
  116. package/android/src/main/res/drawable-xxhdpi/ic_calendar.png +0 -0
  117. package/android/src/main/res/drawable-xxhdpi/ic_camera.png +0 -0
  118. package/android/src/main/res/drawable-xxhdpi/ic_message.png +0 -0
  119. package/android/src/main/res/drawable-xxhdpi/ic_pause.png +0 -0
  120. package/android/src/main/res/drawable-xxhdpi/ic_play.png +0 -0
  121. package/android/src/main/res/drawable-xxhdpi/ic_play_back.png +0 -0
  122. package/android/src/main/res/drawable-xxhdpi/ic_record.png +0 -0
  123. package/android/src/main/res/drawable-xxhdpi/ic_retry.png +0 -0
  124. package/android/src/main/res/drawable-xxhdpi/ic_setting.png +0 -0
  125. package/android/src/main/res/drawable-xxhdpi/ic_sound_off.png +0 -0
  126. package/android/src/main/res/drawable-xxhdpi/ic_sound_on.png +0 -0
  127. package/android/src/main/res/drawable-xxxhdpi/ic_action_arrow_backward.png +0 -0
  128. package/android/src/main/res/drawable-xxxhdpi/ic_arrow_backward_white.png +0 -0
  129. package/android/src/main/res/drawable-xxxhdpi/ic_arrow_blue_right.png +0 -0
  130. package/android/src/main/res/drawable-xxxhdpi/ic_calendar.png +0 -0
  131. package/android/src/main/res/drawable-xxxhdpi/ic_camera.png +0 -0
  132. package/android/src/main/res/drawable-xxxhdpi/ic_message.png +0 -0
  133. package/android/src/main/res/drawable-xxxhdpi/ic_pause.png +0 -0
  134. package/android/src/main/res/drawable-xxxhdpi/ic_play.png +0 -0
  135. package/android/src/main/res/drawable-xxxhdpi/ic_play_back.png +0 -0
  136. package/android/src/main/res/drawable-xxxhdpi/ic_record.png +0 -0
  137. package/android/src/main/res/drawable-xxxhdpi/ic_retry.png +0 -0
  138. package/android/src/main/res/drawable-xxxhdpi/ic_setting.png +0 -0
  139. package/android/src/main/res/drawable-xxxhdpi/ic_sound_off.png +0 -0
  140. package/android/src/main/res/drawable-xxxhdpi/ic_sound_on.png +0 -0
  141. package/android/src/main/res/font/quicksand_bold.ttf +0 -0
  142. package/android/src/main/res/font/quicksand_light.ttf +0 -0
  143. package/android/src/main/res/font/quicksand_medium.ttf +0 -0
  144. package/android/src/main/res/font/quicksand_regular.ttf +0 -0
  145. package/android/src/main/res/font/quicksand_semi_bold.ttf +0 -0
  146. package/android/src/main/res/values/strings.xml +121 -0
  147. package/android/thingMapping.gradle +200 -0
  148. package/android/thingMapping.json +2014 -0
  149. package/ios/components/Alert.swift +54 -0
  150. package/ios/components/AnchorButton.swift +100 -0
  151. package/ios/components/Button.swift +118 -0
  152. package/ios/components/CustomDatePicker.swift +275 -0
  153. package/ios/components/Divider.swift +28 -0
  154. package/ios/components/Image.swift +72 -0
  155. package/ios/components/Label.swift +105 -0
  156. package/ios/components/Switch.swift +61 -0
  157. package/ios/dashboard/AdvanceSettings.swift +127 -0
  158. package/ios/dashboard/Dashboard.swift +354 -0
  159. package/ios/dashboard/Messages.swift +361 -0
  160. package/ios/dashboard/NavigationController.swift +173 -0
  161. package/ios/dashboard/OfflineScreen.swift +109 -0
  162. package/ios/dashboard/Playback.swift +543 -0
  163. package/ios/dashboard/PreviewManager.swift +117 -0
  164. package/ios/dashboard/Settings.swift +672 -0
  165. package/ios/icons/Charging.png +0 -0
  166. package/ios/icons/Charging@2x.png +0 -0
  167. package/ios/icons/Charging@3x.png +0 -0
  168. package/ios/icons/back_arraow.png +0 -0
  169. package/ios/icons/back_arraow@2x.png +0 -0
  170. package/ios/icons/back_arraow@3x.png +0 -0
  171. package/ios/icons/battery_average.png +0 -0
  172. package/ios/icons/battery_average@2x.png +0 -0
  173. package/ios/icons/battery_average@3x.png +0 -0
  174. package/ios/icons/battery_full.png +0 -0
  175. package/ios/icons/battery_full@2x.png +0 -0
  176. package/ios/icons/battery_full@3x.png +0 -0
  177. package/ios/icons/battery_good.png +0 -0
  178. package/ios/icons/battery_good@2x.png +0 -0
  179. package/ios/icons/battery_good@3x.png +0 -0
  180. package/ios/icons/battery_low.png +0 -0
  181. package/ios/icons/battery_low@2x.png +0 -0
  182. package/ios/icons/battery_low@3x.png +0 -0
  183. package/ios/icons/calendar.png +0 -0
  184. package/ios/icons/calendar@2x.png +0 -0
  185. package/ios/icons/calendar@3x.png +0 -0
  186. package/ios/icons/cloud.png +0 -0
  187. package/ios/icons/cloud@2x.png +0 -0
  188. package/ios/icons/cloud@3x.png +0 -0
  189. package/ios/icons/down_update.png +0 -0
  190. package/ios/icons/down_update@2x.png +0 -0
  191. package/ios/icons/down_update@3x.png +0 -0
  192. package/ios/icons/exit_fullscreen.png +0 -0
  193. package/ios/icons/exit_fullscreen@2x.png +0 -0
  194. package/ios/icons/exit_fullscreen@3x.png +0 -0
  195. package/ios/icons/expand.png +0 -0
  196. package/ios/icons/fullscreen.png +0 -0
  197. package/ios/icons/fullscreen@2x.png +0 -0
  198. package/ios/icons/fullscreen@3x.png +0 -0
  199. package/ios/icons/image_placeholder.png +0 -0
  200. package/ios/icons/information.png +0 -0
  201. package/ios/icons/information@2x.png +0 -0
  202. package/ios/icons/information@3x.png +0 -0
  203. package/ios/icons/keyless_Setting.png +0 -0
  204. package/ios/icons/keyless_Setting@2x.png +0 -0
  205. package/ios/icons/keyless_Setting@3x.png +0 -0
  206. package/ios/icons/keyless_back@1x.png +0 -0
  207. package/ios/icons/keyless_back@2x.png +0 -0
  208. package/ios/icons/keyless_back@3x.png +0 -0
  209. package/ios/icons/keyless_filter.png +0 -0
  210. package/ios/icons/keyless_filter@2x.png +0 -0
  211. package/ios/icons/keyless_filter@3x.png +0 -0
  212. package/ios/icons/keyless_message.png +0 -0
  213. package/ios/icons/keyless_message@2x.png +0 -0
  214. package/ios/icons/keyless_message@3x.png +0 -0
  215. package/ios/icons/keyless_pause.png +0 -0
  216. package/ios/icons/keyless_pause@2x.png +0 -0
  217. package/ios/icons/keyless_pause@3x.png +0 -0
  218. package/ios/icons/keyless_photo.png +0 -0
  219. package/ios/icons/keyless_photo@2x.png +0 -0
  220. package/ios/icons/keyless_photo@3x.png +0 -0
  221. package/ios/icons/keyless_play.png +0 -0
  222. package/ios/icons/keyless_play@2x.png +0 -0
  223. package/ios/icons/keyless_play@3x.png +0 -0
  224. package/ios/icons/keyless_play_list.png +0 -0
  225. package/ios/icons/keyless_play_list@2x.png +0 -0
  226. package/ios/icons/keyless_play_list@3x.png +0 -0
  227. package/ios/icons/keyless_play_playback.png +0 -0
  228. package/ios/icons/keyless_play_playback@2x.png +0 -0
  229. package/ios/icons/keyless_play_playback@3x.png +0 -0
  230. package/ios/icons/keyless_record.png +0 -0
  231. package/ios/icons/keyless_record@2x.png +0 -0
  232. package/ios/icons/keyless_record@3x.png +0 -0
  233. package/ios/icons/keyless_record_on.png +0 -0
  234. package/ios/icons/keyless_record_on@2x.png +0 -0
  235. package/ios/icons/keyless_record_on@3x.png +0 -0
  236. package/ios/icons/keyless_sound_off.png +0 -0
  237. package/ios/icons/keyless_sound_off@2x.png +0 -0
  238. package/ios/icons/keyless_sound_off@3x.png +0 -0
  239. package/ios/icons/keyless_sound_on.png +0 -0
  240. package/ios/icons/keyless_sound_on@2x.png +0 -0
  241. package/ios/icons/keyless_sound_on@3x.png +0 -0
  242. package/ios/icons/keyless_speak_off.png +0 -0
  243. package/ios/icons/keyless_speak_off@2x.png +0 -0
  244. package/ios/icons/keyless_speak_on.png +0 -0
  245. package/ios/icons/keyless_speak_on@2x.png +0 -0
  246. package/ios/icons/keyless_speak_on@3x.png +0 -0
  247. package/ios/icons/refresh.png +0 -0
  248. package/ios/icons/refresh@2x.png +0 -0
  249. package/ios/icons/refresh@3x.png +0 -0
  250. package/ios/icons/ty_camera_control_hd_normal@2x.png +0 -0
  251. package/ios/icons/ty_camera_control_hd_normal@3x.png +0 -0
  252. package/ios/icons/ty_camera_control_sd_normal@2x.png +0 -0
  253. package/ios/icons/ty_camera_control_sd_normal@3x.png +0 -0
  254. package/ios/icons/upgrade_success.png +0 -0
  255. package/ios/icons/upgrade_success@2x.png +0 -0
  256. package/ios/icons/upgrade_success@3x.png +0 -0
  257. package/ios/listener/KeylessListener.m +8 -0
  258. package/ios/listener/KeylessListener.swift +56 -0
  259. package/ios/listener/RentlyTuya-Bridging-Header.h +5 -0
  260. package/ios/listener/RentlyTuya.mm +56 -0
  261. package/ios/listener/RentlyTuya.swift +544 -0
  262. package/ios/theme/LocalColor.swift +33 -0
  263. package/ios/theme/LocalFont.swift +32 -0
  264. package/ios/theme/Theme.swift +71 -0
  265. package/ios/tuya/CameraManager.swift +296 -0
  266. package/ios/tuya/SettingsManager.swift +475 -0
  267. package/ios/tuya/Tuya.swift +570 -0
  268. package/ios/tuya/TuyaMessages.swift +98 -0
  269. package/ios/utils/Airbrake.swift +31 -0
  270. package/ios/utils/AppUtility.swift +76 -0
  271. package/ios/utils/HeapAnalytics.swift +8 -0
  272. package/ios/utils/OrientationManager.swift +60 -0
  273. package/ios/utils/PromiseHandler.swift +36 -0
  274. package/lib/commonjs/index.js +90 -0
  275. package/lib/commonjs/index.js.map +1 -0
  276. package/lib/commonjs/package.json +1 -0
  277. package/lib/module/index.js +83 -0
  278. package/lib/module/index.js.map +1 -0
  279. package/lib/module/package.json +1 -0
  280. package/lib/typescript/commonjs/package.json +1 -0
  281. package/lib/typescript/commonjs/src/index.d.ts +75 -0
  282. package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
  283. package/lib/typescript/module/package.json +1 -0
  284. package/lib/typescript/module/src/index.d.ts +75 -0
  285. package/lib/typescript/module/src/index.d.ts.map +1 -0
  286. package/package.json +188 -0
  287. package/rently-tuya.podspec +52 -0
  288. package/src/index.tsx +158 -0
@@ -0,0 +1,809 @@
1
+ package com.rentlytuya.tuya
2
+
3
+ import android.util.Log
4
+ import androidx.compose.runtime.MutableState
5
+ import com.facebook.react.bridge.ReactContext
6
+ import com.rentlytuya.tuya.Tuya.TAG
7
+ import com.rentlytuya.tuya.Tuya.deviceId
8
+ import com.rentlytuya.tuya.Tuya.iTuyaDevice
9
+ import com.rentlytuya.util.Airbrake
10
+ import com.rentlytuya.util.DPConstants
11
+ import com.rentlytuya.util.DateUtil.isNotNull
12
+ import com.rentlytuya.util.KeylessModule
13
+ import com.thingclips.smart.android.device.bean.UpgradeInfoBean
14
+ import com.thingclips.smart.home.sdk.ThingHomeSdk
15
+ import com.thingclips.smart.sdk.api.IDevListener
16
+ import com.thingclips.smart.sdk.api.IGetOtaInfoCallback
17
+ import com.thingclips.smart.sdk.api.IResultCallback
18
+ import kotlinx.coroutines.Dispatchers
19
+ import kotlinx.coroutines.withContext
20
+ import org.json.JSONException
21
+ import org.json.JSONObject
22
+ import java.util.Locale
23
+ import kotlin.coroutines.resume
24
+ import kotlin.coroutines.suspendCoroutine
25
+
26
+ object Settings {
27
+
28
+ fun is8s(): Boolean {
29
+ return !(isDPSupported(dpId = DPConstants.WIRELESS_ELECTRICITY) || isDPSupported(
30
+ dpId = DPConstants.WIRELESS_POWER_MODE
31
+ ))
32
+ }
33
+
34
+ fun isAOSU(): Boolean {
35
+ return (isDPSupported(dpId = DPConstants.ANTI_DISMANTLING_ALARM))
36
+ }
37
+
38
+ fun publishDps(
39
+ dpKey: String,
40
+ value: Any,
41
+ onSuccess: () -> Unit,
42
+ onError: (code: String?, error: String?) -> Unit
43
+ ) {
44
+ if (iTuyaDevice.isNotNull()) {
45
+ iTuyaDevice?.publishDps(createJsonPayload(dpKey, value), object : IResultCallback {
46
+ override fun onError(code: String, error: String) {
47
+ Airbrake.logMessage(
48
+ title = "Publish DP's Failed",
49
+ message = "Error Code: $code",
50
+ additionalInfo = mapOf(
51
+ "Error" to error,
52
+ "DP-Key" to dpKey,
53
+ "Value" to value.toString()
54
+ )
55
+ )
56
+ onError(code, error)
57
+ }
58
+
59
+ override fun onSuccess() {
60
+ Log.i(TAG, "$dpKey set to $value successfully")
61
+ onSuccess()
62
+ }
63
+ })
64
+ } else {
65
+ Log.i(TAG, "Device is null, cannot publishDps")
66
+ onError(null, null)
67
+ }
68
+ }
69
+
70
+ fun createJsonPayload(dpKey: String, value: Any): String {
71
+ val jsonObject = JSONObject()
72
+ try {
73
+ jsonObject.put(dpKey, value)
74
+ } catch (e: JSONException) {
75
+ Airbrake.logMessage(
76
+ title = "Creating JSON Payload for Publish DP's Failed",
77
+ message = "Error: ${e.message}"
78
+ )
79
+ }
80
+ return jsonObject.toString()
81
+ }
82
+
83
+ fun initializeSettings(
84
+ isWaterMarkEnabled: MutableState<Boolean>,
85
+ isFlipEnabled: MutableState<Boolean>,
86
+ isAntiDismantlingAlarmEnabled: MutableState<Boolean>,
87
+ nightVisionLevel: MutableState<String>,
88
+ isMotionDetectionEnabled: MutableState<Boolean>,
89
+ motionSensitivityLevel: MutableState<String>,
90
+ aosuMotionSensitivityLevel: MutableState<String>,
91
+ isPIRDetectionEnabled: MutableState<Boolean>,
92
+ pirSensitivityLevel: MutableState<Int>,
93
+ storageFunctionType: MutableState<Int>,
94
+ isSDCardRecordingEnabled: MutableState<Boolean>,
95
+ sdCardRecordingType: MutableState<String>,
96
+ chimeType: MutableState<String>,
97
+ powerSource: MutableState<String>,
98
+ batteryPercentage: MutableState<Int>,
99
+ totalStorageCapacity: MutableState<String>,
100
+ usedStorage: MutableState<String>,
101
+ remainingStorageCapacity: MutableState<String>
102
+ ) {
103
+ val deviceBean = ThingHomeSdk.getDataInstance().getDeviceBean(deviceId)
104
+ if (deviceBean.isNotNull()) {
105
+ for ((key, value) in deviceBean.getDps()) {
106
+ if (key.isNotNull() && value.isNotNull()) {
107
+ when (key) {
108
+ DPConstants.WATERMARK -> {
109
+ Log.i(TAG, "Watermark: $value ${value::class}")
110
+ isWaterMarkEnabled.value = value as Boolean
111
+ }
112
+
113
+ DPConstants.BASIC_FLIP -> {
114
+ Log.i(TAG, "Flip: $value ${value::class}")
115
+ isFlipEnabled.value = value as Boolean
116
+ }
117
+
118
+ DPConstants.ANTI_DISMANTLING_ALARM -> {
119
+ Log.i(TAG, "AntiDismantlingAlarm: $value ${value::class}")
120
+ isAntiDismantlingAlarmEnabled.value = value as Boolean
121
+ }
122
+
123
+ DPConstants.BASIC_NIGHT_VISION -> {
124
+ Log.i(TAG, "Night Vision Mode: $value ${value::class}")
125
+ nightVisionLevel.value = value as String
126
+ }
127
+
128
+ DPConstants.MOTION_SWITCH -> {
129
+ Log.i(TAG, "Motion Detection: $value ${value::class}")
130
+ isMotionDetectionEnabled.value = value as Boolean
131
+ }
132
+
133
+ DPConstants.MOTION_SENSITIVITY -> {
134
+ Log.i(TAG, "Motion Sensitivity: $value ${value::class}")
135
+ motionSensitivityLevel.value = value as String
136
+ }
137
+
138
+ DPConstants.MOTION_SENSITIVITY_AOSU -> {
139
+ Log.i(TAG, "AOSU Motion Sensitivity: $value ${value::class}")
140
+ aosuMotionSensitivityLevel.value = value as String
141
+ }
142
+
143
+ DPConstants.PIR_SWITCH -> {
144
+ Log.i(TAG, "PIR Detection: $value ${value::class}")
145
+ isPIRDetectionEnabled.value = value as Boolean
146
+ }
147
+
148
+ DPConstants.PIR_SENSITIVITY -> {
149
+ Log.i(TAG, "PIR Sensitivity: $value ${value::class}")
150
+ pirSensitivityLevel.value = value as Int
151
+ }
152
+
153
+ DPConstants.SD_STATUS -> {
154
+ Log.i(TAG, "SD Card Status: $value ${value::class}")
155
+ storageFunctionType.value = value as Int
156
+ }
157
+
158
+ DPConstants.SD_RECORD_SWITCH -> {
159
+ Log.i(TAG, "SD Card Recording: $value ${value::class}")
160
+ isSDCardRecordingEnabled.value = value as Boolean
161
+ }
162
+
163
+ DPConstants.SD_RECORD_MODE -> {
164
+ Log.i(TAG, "SD Card Record Mode: $value ${value::class}")
165
+ sdCardRecordingType.value = value as String
166
+ }
167
+
168
+ DPConstants.CHIME_TYPE -> {
169
+ Log.i(TAG, "Chime Type: $value ${value::class}")
170
+ chimeType.value = value as String
171
+ }
172
+
173
+ DPConstants.WIRELESS_POWER_MODE -> {
174
+ Log.i(TAG, "Power Mode: $value ${value::class}")
175
+ powerSource.value = value as String
176
+ }
177
+
178
+ DPConstants.WIRELESS_ELECTRICITY -> {
179
+ Log.i(TAG, "Wireless Electricity: $value ${value::class}")
180
+ batteryPercentage.value = value as Int
181
+ }
182
+
183
+ DPConstants.SD_STORAGE -> {
184
+ Log.i(TAG, "SD Card Capacity Value: $value ${value::class}")
185
+ parseStorageValue(
186
+ value = value,
187
+ totalStorageCapacity = totalStorageCapacity,
188
+ usedStorage = usedStorage,
189
+ remainingStorageCapacity = remainingStorageCapacity
190
+ )
191
+ }
192
+ }
193
+ }
194
+ }
195
+ }
196
+
197
+ listenDPUpdate(
198
+ isWaterMarkEnabled = isWaterMarkEnabled,
199
+ isFlipEnabled = isFlipEnabled,
200
+ isAntiDismantlingAlarmEnabled = isAntiDismantlingAlarmEnabled,
201
+ nightVisionLevel = nightVisionLevel,
202
+ isMotionDetectionEnabled = isMotionDetectionEnabled,
203
+ motionSensitivityLevel = motionSensitivityLevel,
204
+ aosuMotionSensitivityLevel = aosuMotionSensitivityLevel,
205
+ isPIRDetectionEnabled = isPIRDetectionEnabled,
206
+ pirSensitivityLevel = pirSensitivityLevel,
207
+ storageFunctionType = storageFunctionType,
208
+ isSDCardRecordingEnabled = isSDCardRecordingEnabled,
209
+ sdCardRecordingType = sdCardRecordingType,
210
+ chimeType = chimeType,
211
+ powerSource = powerSource,
212
+ batteryPercentage = batteryPercentage,
213
+ totalStorageCapacity = totalStorageCapacity,
214
+ usedStorage = usedStorage,
215
+ remainingStorageCapacity = remainingStorageCapacity
216
+ )
217
+ }
218
+
219
+ private fun parseStorageValue(
220
+ value: Any,
221
+ totalStorageCapacity: MutableState<String>,
222
+ usedStorage: MutableState<String>,
223
+ remainingStorageCapacity: MutableState<String>
224
+ ) {
225
+ val storageValue = value.toString()
226
+ if (storageValue.contains("|")) {
227
+ val storageParts: Array<String> = storageValue.split("\\|".toRegex())
228
+ .dropLastWhile { it.isEmpty() }
229
+ .toTypedArray()
230
+
231
+ if (storageParts.size == 3) {
232
+ val totalStorageGB = storageParts[0].toDouble() / 1024 / 1024
233
+ totalStorageCapacity.value = String.format(Locale.getDefault(), "%.1fG", totalStorageGB)
234
+
235
+ val usedStorageGB = storageParts[1].toDouble() / 1024 / 1024
236
+ usedStorage.value = String.format(Locale.getDefault(), "%.1fG", usedStorageGB)
237
+
238
+ val remainingStorageGB = storageParts[2].toDouble() / 1024 / 1024
239
+ remainingStorageCapacity.value =
240
+ String.format(Locale.getDefault(), "%.1fG", remainingStorageGB)
241
+ }
242
+ } else {
243
+ totalStorageCapacity.value = String.format(Locale.getDefault(), "%.1fG", 0.0)
244
+ usedStorage.value = String.format(Locale.getDefault(), "%.1fG", 0.0)
245
+ remainingStorageCapacity.value = String.format(Locale.getDefault(), "%.1fG", 0.0)
246
+ }
247
+ Log.i(TAG, "Total Capacity: ${totalStorageCapacity.value}")
248
+ Log.i(TAG, "Used: ${usedStorage.value}")
249
+ Log.i(TAG, "Remaining Capacity: ${remainingStorageCapacity.value}")
250
+ }
251
+
252
+ fun setWatermark(
253
+ enable: Boolean,
254
+ isLoading: MutableState<Boolean>,
255
+ isWaterMarkEnabled: MutableState<Boolean>
256
+ ) {
257
+ isLoading.value = true
258
+ publishDps(
259
+ dpKey = DPConstants.WATERMARK,
260
+ value = enable,
261
+ onSuccess = {
262
+ isLoading.value = false
263
+ isWaterMarkEnabled.value = enable
264
+ Log.i(TAG, "Watermark value changed to $enable")
265
+ },
266
+ onError = { code, error ->
267
+ isLoading.value = false
268
+ Log.i(TAG, "Error in changing Watermark value: Error Code: $code, Error: $error")
269
+ }
270
+ )
271
+ }
272
+
273
+ fun setFlip(
274
+ enable: Boolean,
275
+ isLoading: MutableState<Boolean>,
276
+ isFlipEnabled: MutableState<Boolean>
277
+ ) {
278
+ isLoading.value = true
279
+ publishDps(
280
+ dpKey = DPConstants.BASIC_FLIP,
281
+ value = enable,
282
+ onSuccess = {
283
+ isLoading.value = false
284
+ isFlipEnabled.value = enable
285
+ Log.i(TAG, "Flip value changed to $enable")
286
+ },
287
+ onError = { code, error ->
288
+ isLoading.value = false
289
+ Log.i(TAG, "Error in changing Flip value: Error Code: $code, Error: $error")
290
+ }
291
+ )
292
+ }
293
+
294
+ fun setAntiDismantlingAlarm(
295
+ enable: Boolean,
296
+ isLoading: MutableState<Boolean>,
297
+ isAntiDismantlingAlarmEnabled: MutableState<Boolean>
298
+ ) {
299
+ isLoading.value = true
300
+ publishDps(
301
+ dpKey = DPConstants.ANTI_DISMANTLING_ALARM,
302
+ value = enable,
303
+ onSuccess = {
304
+ isLoading.value = false
305
+ isAntiDismantlingAlarmEnabled.value = enable
306
+ Log.i(TAG, "Anti-Dismantling Alarm value changed to $enable")
307
+ },
308
+ onError = { code, error ->
309
+ isLoading.value = false
310
+ Log.i(
311
+ TAG,
312
+ "Error in changing Anti-Dismantling Alarm value: Error Code: $code, Error: $error"
313
+ )
314
+ }
315
+ )
316
+ }
317
+
318
+ fun setNightVision(
319
+ newMode: String,
320
+ mode: MutableState<String>,
321
+ isLoading: MutableState<Boolean>
322
+ ) {
323
+ isLoading.value = true
324
+ publishDps(
325
+ dpKey = DPConstants.BASIC_NIGHT_VISION,
326
+ value = newMode,
327
+ onSuccess = {
328
+ isLoading.value = false
329
+ mode.value = newMode
330
+ Log.i(TAG, "Night Vision value changed to $newMode")
331
+ },
332
+ onError = { code, error ->
333
+ isLoading.value = false
334
+ Log.i(TAG, "Error in changing Night Vision value: Error Code: $code, Error: $error")
335
+ }
336
+ )
337
+ }
338
+
339
+ fun setMotionDetection(
340
+ is8s: Boolean,
341
+ enable: Boolean,
342
+ isLoading: MutableState<Boolean>,
343
+ isMotionDetectionEnabled: MutableState<Boolean>
344
+ ) {
345
+ isLoading.value = true
346
+ publishDps(
347
+ dpKey = if (is8s) DPConstants.MOTION_SWITCH else DPConstants.PIR_SWITCH,
348
+ value = enable,
349
+ onSuccess = {
350
+ isLoading.value = false
351
+ isMotionDetectionEnabled.value = enable
352
+ Log.i(TAG, "Motion/PIR Detection value changed to $enable")
353
+ },
354
+ onError = { code, error ->
355
+ isLoading.value = false
356
+ Log.i(
357
+ TAG,
358
+ "Error in changing Motion/PIR Detection value: Error Code: $code, Error: $error"
359
+ )
360
+ }
361
+ )
362
+ }
363
+
364
+ fun setMotionSensitivity(
365
+ newMode: String,
366
+ mode: MutableState<String>,
367
+ isLoading: MutableState<Boolean>,
368
+ isAOSU: Boolean = false
369
+ ) {
370
+ isLoading.value = true
371
+ publishDps(
372
+ dpKey = if (isAOSU) DPConstants.MOTION_SENSITIVITY_AOSU else DPConstants.MOTION_SENSITIVITY,
373
+ value = newMode,
374
+ onSuccess = {
375
+ isLoading.value = false
376
+ mode.value = newMode
377
+ Log.i(TAG, "Motion Sensitivity changed to $newMode")
378
+ },
379
+ onError = { code, error ->
380
+ isLoading.value = false
381
+ Log.i(
382
+ TAG,
383
+ "Error in changing Motion Sensitivity value: Error Code: $code, Error: $error"
384
+ )
385
+ }
386
+ )
387
+ }
388
+
389
+ fun setPIRSensitivity(
390
+ newMode: Int,
391
+ mode: MutableState<Int>,
392
+ isLoading: MutableState<Boolean>
393
+ ) {
394
+ isLoading.value = true
395
+ publishDps(
396
+ dpKey = DPConstants.PIR_SENSITIVITY,
397
+ value = newMode,
398
+ onSuccess = {
399
+ isLoading.value = false
400
+ mode.value = newMode
401
+ Log.i(TAG, "PIR Sensitivity changed to $newMode")
402
+ },
403
+ onError = { code, error ->
404
+ isLoading.value = false
405
+ Log.i(
406
+ TAG,
407
+ "Error in changing PIR Sensitivity value: Error Code: $code, Error: $error"
408
+ )
409
+ }
410
+ )
411
+ }
412
+
413
+ fun setSDCardRecording(
414
+ enable: Boolean,
415
+ isLoading: MutableState<Boolean>,
416
+ isSDCardRecordingEnabled: MutableState<Boolean>
417
+ ) {
418
+ isLoading.value = true
419
+ publishDps(
420
+ dpKey = DPConstants.SD_RECORD_SWITCH,
421
+ value = enable,
422
+ onSuccess = {
423
+ isLoading.value = false
424
+ isSDCardRecordingEnabled.value = enable
425
+ Log.i(TAG, "SD card recording enabled set to $enable")
426
+ },
427
+ onError = { code, error ->
428
+ isLoading.value = false
429
+ Log.i(
430
+ TAG,
431
+ "Error in changing SD card recording value: Error Code: $code, Error: $error"
432
+ )
433
+ }
434
+ )
435
+ }
436
+
437
+ fun setSDCardRecordingMode(
438
+ newMode: String,
439
+ mode: MutableState<String>,
440
+ isLoading: MutableState<Boolean>
441
+ ) {
442
+ isLoading.value = true
443
+ publishDps(
444
+ dpKey = DPConstants.SD_RECORD_MODE,
445
+ value = newMode,
446
+ onSuccess = {
447
+ isLoading.value = false
448
+ mode.value = newMode
449
+ Log.i(TAG, "SD Card Recording mode changed to $newMode")
450
+ },
451
+ onError = { code, error ->
452
+ isLoading.value = false
453
+ Log.i(
454
+ TAG,
455
+ "Error in changing Sd Card Recording Mode value: Error Code: $code, Error: $error"
456
+ )
457
+ }
458
+ )
459
+ }
460
+
461
+ fun setChime(
462
+ newMode: String,
463
+ mode: MutableState<String>,
464
+ isLoading: MutableState<Boolean>
465
+ ) {
466
+ isLoading.value = true
467
+ publishDps(
468
+ dpKey = DPConstants.CHIME_TYPE,
469
+ value = newMode,
470
+ onSuccess = {
471
+ isLoading.value = false
472
+ mode.value = newMode
473
+ Log.i(TAG, "Chime value changed to $newMode")
474
+ },
475
+ onError = { code, error ->
476
+ isLoading.value = false
477
+ Log.i(TAG, "Error in changing Chime value: Error Code: $code, Error: $error")
478
+ }
479
+ )
480
+ }
481
+
482
+ fun formatSDCard(
483
+ isLoading: MutableState<Boolean>? = null
484
+ ) {
485
+ isLoading?.value = true
486
+ publishDps(
487
+ dpKey = DPConstants.SD_FORMAT,
488
+ value = true,
489
+ onSuccess = {
490
+ isLoading?.value = false
491
+ Log.i(TAG, "SD Card Format started")
492
+ },
493
+ onError = { code, error ->
494
+ isLoading?.value = false
495
+ Log.i(TAG, "Error in SD Card Format: Error Code: $code, Error: $error")
496
+ }
497
+ )
498
+ }
499
+
500
+ fun getMemoryCardCapacity(
501
+ totalStorageCapacity: MutableState<String>,
502
+ usedStorage: MutableState<String>,
503
+ remainingStorageCapacity: MutableState<String>
504
+ ) {
505
+
506
+ val value = queryValueByDPID(deviceId = deviceId, dpId = DPConstants.SD_STORAGE)
507
+
508
+ if (value.isNotNull()) {
509
+ parseStorageValue(
510
+ value = value,
511
+ totalStorageCapacity = totalStorageCapacity,
512
+ usedStorage = usedStorage,
513
+ remainingStorageCapacity = remainingStorageCapacity
514
+ )
515
+ }
516
+ }
517
+
518
+ fun getFirmwareVersion(
519
+ isLoading: MutableState<Boolean>,
520
+ firmwareVersion: MutableState<String?>
521
+ ) {
522
+ isLoading.value = true
523
+ val otaService = ThingHomeSdk.newOTAServiceInstance(deviceId)
524
+ otaService.getFirmwareUpgradeInfo(object : IGetOtaInfoCallback {
525
+ override fun onSuccess(upgradeInfoBeans: List<UpgradeInfoBean>) {
526
+ val mainModuleBean = upgradeInfoBeans.firstOrNull {
527
+ it.typeDesc.equals("Main Module", ignoreCase = true)
528
+ }
529
+ firmwareVersion.value = mainModuleBean?.currentVersion?.let { "v$it" }
530
+ isLoading.value = false
531
+ Log.i(TAG, "Fetch current firmware version success: $upgradeInfoBeans")
532
+ }
533
+
534
+ override fun onFailure(code: String, error: String) {
535
+ isLoading.value = false
536
+ Log.e(TAG, "Failed to fetch firmware info: $code, $error")
537
+ Airbrake.logMessage(
538
+ title = "Get Firmware version Failed",
539
+ message = "Error Code: $code",
540
+ additionalInfo = mapOf("Error" to error)
541
+ )
542
+ }
543
+ })
544
+ }
545
+
546
+ fun queryValueByDPID(deviceId: String?, dpId: String): Any? {
547
+ val validDeviceId = deviceId ?: Tuya.deviceId
548
+ return if (validDeviceId.isNotNull()) {
549
+ ThingHomeSdk.getDataInstance().getDeviceBean(validDeviceId)?.getDps()?.get(dpId)
550
+ } else {
551
+ Log.i(TAG, "Device Id is null")
552
+ null
553
+ }
554
+ }
555
+
556
+ fun isDPSupported(
557
+ deviceId: String? = null,
558
+ dpId: String
559
+ ): Boolean {
560
+ val value = queryValueByDPID(deviceId, dpId)
561
+ return value.isNotNull()
562
+ }
563
+
564
+ private fun listenDPUpdate(
565
+ isWaterMarkEnabled: MutableState<Boolean>,
566
+ isFlipEnabled: MutableState<Boolean>,
567
+ isAntiDismantlingAlarmEnabled: MutableState<Boolean>,
568
+ nightVisionLevel: MutableState<String>,
569
+ isMotionDetectionEnabled: MutableState<Boolean>,
570
+ motionSensitivityLevel: MutableState<String>,
571
+ aosuMotionSensitivityLevel: MutableState<String>,
572
+ isPIRDetectionEnabled: MutableState<Boolean>,
573
+ pirSensitivityLevel: MutableState<Int>,
574
+ storageFunctionType: MutableState<Int>,
575
+ isSDCardRecordingEnabled: MutableState<Boolean>,
576
+ sdCardRecordingType: MutableState<String>,
577
+ chimeType: MutableState<String>,
578
+ powerSource: MutableState<String>,
579
+ batteryPercentage: MutableState<Int>,
580
+ totalStorageCapacity: MutableState<String>,
581
+ usedStorage: MutableState<String>,
582
+ remainingStorageCapacity: MutableState<String>
583
+ ) {
584
+ ThingHomeSdk.newDeviceInstance(deviceId).registerDevListener(object : IDevListener {
585
+ override fun onDpUpdate(devId: String, dpStr: String) {
586
+ try {
587
+ val obj = JSONObject(dpStr)
588
+ val keys = obj.keys()
589
+ val key = keys.next()
590
+ if (key.isNotNull()) {
591
+ Log.i(TAG, "dp listen $key ${obj.getString(key)}")
592
+ when (key) {
593
+ DPConstants.WATERMARK -> {
594
+ isWaterMarkEnabled.value = obj.getBoolean(key)
595
+ }
596
+
597
+ DPConstants.BASIC_FLIP -> {
598
+ isFlipEnabled.value = obj.getBoolean(key)
599
+ }
600
+
601
+ DPConstants.ANTI_DISMANTLING_ALARM -> {
602
+ isAntiDismantlingAlarmEnabled.value = obj.getBoolean(key)
603
+ }
604
+
605
+ DPConstants.BASIC_NIGHT_VISION -> {
606
+ nightVisionLevel.value = obj.getString(key)
607
+ }
608
+
609
+ DPConstants.MOTION_SWITCH -> {
610
+ isMotionDetectionEnabled.value = obj.getBoolean(key)
611
+ }
612
+
613
+ DPConstants.MOTION_SENSITIVITY -> {
614
+ motionSensitivityLevel.value = obj.getString(key)
615
+ }
616
+
617
+ DPConstants.MOTION_SENSITIVITY_AOSU -> {
618
+ aosuMotionSensitivityLevel.value = obj.getString(key)
619
+ }
620
+
621
+ DPConstants.PIR_SWITCH -> {
622
+ isPIRDetectionEnabled.value = obj.getBoolean(key)
623
+ }
624
+
625
+ DPConstants.PIR_SENSITIVITY -> {
626
+ pirSensitivityLevel.value = obj.getInt(key)
627
+ }
628
+
629
+ DPConstants.SD_STATUS -> {
630
+ storageFunctionType.value = obj.getInt(key)
631
+ }
632
+
633
+ DPConstants.SD_RECORD_SWITCH -> {
634
+ isSDCardRecordingEnabled.value = obj.getBoolean(key)
635
+ }
636
+
637
+ DPConstants.SD_RECORD_MODE -> {
638
+ sdCardRecordingType.value = obj.getString(key)
639
+ }
640
+
641
+ DPConstants.CHIME_TYPE -> {
642
+ chimeType.value = obj.getString(key)
643
+ }
644
+
645
+ DPConstants.WIRELESS_POWER_MODE -> {
646
+ powerSource.value = obj.getString(key)
647
+ }
648
+
649
+ DPConstants.WIRELESS_ELECTRICITY -> {
650
+ batteryPercentage.value = obj.getInt(key)
651
+ }
652
+
653
+ DPConstants.SD_STORAGE -> {
654
+ parseStorageValue(
655
+ value = obj.getInt(key),
656
+ totalStorageCapacity = totalStorageCapacity,
657
+ usedStorage = usedStorage,
658
+ remainingStorageCapacity = remainingStorageCapacity
659
+ )
660
+ }
661
+ }
662
+ }
663
+ } catch (e: Exception) {
664
+ Log.i(TAG, "Exception in listen onDPUpdate ${e.message}")
665
+ e.printStackTrace()
666
+ }
667
+ }
668
+
669
+ override fun onRemoved(devId: String) {
670
+ Log.i(TAG, "onRemoved $devId")
671
+ }
672
+
673
+ override fun onStatusChanged(devId: String, online: Boolean) {
674
+ Log.i(TAG, "onStatusChanged $devId $online")
675
+ }
676
+
677
+ override fun onNetworkStatusChanged(devId: String, status: Boolean) {
678
+ Log.i(TAG, "onNetworkStatusChanged $devId $status")
679
+ }
680
+
681
+ override fun onDevInfoUpdate(devId: String) {
682
+ Log.i(TAG, "onDevInfoUpdate $devId")
683
+ }
684
+ })
685
+ }
686
+ }
687
+
688
+ object DefaultSettings {
689
+
690
+ // For Default Settings
691
+ private var isMotionSensitivityUpdated = false
692
+ private var isMotionDetectionUpdated = false
693
+ private var isRecordingModeUpdated = false
694
+ private var isRetryRequired = true
695
+
696
+ private fun resetValues() {
697
+ isMotionSensitivityUpdated = false
698
+ isMotionDetectionUpdated = false
699
+ isRecordingModeUpdated = false
700
+ isRetryRequired = true
701
+ }
702
+
703
+ private suspend fun publishDps(dpKey: String, value: Any): Boolean =
704
+ suspendCoroutine { continuation ->
705
+ Settings.publishDps(
706
+ dpKey = dpKey,
707
+ value = value,
708
+ onSuccess = { continuation.resume(true) },
709
+ onError = { code, error ->
710
+ Log.i(TAG, "Failed to publish Dps for $dpKey, Code: $code, Error: $error")
711
+ continuation.resume(false)
712
+ }
713
+ )
714
+ }
715
+
716
+ suspend fun updateDoorbellSettings(reactContext: ReactContext) = withContext(Dispatchers.IO) {
717
+ while (true) {
718
+ try {
719
+ enableDefaultSettings()
720
+
721
+ if (isMotionDetectionUpdated && isMotionSensitivityUpdated && isRecordingModeUpdated) {
722
+ resetDefaultSettingsValue(reactContext = reactContext)
723
+ resetValues()
724
+ break
725
+ } else if (isRetryRequired) {
726
+ isRetryRequired = false
727
+ } else {
728
+ resetValues()
729
+ break
730
+ }
731
+ } catch (e: Exception) {
732
+ Airbrake.logMessage(
733
+ title = "Update Doorbell Default Settings Failed",
734
+ message = "Error: ${e.message}"
735
+ )
736
+ break
737
+ }
738
+ }
739
+ }
740
+
741
+ private fun resetDefaultSettingsValue(reactContext: ReactContext) {
742
+ reactContext.let { context ->
743
+ val keylessModule = context.getNativeModule(KeylessModule::class.java)
744
+ Tuya.id?.let {
745
+ keylessModule?.sendDataToJS(
746
+ eventName = "resetDoorbellDefaultSettingsFlag",
747
+ deviceId = it,
748
+ onSuccess = {
749
+ Log.i(TAG, "Reset Default Settings Success")
750
+ },
751
+ onFailure = {
752
+ Log.i(TAG, "Reset Default Settings Failed")
753
+ }
754
+ )
755
+ } ?: Log.i(TAG, "ID is null")
756
+ }
757
+ }
758
+
759
+ private suspend fun enableDefaultSettings() = withContext(Dispatchers.IO) {
760
+ try {
761
+ if (Settings.isAOSU()){
762
+ // AOSU Doorbell Logic
763
+ handleMotionDetection(DPConstants.MOTION_SWITCH, DPConstants.MOTION_SENSITIVITY_AOSU, "1")
764
+ isRecordingModeUpdated= true // Recording mode not supported for AOSU
765
+ } else if (!Settings.is8s()) {
766
+ // 15s Doorbell Logic
767
+ handleMotionDetection(DPConstants.PIR_SWITCH, DPConstants.PIR_SENSITIVITY, 1)
768
+ isRecordingModeUpdated = true // Recording mode not supported for 15s Doorbell
769
+ } else {
770
+ // 8s Doorbell Logic
771
+ handleMotionDetection(DPConstants.MOTION_SWITCH, DPConstants.MOTION_SENSITIVITY, "0")
772
+ isRecordingModeUpdated = handleRecordingMode()
773
+ }
774
+ } catch (e: Exception) {
775
+ Airbrake.logMessage(
776
+ title = "Enable Doorbell Default Settings Failed",
777
+ message = "Error: ${e.message}"
778
+ )
779
+ }
780
+ }
781
+
782
+ private suspend fun handleMotionDetection(
783
+ switchKey: String,
784
+ sensitivityKey: String,
785
+ sensitivityValue: Any
786
+ ) {
787
+ isMotionDetectionUpdated = publishDps(switchKey, Tuya.motionDetection)
788
+
789
+ isMotionSensitivityUpdated = if (Tuya.setSensitivityLow && !isMotionSensitivityUpdated) {
790
+ publishDps(sensitivityKey, sensitivityValue)
791
+ } else {
792
+ true
793
+ }
794
+ }
795
+
796
+ private suspend fun handleRecordingMode(): Boolean {
797
+ if (Tuya.continuousRecording || Tuya.eventRecording) {
798
+ val recordingSwitchUpdated = publishDps(DPConstants.SD_RECORD_SWITCH, true)
799
+ return if (recordingSwitchUpdated) {
800
+ when {
801
+ Tuya.continuousRecording -> publishDps(DPConstants.SD_RECORD_MODE, "2")
802
+ Tuya.eventRecording -> publishDps(DPConstants.SD_RECORD_MODE, "1")
803
+ else -> true
804
+ }
805
+ } else false
806
+ }
807
+ return true
808
+ }
809
+ }