@homebridge-plugins/homebridge-eufy-security 4.7.2 → 5.0.0-beta.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 (471) hide show
  1. package/AUTHORS +4 -0
  2. package/CODE_OF_CONDUCT.md +30 -0
  3. package/CONTRIBUTING.md +77 -0
  4. package/README.md +152 -49
  5. package/SECURITY.md +30 -0
  6. package/config.schema.json +92 -3
  7. package/dist/account/ownership.js +290 -0
  8. package/dist/account/ownership.js.map +1 -0
  9. package/dist/account/persistence.js +274 -0
  10. package/dist/account/persistence.js.map +1 -0
  11. package/dist/account/temporary-authentication.js +348 -0
  12. package/dist/account/temporary-authentication.js.map +1 -0
  13. package/dist/configuration.js +167 -0
  14. package/dist/configuration.js.map +1 -0
  15. package/dist/device/member-evidence.js +66 -0
  16. package/dist/device/member-evidence.js.map +1 -0
  17. package/dist/device/member-trust.js +114 -0
  18. package/dist/device/member-trust.js.map +1 -0
  19. package/dist/device/snapshot.js +190 -0
  20. package/dist/device/snapshot.js.map +1 -0
  21. package/dist/diagnostics.js +2218 -0
  22. package/dist/diagnostics.js.map +1 -0
  23. package/dist/homekit/adapter.js +2 -0
  24. package/dist/homekit/adapter.js.map +1 -0
  25. package/dist/homekit/adapters/battery.js +208 -0
  26. package/dist/homekit/adapters/battery.js.map +1 -0
  27. package/dist/homekit/adapters/camera-controls.js +527 -0
  28. package/dist/homekit/adapters/camera-controls.js.map +1 -0
  29. package/dist/homekit/adapters/camera-streaming.js +1515 -0
  30. package/dist/homekit/adapters/camera-streaming.js.map +1 -0
  31. package/dist/homekit/adapters/contact.js +138 -0
  32. package/dist/homekit/adapters/contact.js.map +1 -0
  33. package/dist/homekit/adapters/doorbell.js +57 -0
  34. package/dist/homekit/adapters/doorbell.js.map +1 -0
  35. package/dist/homekit/adapters/information.js +55 -0
  36. package/dist/homekit/adapters/information.js.map +1 -0
  37. package/dist/homekit/adapters/lock.js +489 -0
  38. package/dist/homekit/adapters/lock.js.map +1 -0
  39. package/dist/homekit/adapters/motion.js +100 -0
  40. package/dist/homekit/adapters/motion.js.map +1 -0
  41. package/dist/homekit/adapters/registry.js +26 -0
  42. package/dist/homekit/adapters/registry.js.map +1 -0
  43. package/dist/homekit/adapters/security-system.js +425 -0
  44. package/dist/homekit/adapters/security-system.js.map +1 -0
  45. package/dist/homekit/adapters/siren.js +136 -0
  46. package/dist/homekit/adapters/siren.js.map +1 -0
  47. package/dist/homekit/adapters/smart-light.js +662 -0
  48. package/dist/homekit/adapters/smart-light.js.map +1 -0
  49. package/dist/homekit/coverage-matrix.js +119 -0
  50. package/dist/homekit/coverage-matrix.js.map +1 -0
  51. package/dist/homekit/device-control.js +175 -0
  52. package/dist/homekit/device-control.js.map +1 -0
  53. package/dist/homekit/reconciler.js +319 -0
  54. package/dist/homekit/reconciler.js.map +1 -0
  55. package/dist/homekit/representation.js +23 -0
  56. package/dist/homekit/representation.js.map +1 -0
  57. package/dist/index.js +4 -9
  58. package/dist/index.js.map +1 -1
  59. package/dist/media/contracts.js +2 -0
  60. package/dist/media/contracts.js.map +1 -0
  61. package/dist/media/last-successful-image.js +208 -0
  62. package/dist/media/last-successful-image.js.map +1 -0
  63. package/dist/media/live-stream.js +1003 -0
  64. package/dist/media/live-stream.js.map +1 -0
  65. package/dist/media/recording.js +560 -0
  66. package/dist/media/recording.js.map +1 -0
  67. package/dist/media/session-budget.js +39 -0
  68. package/dist/media/session-budget.js.map +1 -0
  69. package/dist/media/snapshot.js +406 -0
  70. package/dist/media/snapshot.js.map +1 -0
  71. package/dist/media/station-live-sessions.js +101 -0
  72. package/dist/media/station-live-sessions.js.map +1 -0
  73. package/dist/platform.js +97 -809
  74. package/dist/platform.js.map +1 -1
  75. package/dist/runtime/channel.js +375 -0
  76. package/dist/runtime/channel.js.map +1 -0
  77. package/dist/runtime/owner.js +682 -0
  78. package/dist/runtime/owner.js.map +1 -0
  79. package/dist/runtime/sdk-client.js +211 -0
  80. package/dist/runtime/sdk-client.js.map +1 -0
  81. package/dist/runtime/tracker.js +211 -0
  82. package/dist/runtime/tracker.js.map +1 -0
  83. package/dist/settings.js +1 -43
  84. package/dist/settings.js.map +1 -1
  85. package/dist/storage.js +59 -0
  86. package/dist/storage.js.map +1 -0
  87. package/dist/ui/dashboard.js +181 -0
  88. package/dist/ui/dashboard.js.map +1 -0
  89. package/dist/ui/device-image.js +22 -0
  90. package/dist/ui/device-image.js.map +1 -0
  91. package/dist/ui/runtime-channel-client.js +305 -0
  92. package/dist/ui/runtime-channel-client.js.map +1 -0
  93. package/dist/ui/server.js +259 -0
  94. package/dist/ui/server.js.map +1 -0
  95. package/homebridge-ui/public/app.css +1902 -0
  96. package/homebridge-ui/public/assets/devices/clean/clean-T1250.webp +0 -0
  97. package/homebridge-ui/public/assets/devices/clean/clean-T2070.webp +0 -0
  98. package/homebridge-ui/public/assets/devices/clean/clean-T2080.webp +0 -0
  99. package/homebridge-ui/public/assets/devices/clean/clean-T2081.webp +0 -0
  100. package/homebridge-ui/public/assets/devices/clean/clean-T2103.webp +0 -0
  101. package/homebridge-ui/public/assets/devices/clean/clean-T2117.webp +0 -0
  102. package/homebridge-ui/public/assets/devices/clean/clean-T2118.webp +0 -0
  103. package/homebridge-ui/public/assets/devices/clean/clean-T2119.webp +0 -0
  104. package/homebridge-ui/public/assets/devices/clean/clean-T211A.webp +0 -0
  105. package/homebridge-ui/public/assets/devices/clean/clean-T2120.webp +0 -0
  106. package/homebridge-ui/public/assets/devices/clean/clean-T2123.webp +0 -0
  107. package/homebridge-ui/public/assets/devices/clean/clean-T2128.webp +0 -0
  108. package/homebridge-ui/public/assets/devices/clean/clean-T2130.webp +0 -0
  109. package/homebridge-ui/public/assets/devices/clean/clean-T2132.webp +0 -0
  110. package/homebridge-ui/public/assets/devices/clean/clean-T2150.webp +0 -0
  111. package/homebridge-ui/public/assets/devices/clean/clean-T2181.webp +0 -0
  112. package/homebridge-ui/public/assets/devices/clean/clean-T2182.webp +0 -0
  113. package/homebridge-ui/public/assets/devices/clean/clean-T2190.webp +0 -0
  114. package/homebridge-ui/public/assets/devices/clean/clean-T2192.webp +0 -0
  115. package/homebridge-ui/public/assets/devices/clean/clean-T2193.webp +0 -0
  116. package/homebridge-ui/public/assets/devices/clean/clean-T2194.webp +0 -0
  117. package/homebridge-ui/public/assets/devices/clean/clean-T2210.webp +0 -0
  118. package/homebridge-ui/public/assets/devices/clean/clean-T2250.webp +0 -0
  119. package/homebridge-ui/public/assets/devices/clean/clean-T2251.webp +0 -0
  120. package/homebridge-ui/public/assets/devices/clean/clean-T2252.webp +0 -0
  121. package/homebridge-ui/public/assets/devices/clean/clean-T2253.webp +0 -0
  122. package/homebridge-ui/public/assets/devices/clean/clean-T2254.webp +0 -0
  123. package/homebridge-ui/public/assets/devices/clean/clean-T2255.webp +0 -0
  124. package/homebridge-ui/public/assets/devices/clean/clean-T2256.webp +0 -0
  125. package/homebridge-ui/public/assets/devices/clean/clean-T2257.webp +0 -0
  126. package/homebridge-ui/public/assets/devices/clean/clean-T2258.webp +0 -0
  127. package/homebridge-ui/public/assets/devices/clean/clean-T2259.webp +0 -0
  128. package/homebridge-ui/public/assets/devices/clean/clean-T2261.webp +0 -0
  129. package/homebridge-ui/public/assets/devices/clean/clean-T2262.webp +0 -0
  130. package/homebridge-ui/public/assets/devices/clean/clean-T2266.webp +0 -0
  131. package/homebridge-ui/public/assets/devices/clean/clean-T2267.webp +0 -0
  132. package/homebridge-ui/public/assets/devices/clean/clean-T2268.webp +0 -0
  133. package/homebridge-ui/public/assets/devices/clean/clean-T2270.webp +0 -0
  134. package/homebridge-ui/public/assets/devices/clean/clean-T2272.webp +0 -0
  135. package/homebridge-ui/public/assets/devices/clean/clean-T2273.webp +0 -0
  136. package/homebridge-ui/public/assets/devices/clean/clean-T2276.webp +0 -0
  137. package/homebridge-ui/public/assets/devices/clean/clean-T2277.webp +0 -0
  138. package/homebridge-ui/public/assets/devices/clean/clean-T2278.webp +0 -0
  139. package/homebridge-ui/public/assets/devices/clean/clean-T2280.webp +0 -0
  140. package/homebridge-ui/public/assets/devices/clean/clean-T2292.webp +0 -0
  141. package/homebridge-ui/public/assets/devices/clean/clean-T2320.webp +0 -0
  142. package/homebridge-ui/public/assets/devices/clean/clean-T2351.webp +0 -0
  143. package/homebridge-ui/public/assets/devices/clean/clean-T2352.webp +0 -0
  144. package/homebridge-ui/public/assets/devices/clean/clean-T2353.webp +0 -0
  145. package/homebridge-ui/public/assets/devices/life/life-T8L00.webp +0 -0
  146. package/homebridge-ui/public/assets/devices/life/life-T8L01.webp +0 -0
  147. package/homebridge-ui/public/assets/devices/life/life-T8L02.webp +0 -0
  148. package/homebridge-ui/public/assets/devices/life/life-T8L04.webp +0 -0
  149. package/homebridge-ui/public/assets/devices/life/life-T8L10.webp +0 -0
  150. package/homebridge-ui/public/assets/devices/life/life-T8L20.webp +0 -0
  151. package/homebridge-ui/public/assets/devices/life/life-T8L30.webp +0 -0
  152. package/homebridge-ui/public/assets/devices/life/life-T8L40.webp +0 -0
  153. package/homebridge-ui/public/assets/devices/mower/mower-T2801.webp +0 -0
  154. package/homebridge-ui/public/assets/devices/mower/mower-T280B.webp +0 -0
  155. package/homebridge-ui/public/assets/devices/mower/mower-T2880.webp +0 -0
  156. package/homebridge-ui/public/assets/devices/security/security-T7400.webp +0 -0
  157. package/homebridge-ui/public/assets/devices/security/security-T7401.webp +0 -0
  158. package/homebridge-ui/public/assets/devices/security/security-T8001.webp +0 -0
  159. package/homebridge-ui/public/assets/devices/security/security-T8002.webp +0 -0
  160. package/homebridge-ui/public/assets/devices/security/security-T8010.webp +0 -0
  161. package/homebridge-ui/public/assets/devices/security/security-T8021.webp +0 -0
  162. package/homebridge-ui/public/assets/devices/security/security-T8023.webp +0 -0
  163. package/homebridge-ui/public/assets/devices/security/security-T8025.webp +0 -0
  164. package/homebridge-ui/public/assets/devices/security/security-T8030.webp +0 -0
  165. package/homebridge-ui/public/assets/devices/security/security-T8110.webp +0 -0
  166. package/homebridge-ui/public/assets/devices/security/security-T8111.webp +0 -0
  167. package/homebridge-ui/public/assets/devices/security/security-T8112.webp +0 -0
  168. package/homebridge-ui/public/assets/devices/security/security-T8113.webp +0 -0
  169. package/homebridge-ui/public/assets/devices/security/security-T8114.webp +0 -0
  170. package/homebridge-ui/public/assets/devices/security/security-T8122.webp +0 -0
  171. package/homebridge-ui/public/assets/devices/security/security-T8123.webp +0 -0
  172. package/homebridge-ui/public/assets/devices/security/security-T8124.webp +0 -0
  173. package/homebridge-ui/public/assets/devices/security/security-T8130.webp +0 -0
  174. package/homebridge-ui/public/assets/devices/security/security-T8131.webp +0 -0
  175. package/homebridge-ui/public/assets/devices/security/security-T8134.webp +0 -0
  176. package/homebridge-ui/public/assets/devices/security/security-T8140.webp +0 -0
  177. package/homebridge-ui/public/assets/devices/security/security-T8141.webp +0 -0
  178. package/homebridge-ui/public/assets/devices/security/security-T8150.webp +0 -0
  179. package/homebridge-ui/public/assets/devices/security/security-T8151.webp +0 -0
  180. package/homebridge-ui/public/assets/devices/security/security-T8152.webp +0 -0
  181. package/homebridge-ui/public/assets/devices/security/security-T8153.webp +0 -0
  182. package/homebridge-ui/public/assets/devices/security/security-T8160.webp +0 -0
  183. package/homebridge-ui/public/assets/devices/security/security-T8161.webp +0 -0
  184. package/homebridge-ui/public/assets/devices/security/security-T8162.webp +0 -0
  185. package/homebridge-ui/public/assets/devices/security/security-T8170.webp +0 -0
  186. package/homebridge-ui/public/assets/devices/security/security-T8171.webp +0 -0
  187. package/homebridge-ui/public/assets/devices/security/security-T8172.webp +0 -0
  188. package/homebridge-ui/public/assets/devices/security/security-T8173.webp +0 -0
  189. package/homebridge-ui/public/assets/devices/security/security-T8200.webp +0 -0
  190. package/homebridge-ui/public/assets/devices/security/security-T8200X.webp +0 -0
  191. package/homebridge-ui/public/assets/devices/security/security-T8201.webp +0 -0
  192. package/homebridge-ui/public/assets/devices/security/security-T8203.webp +0 -0
  193. package/homebridge-ui/public/assets/devices/security/security-T8210.webp +0 -0
  194. package/homebridge-ui/public/assets/devices/security/security-T8213.webp +0 -0
  195. package/homebridge-ui/public/assets/devices/security/security-T8214.webp +0 -0
  196. package/homebridge-ui/public/assets/devices/security/security-T8222.webp +0 -0
  197. package/homebridge-ui/public/assets/devices/security/security-T8400.webp +0 -0
  198. package/homebridge-ui/public/assets/devices/security/security-T8401.webp +0 -0
  199. package/homebridge-ui/public/assets/devices/security/security-T8410.webp +0 -0
  200. package/homebridge-ui/public/assets/devices/security/security-T8411.webp +0 -0
  201. package/homebridge-ui/public/assets/devices/security/security-T8414.webp +0 -0
  202. package/homebridge-ui/public/assets/devices/security/security-T8416.webp +0 -0
  203. package/homebridge-ui/public/assets/devices/security/security-T8417.webp +0 -0
  204. package/homebridge-ui/public/assets/devices/security/security-T8419.webp +0 -0
  205. package/homebridge-ui/public/assets/devices/security/security-T8419N.webp +0 -0
  206. package/homebridge-ui/public/assets/devices/security/security-T8420.webp +0 -0
  207. package/homebridge-ui/public/assets/devices/security/security-T8420X.webp +0 -0
  208. package/homebridge-ui/public/assets/devices/security/security-T8422.webp +0 -0
  209. package/homebridge-ui/public/assets/devices/security/security-T8423.webp +0 -0
  210. package/homebridge-ui/public/assets/devices/security/security-T8424.webp +0 -0
  211. package/homebridge-ui/public/assets/devices/security/security-T8425.webp +0 -0
  212. package/homebridge-ui/public/assets/devices/security/security-T8441.webp +0 -0
  213. package/homebridge-ui/public/assets/devices/security/security-T8442.webp +0 -0
  214. package/homebridge-ui/public/assets/devices/security/security-T8452.webp +0 -0
  215. package/homebridge-ui/public/assets/devices/security/security-T84A0.webp +0 -0
  216. package/homebridge-ui/public/assets/devices/security/security-T84A1.webp +0 -0
  217. package/homebridge-ui/public/assets/devices/security/security-T8500.webp +0 -0
  218. package/homebridge-ui/public/assets/devices/security/security-T8502.webp +0 -0
  219. package/homebridge-ui/public/assets/devices/security/security-T8503.webp +0 -0
  220. package/homebridge-ui/public/assets/devices/security/security-T8504.webp +0 -0
  221. package/homebridge-ui/public/assets/devices/security/security-T8506.webp +0 -0
  222. package/homebridge-ui/public/assets/devices/security/security-T8510.webp +0 -0
  223. package/homebridge-ui/public/assets/devices/security/security-T8510P.webp +0 -0
  224. package/homebridge-ui/public/assets/devices/security/security-T8520.webp +0 -0
  225. package/homebridge-ui/public/assets/devices/security/security-T8520P.webp +0 -0
  226. package/homebridge-ui/public/assets/devices/security/security-T8530.webp +0 -0
  227. package/homebridge-ui/public/assets/devices/security/security-T8531.webp +0 -0
  228. package/homebridge-ui/public/assets/devices/security/security-T85D0.webp +0 -0
  229. package/homebridge-ui/public/assets/devices/security/security-T85L0.webp +0 -0
  230. package/homebridge-ui/public/assets/devices/security/security-T85P0.webp +0 -0
  231. package/homebridge-ui/public/assets/devices/security/security-T85V0.webp +0 -0
  232. package/homebridge-ui/public/assets/devices/security/security-T8600.webp +0 -0
  233. package/homebridge-ui/public/assets/devices/security/security-T86P2.webp +0 -0
  234. package/homebridge-ui/public/assets/devices/security/security-T8790.webp +0 -0
  235. package/homebridge-ui/public/assets/devices/security/security-T87B0.webp +0 -0
  236. package/homebridge-ui/public/assets/devices/security/security-T87B2.webp +0 -0
  237. package/homebridge-ui/public/assets/devices/security/security-T8900.webp +0 -0
  238. package/homebridge-ui/public/assets/devices/security/security-T8910.webp +0 -0
  239. package/homebridge-ui/public/assets/devices/security/security-T8920.webp +0 -0
  240. package/homebridge-ui/public/assets/devices/security/security-T8960.webp +0 -0
  241. package/homebridge-ui/public/assets/devices/security/security-T8B0.webp +0 -0
  242. package/homebridge-ui/public/assets/devices/security/security-T8E00.webp +0 -0
  243. package/homebridge-ui/public/assets/devices/security/security-T8N00.webp +0 -0
  244. package/homebridge-ui/public/assets/devices/security/security-T8W11C.webp +0 -0
  245. package/homebridge-ui/public/assets/devices/security/security-T90F0.webp +0 -0
  246. package/homebridge-ui/public/assets/devices/security/security-T90M0.webp +0 -0
  247. package/homebridge-ui/public/assets/devices/security/security-T90R0.webp +0 -0
  248. package/homebridge-ui/public/assets/devices/security/security-T90S0.webp +0 -0
  249. package/homebridge-ui/public/assets/icons/inventory.svg +1 -1
  250. package/homebridge-ui/public/assets/icons/troubleshoot.svg +1 -0
  251. package/homebridge-ui/public/assets/icons/warning.svg +1 -1
  252. package/homebridge-ui/public/assets/logo-dark.svg +10 -0
  253. package/homebridge-ui/public/assets/logo.svg +10 -0
  254. package/homebridge-ui/public/i18n/en.json +218 -0
  255. package/homebridge-ui/public/i18n/fr.json +218 -0
  256. package/homebridge-ui/public/index.html +377 -28
  257. package/homebridge-ui/public/js/app.js +1065 -0
  258. package/homebridge-ui/public/js/dashboard.js +385 -0
  259. package/homebridge-ui/public/js/legacy-settings.js +37 -0
  260. package/homebridge-ui/public/js/profile-wizard.js +68 -0
  261. package/homebridge-ui/server.js +2 -1393
  262. package/i18n/runtime/en.json +100 -0
  263. package/media/Snapshot-Unavailable.jpg +0 -0
  264. package/media/Snapshot-black.jpg +0 -0
  265. package/media/camera-disabled.jpg +0 -0
  266. package/media/camera-offline.jpg +0 -0
  267. package/package.json +29 -24
  268. package/.claude/CLAUDE.md +0 -175
  269. package/.claude/PRD.md +0 -241
  270. package/.claude/docs/debug-recording-lessons.md +0 -91
  271. package/.claude/docs/hksv-recording-fix.md +0 -160
  272. package/.claude/skills/architect/SKILL.md +0 -76
  273. package/.claude/skills/developer/SKILL.md +0 -59
  274. package/.claude/skills/new-device-support/SKILL.md +0 -212
  275. package/.claude/skills/new-device-support/check-device.mjs +0 -363
  276. package/.claude/skills/new-device-support/map-properties.mjs +0 -450
  277. package/.claude/skills/new-device-support/verify-device.mjs +0 -272
  278. package/.claude/skills/planner/SKILL.md +0 -100
  279. package/.claude/skills/qa/SKILL.md +0 -79
  280. package/.claude/skills/support/SKILL.md +0 -175
  281. package/.prettierignore +0 -7
  282. package/.prettierrc.json +0 -7
  283. package/FUNDING.yml +0 -1
  284. package/dist/accessories/AutoSyncStationAccessory.js +0 -157
  285. package/dist/accessories/AutoSyncStationAccessory.js.map +0 -1
  286. package/dist/accessories/BaseAccessory.js +0 -261
  287. package/dist/accessories/BaseAccessory.js.map +0 -1
  288. package/dist/accessories/CameraAccessory.js +0 -459
  289. package/dist/accessories/CameraAccessory.js.map +0 -1
  290. package/dist/accessories/Device.js +0 -65
  291. package/dist/accessories/Device.js.map +0 -1
  292. package/dist/accessories/EntrySensorAccessory.js +0 -48
  293. package/dist/accessories/EntrySensorAccessory.js.map +0 -1
  294. package/dist/accessories/GarageDoorAccessory.js +0 -160
  295. package/dist/accessories/GarageDoorAccessory.js.map +0 -1
  296. package/dist/accessories/LockAccessory.js +0 -142
  297. package/dist/accessories/LockAccessory.js.map +0 -1
  298. package/dist/accessories/MotionSensorAccessory.js +0 -48
  299. package/dist/accessories/MotionSensorAccessory.js.map +0 -1
  300. package/dist/accessories/SmartDropAccessory.js +0 -141
  301. package/dist/accessories/SmartDropAccessory.js.map +0 -1
  302. package/dist/accessories/StationAccessory.js +0 -373
  303. package/dist/accessories/StationAccessory.js.map +0 -1
  304. package/dist/config.js +0 -26
  305. package/dist/config.js.map +0 -1
  306. package/dist/controller/DebugRecordingManager.js +0 -402
  307. package/dist/controller/DebugRecordingManager.js.map +0 -1
  308. package/dist/controller/LocalLivestreamManager.js +0 -371
  309. package/dist/controller/LocalLivestreamManager.js.map +0 -1
  310. package/dist/controller/recordingDelegate.js +0 -252
  311. package/dist/controller/recordingDelegate.js.map +0 -1
  312. package/dist/controller/snapshotDelegate.js +0 -348
  313. package/dist/controller/snapshotDelegate.js.map +0 -1
  314. package/dist/controller/streamingDelegate.js +0 -389
  315. package/dist/controller/streamingDelegate.js.map +0 -1
  316. package/dist/interfaces.js +0 -2
  317. package/dist/interfaces.js.map +0 -1
  318. package/dist/media/Snapshot-Unavailable.png +0 -0
  319. package/dist/media/Snapshot-Unavailable.xcf +0 -0
  320. package/dist/media/Snapshot-black.png +0 -0
  321. package/dist/media/camera-disabled.png +0 -0
  322. package/dist/media/camera-offline.png +0 -0
  323. package/dist/media/media/Snapshot-Unavailable.png +0 -0
  324. package/dist/media/media/Snapshot-Unavailable.xcf +0 -0
  325. package/dist/media/media/Snapshot-black.png +0 -0
  326. package/dist/media/media/camera-disabled.png +0 -0
  327. package/dist/media/media/camera-offline.png +0 -0
  328. package/dist/utils/Talkback.js +0 -162
  329. package/dist/utils/Talkback.js.map +0 -1
  330. package/dist/utils/accessoriesStore.js +0 -210
  331. package/dist/utils/accessoriesStore.js.map +0 -1
  332. package/dist/utils/configTypes.js +0 -38
  333. package/dist/utils/configTypes.js.map +0 -1
  334. package/dist/utils/ffmpeg.js +0 -1111
  335. package/dist/utils/ffmpeg.js.map +0 -1
  336. package/dist/utils/interfaces.js +0 -8
  337. package/dist/utils/interfaces.js.map +0 -1
  338. package/dist/utils/utils.js +0 -224
  339. package/dist/utils/utils.js.map +0 -1
  340. package/dist/version.js +0 -2
  341. package/dist/version.js.map +0 -1
  342. package/homebridge-eufy-security.png +0 -0
  343. package/homebridge-ui/diagnosticsCrypto.js +0 -112
  344. package/homebridge-ui/public/app.js +0 -237
  345. package/homebridge-ui/public/assets/devices/4g_lte_cam_s330_large.png +0 -0
  346. package/homebridge-ui/public/assets/devices/4g_lte_starlight_large.jpg +0 -0
  347. package/homebridge-ui/public/assets/devices/BATTERY_DOORBELL_C30.png +0 -0
  348. package/homebridge-ui/public/assets/devices/BATTERY_DOORBELL_C31.png +0 -0
  349. package/homebridge-ui/public/assets/devices/batterydoorbell1080p_large.jpg +0 -0
  350. package/homebridge-ui/public/assets/devices/batterydoorbell2k_large.png +0 -0
  351. package/homebridge-ui/public/assets/devices/batterydoorbell2kdual_large.jpg +0 -0
  352. package/homebridge-ui/public/assets/devices/batterydoorbell_e340_large.png +0 -0
  353. package/homebridge-ui/public/assets/devices/eufy-security-client.png +0 -0
  354. package/homebridge-ui/public/assets/devices/eufyCamS4_large.png +0 -0
  355. package/homebridge-ui/public/assets/devices/eufycam2_large.png +0 -0
  356. package/homebridge-ui/public/assets/devices/eufycam2c_large.jpg +0 -0
  357. package/homebridge-ui/public/assets/devices/eufycam2cpro_large.jpg +0 -0
  358. package/homebridge-ui/public/assets/devices/eufycam2pro_large.jpg +0 -0
  359. package/homebridge-ui/public/assets/devices/eufycam3_large.jpg +0 -0
  360. package/homebridge-ui/public/assets/devices/eufycam3c_large.jpg +0 -0
  361. package/homebridge-ui/public/assets/devices/eufycam3pro_large.png +0 -0
  362. package/homebridge-ui/public/assets/devices/eufycam_large.jpg +0 -0
  363. package/homebridge-ui/public/assets/devices/eufycame330_large.jpg +0 -0
  364. package/homebridge-ui/public/assets/devices/flood_freeze_sensor_e20_t90F0_large.png +0 -0
  365. package/homebridge-ui/public/assets/devices/floodlight2_large.jpg +0 -0
  366. package/homebridge-ui/public/assets/devices/floodlight2pro_large.jpg +0 -0
  367. package/homebridge-ui/public/assets/devices/floodlight_large.jpg +0 -0
  368. package/homebridge-ui/public/assets/devices/floodlightcame340_large.jpg +0 -0
  369. package/homebridge-ui/public/assets/devices/garage_camera_t8452_large.png +0 -0
  370. package/homebridge-ui/public/assets/devices/homebase2_large.png +0 -0
  371. package/homebridge-ui/public/assets/devices/homebase3_large.png +0 -0
  372. package/homebridge-ui/public/assets/devices/homebase_large.jpg +0 -0
  373. package/homebridge-ui/public/assets/devices/homebasemini_large.png +0 -0
  374. package/homebridge-ui/public/assets/devices/indoorcamC210_large.png +0 -0
  375. package/homebridge-ui/public/assets/devices/indoorcamC220_large.png +0 -0
  376. package/homebridge-ui/public/assets/devices/indoorcamC220_t8419N_large.png +0 -0
  377. package/homebridge-ui/public/assets/devices/indoorcamE30_large.png +0 -0
  378. package/homebridge-ui/public/assets/devices/indoorcamc120_large.png +0 -0
  379. package/homebridge-ui/public/assets/devices/indoorcammini_large.jpg +0 -0
  380. package/homebridge-ui/public/assets/devices/indoorcamp24_large.png +0 -0
  381. package/homebridge-ui/public/assets/devices/indoorcams350_large.png +0 -0
  382. package/homebridge-ui/public/assets/devices/keypad_large.png +0 -0
  383. package/homebridge-ui/public/assets/devices/minibase_chime_T8023_large.jpg +0 -0
  384. package/homebridge-ui/public/assets/devices/motionsensor_large.png +0 -0
  385. package/homebridge-ui/public/assets/devices/nvr_s4_max_T8N00_large.png +0 -0
  386. package/homebridge-ui/public/assets/devices/pir_sensor_e20_large.png +0 -0
  387. package/homebridge-ui/public/assets/devices/poe_bullet_ptz_cam_s4_T8E00_large.png +0 -0
  388. package/homebridge-ui/public/assets/devices/sensor_large.png +0 -0
  389. package/homebridge-ui/public/assets/devices/siren_sensor_e20_large.png +0 -0
  390. package/homebridge-ui/public/assets/devices/smartdrop_t8790_large.png +0 -0
  391. package/homebridge-ui/public/assets/devices/smartlock_t8500_large.png +0 -0
  392. package/homebridge-ui/public/assets/devices/smartlock_t8500_wifibridge_large.jpg +0 -0
  393. package/homebridge-ui/public/assets/devices/smartlock_t8503_large.png +0 -0
  394. package/homebridge-ui/public/assets/devices/smartlock_t8504_large.jpg +0 -0
  395. package/homebridge-ui/public/assets/devices/smartlock_t8510P_t8520P_large.png +0 -0
  396. package/homebridge-ui/public/assets/devices/smartlock_t85D0_large.png +0 -0
  397. package/homebridge-ui/public/assets/devices/smartlock_t85L0_large.png +0 -0
  398. package/homebridge-ui/public/assets/devices/smartlock_t85P0_large.png +0 -0
  399. package/homebridge-ui/public/assets/devices/smartlock_t85V0_large.png +0 -0
  400. package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8502_large.png +0 -0
  401. package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8506_large.png +0 -0
  402. package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8520_large.png +0 -0
  403. package/homebridge-ui/public/assets/devices/smartlock_touch_t8510_large.png +0 -0
  404. package/homebridge-ui/public/assets/devices/smartlock_touch_t8510_wifibridge_large.jpg +0 -0
  405. package/homebridge-ui/public/assets/devices/smartlock_video_t8530_large.png +0 -0
  406. package/homebridge-ui/public/assets/devices/smartlock_video_t8531_large.png +0 -0
  407. package/homebridge-ui/public/assets/devices/smartlockwifibridge_t8021_large.jpg +0 -0
  408. package/homebridge-ui/public/assets/devices/smartsafe_s10_t7400_large.png +0 -0
  409. package/homebridge-ui/public/assets/devices/smartsafe_s12_t7401_large.png +0 -0
  410. package/homebridge-ui/public/assets/devices/smarttrack_card_t87B2_large.png +0 -0
  411. package/homebridge-ui/public/assets/devices/smarttrack_link_t87B0_large.png +0 -0
  412. package/homebridge-ui/public/assets/devices/smoke_alarm_e10_t90S0_large.png +0 -0
  413. package/homebridge-ui/public/assets/devices/solocamc210_large.jpg +0 -0
  414. package/homebridge-ui/public/assets/devices/solocamc35_large.png +0 -0
  415. package/homebridge-ui/public/assets/devices/solocame20_large.jpg +0 -0
  416. package/homebridge-ui/public/assets/devices/solocame30_large.png +0 -0
  417. package/homebridge-ui/public/assets/devices/solocame40_large.jpg +0 -0
  418. package/homebridge-ui/public/assets/devices/solocame42_large.png +0 -0
  419. package/homebridge-ui/public/assets/devices/solocaml20_large.jpg +0 -0
  420. package/homebridge-ui/public/assets/devices/solocams220_large.jpg +0 -0
  421. package/homebridge-ui/public/assets/devices/solocams340_large.png +0 -0
  422. package/homebridge-ui/public/assets/devices/solocams40_large.jpg +0 -0
  423. package/homebridge-ui/public/assets/devices/soloindoorcamc24_large.jpg +0 -0
  424. package/homebridge-ui/public/assets/devices/solooutdoorcamc22_large.png +0 -0
  425. package/homebridge-ui/public/assets/devices/solooutdoorcamc24_large.jpg +0 -0
  426. package/homebridge-ui/public/assets/devices/unknown.png +0 -0
  427. package/homebridge-ui/public/assets/devices/walllight_s100_large.png +0 -0
  428. package/homebridge-ui/public/assets/devices/walllight_s120_large.png +0 -0
  429. package/homebridge-ui/public/assets/devices/water_freeze_sensor_t8920_large.png +0 -0
  430. package/homebridge-ui/public/assets/devices/wireddoorbell1080p_large.jpg +0 -0
  431. package/homebridge-ui/public/assets/devices/wireddoorbell2k_large.png +0 -0
  432. package/homebridge-ui/public/assets/devices/wireddoorbelldual_large.jpg +0 -0
  433. package/homebridge-ui/public/assets/icons/attach.svg +0 -1
  434. package/homebridge-ui/public/assets/icons/battery_0.svg +0 -1
  435. package/homebridge-ui/public/assets/icons/battery_1.svg +0 -1
  436. package/homebridge-ui/public/assets/icons/battery_2.svg +0 -1
  437. package/homebridge-ui/public/assets/icons/battery_3.svg +0 -1
  438. package/homebridge-ui/public/assets/icons/battery_4.svg +0 -1
  439. package/homebridge-ui/public/assets/icons/battery_5.svg +0 -1
  440. package/homebridge-ui/public/assets/icons/battery_6.svg +0 -1
  441. package/homebridge-ui/public/assets/icons/copy.svg +0 -1
  442. package/homebridge-ui/public/assets/icons/delete.svg +0 -1
  443. package/homebridge-ui/public/assets/icons/download.svg +0 -1
  444. package/homebridge-ui/public/assets/icons/info.svg +0 -1
  445. package/homebridge-ui/public/assets/icons/refresh.svg +0 -1
  446. package/homebridge-ui/public/assets/icons/satellite_alt.svg +0 -1
  447. package/homebridge-ui/public/assets/icons/solar_power.svg +0 -1
  448. package/homebridge-ui/public/components/device-card.js +0 -174
  449. package/homebridge-ui/public/components/guard-modes.js +0 -88
  450. package/homebridge-ui/public/components/number-input.js +0 -121
  451. package/homebridge-ui/public/components/select.js +0 -73
  452. package/homebridge-ui/public/components/toggle.js +0 -68
  453. package/homebridge-ui/public/services/api.js +0 -250
  454. package/homebridge-ui/public/services/config.js +0 -144
  455. package/homebridge-ui/public/style.css +0 -818
  456. package/homebridge-ui/public/utils/countries.js +0 -73
  457. package/homebridge-ui/public/utils/device-images.js +0 -102
  458. package/homebridge-ui/public/utils/helpers.js +0 -115
  459. package/homebridge-ui/public/views/dashboard.js +0 -226
  460. package/homebridge-ui/public/views/device-detail.js +0 -654
  461. package/homebridge-ui/public/views/diagnostics.js +0 -402
  462. package/homebridge-ui/public/views/login.js +0 -650
  463. package/homebridge-ui/public/views/recordings.js +0 -319
  464. package/homebridge-ui/public/views/settings.js +0 -197
  465. package/homebridge-ui/public/views/unsupported-detail.js +0 -296
  466. package/media/Snapshot-Unavailable.png +0 -0
  467. package/media/Snapshot-Unavailable.xcf +0 -0
  468. package/media/Snapshot-black.png +0 -0
  469. package/media/camera-disabled.png +0 -0
  470. package/media/camera-offline.png +0 -0
  471. package/scripts/decrypt-diagnostics.mjs +0 -257
@@ -1,389 +0,0 @@
1
- import { createSocket } from 'dgram';
2
- import { pickPort } from 'pick-port';
3
- import { PropertyName } from 'eufy-security-client';
4
- import { FFmpeg, FFmpegParameters } from '../utils/ffmpeg.js';
5
- import { TalkbackStream } from '../utils/Talkback.js';
6
- import { HAP, isRtspReady, applyP2PAudioFormat, ffmpegLoggerFactory } from '../utils/utils.js';
7
- import { LocalLivestreamManager } from './LocalLivestreamManager.js';
8
- import { snapshotDelegate } from './snapshotDelegate.js';
9
- /** Grace period (ms) before the first RTCP keep-alive is expected. */
10
- const STREAM_INITIAL_GRACE_MS = 15_000;
11
- export class StreamingDelegate {
12
- camera;
13
- controller;
14
- log;
15
- ffmpegLog;
16
- localLivestreamManager;
17
- snapshotDelegate;
18
- // keep track of sessions
19
- pendingSessions = new Map();
20
- ongoingSessions = new Map();
21
- get device() {
22
- return this.camera.device;
23
- }
24
- get videoConfig() {
25
- return this.camera.cameraConfig.videoConfig;
26
- }
27
- constructor(camera) {
28
- this.camera = camera;
29
- this.log = camera.log;
30
- this.ffmpegLog = ffmpegLoggerFactory.forCamera(camera.device.getSerial());
31
- this.localLivestreamManager = new LocalLivestreamManager(camera);
32
- this.snapshotDelegate = new snapshotDelegate(this.camera, this.localLivestreamManager);
33
- }
34
- setController(controller) {
35
- this.controller = controller;
36
- }
37
- getLivestreamManager() {
38
- return this.localLivestreamManager;
39
- }
40
- getSnapshotDelegate() {
41
- return this.snapshotDelegate;
42
- }
43
- async handleSnapshotRequest(request, callback) {
44
- this.log.debug(`Snapshot requested: ${request.width}x${request.height}`);
45
- try {
46
- const snapshot = await this.snapshotDelegate.getSnapshotBufferResized(request);
47
- this.log.debug('Snapshot byte length: ' + snapshot?.byteLength);
48
- callback(undefined, snapshot);
49
- }
50
- catch (error) {
51
- this.log.error(error);
52
- callback();
53
- }
54
- }
55
- async prepareStream(request, callback) {
56
- this.log.debug(`stream prepare request with session id ${request.sessionID} was received.`);
57
- const [videoReturnPort, audioReturnPort] = await Promise.all([
58
- pickPort({ type: 'udp' }),
59
- pickPort({ type: 'udp' }),
60
- ]);
61
- const videoSSRC = HAP.CameraController.generateSynchronisationSource();
62
- const audioSSRC = HAP.CameraController.generateSynchronisationSource();
63
- const srtpBuffer = (m) => Buffer.concat([m.srtp_key, m.srtp_salt]);
64
- const sessionInfo = {
65
- address: request.targetAddress,
66
- ipv6: request.addressVersion === 'ipv6',
67
- videoPort: request.video.port,
68
- videoReturnPort,
69
- videoCryptoSuite: request.video.srtpCryptoSuite,
70
- videoSRTP: srtpBuffer(request.video),
71
- videoSSRC,
72
- audioPort: request.audio.port,
73
- audioReturnPort,
74
- audioCryptoSuite: request.audio.srtpCryptoSuite,
75
- audioSRTP: srtpBuffer(request.audio),
76
- audioSSRC,
77
- };
78
- this.pendingSessions.set(request.sessionID, sessionInfo);
79
- const response = {
80
- video: this.buildMediaResponse(videoReturnPort, videoSSRC, request.video),
81
- audio: this.buildMediaResponse(audioReturnPort, audioSSRC, request.audio),
82
- };
83
- callback(undefined, response);
84
- }
85
- buildMediaResponse(returnPort, ssrc, media) {
86
- return {
87
- port: returnPort,
88
- ssrc,
89
- srtp_key: media.srtp_key,
90
- srtp_salt: media.srtp_salt,
91
- };
92
- }
93
- async startStream(request, callback) {
94
- const sessionInfo = this.pendingSessions.get(request.sessionID);
95
- if (!sessionInfo) {
96
- this.log.error('Error finding session information.');
97
- callback(new Error('Error finding session information'));
98
- return;
99
- }
100
- try {
101
- const activeSession = {};
102
- activeSession.socket = this.createKeepAliveSocket(sessionInfo, request, activeSession);
103
- const { videoParams, audioParams } = await this.buildStreamParameters(sessionInfo, request);
104
- const isP2P = await this.configureStreamInput(videoParams, audioParams);
105
- // Record a parallel copy of the video stream to disk for debugging.
106
- // For P2P cameras, the raw recording (DebugRecordingManager) captures
107
- // both video+audio from the P2P feed — the file tee here would only
108
- // duplicate the raw video without audio. For RTSP cameras, this tee
109
- // is the only recording mechanism since DebugRecordingManager is P2P-only.
110
- if (this.camera.platform.config.debugLivestream && !isP2P) {
111
- const recDir = this.camera.platform.eufyPath + '/recordings';
112
- const recPath = videoParams.setFileRecording(recDir, this.device.getSerial());
113
- this.log.debug(`Recording RTSP stream to ${recPath}`);
114
- }
115
- await this.startFFmpegProcesses(activeSession, videoParams, audioParams, request, callback, isP2P);
116
- await this.setupTalkback(activeSession, sessionInfo, request);
117
- this.finalizeSession(request.sessionID, activeSession);
118
- // Opportunistically capture a snapshot from the running livestream
119
- this.captureSnapshotFromLivestream();
120
- }
121
- catch (error) {
122
- this.log.error('Stream could not be started: ' + error);
123
- callback(error);
124
- this.pendingSessions.delete(request.sessionID);
125
- }
126
- }
127
- /**
128
- * Creates a UDP socket that monitors RTCP keep-alive messages.
129
- * If no message is received within 5x the RTCP interval, the stream is considered inactive.
130
- */
131
- createKeepAliveSocket(sessionInfo, request, activeSession) {
132
- const socket = createSocket(sessionInfo.ipv6 ? 'udp6' : 'udp4');
133
- let firstMessageReceived = false;
134
- socket.on('error', (err) => {
135
- this.log.error('Socket error: ' + err.message);
136
- this.stopStream(request.sessionID);
137
- });
138
- socket.on('message', () => {
139
- if (!firstMessageReceived) {
140
- firstMessageReceived = true;
141
- if (activeSession.graceTimeout) {
142
- clearTimeout(activeSession.graceTimeout);
143
- activeSession.graceTimeout = undefined;
144
- }
145
- this.log.debug('First RTCP keep-alive received — stream health monitoring active.');
146
- }
147
- if (activeSession.timeout) {
148
- clearTimeout(activeSession.timeout);
149
- }
150
- activeSession.timeout = setTimeout(() => {
151
- this.log.debug('Device appears to be inactive. Stopping video stream.');
152
- this.controller?.forceStopStreamingSession(request.sessionID);
153
- this.stopStream(request.sessionID);
154
- }, request.video.rtcp_interval * 5 * 1000);
155
- });
156
- // Initial grace period: warn if no RTCP arrives at all
157
- // (helps diagnose "stream starts but shows black screen" issues)
158
- activeSession.graceTimeout = setTimeout(() => {
159
- if (!firstMessageReceived) {
160
- this.log.warn('No RTCP keep-alive received within initial grace period (' +
161
- `${STREAM_INITIAL_GRACE_MS / 1000}s). Stream may not be reaching the Home app.`);
162
- }
163
- }, STREAM_INITIAL_GRACE_MS);
164
- socket.bind(sessionInfo.videoReturnPort);
165
- return socket;
166
- }
167
- /**
168
- * Builds FFmpeg parameters for video and (optionally) audio streams.
169
- */
170
- async buildStreamParameters(sessionInfo, request) {
171
- const videoParams = await FFmpegParameters.forVideo(this.videoConfig.debug);
172
- videoParams.setup(this.camera.cameraConfig, request);
173
- videoParams.setRTPTarget(sessionInfo, request);
174
- const isCodecSupported = request.audio.codec === "OPUS" /* AudioStreamingCodecType.OPUS */ || request.audio.codec === "AAC-eld" /* AudioStreamingCodecType.AAC_ELD */;
175
- if (!isCodecSupported) {
176
- this.log.warn(`An unsupported audio codec (type: ${request.audio.codec}) was requested. Audio streaming will be omitted.`);
177
- }
178
- let audioParams;
179
- if (isCodecSupported && this.camera.cameraConfig.audio !== false) {
180
- audioParams = await FFmpegParameters.forAudio(this.videoConfig.debug);
181
- audioParams.setup(this.camera.cameraConfig, request);
182
- audioParams.setRTPTarget(sessionInfo, request);
183
- }
184
- return { videoParams, audioParams };
185
- }
186
- /**
187
- * Configures the input source (RTSP URL or P2P livestream) for the FFmpeg parameters.
188
- *
189
- * @returns `true` when the stream is a P2P livestream, `false` for RTSP.
190
- */
191
- async configureStreamInput(videoParams, audioParams) {
192
- if (isRtspReady(this.device, this.camera.cameraConfig)) {
193
- const url = this.device.getPropertyValue(PropertyName.DeviceRTSPStreamUrl);
194
- this.log.debug('RTSP URL: ' + url);
195
- videoParams.setInputSource(url);
196
- audioParams?.setInputSource(url);
197
- return false;
198
- }
199
- this.log.debug(`Using P2P local livestream for ${this.device.getName()} ` +
200
- `(serial: ${this.device.getSerial()}, type: ${this.device.getDeviceType()})`);
201
- const streamData = await this.localLivestreamManager.getLocalLiveStream('livestream');
202
- this.log.debug('Livestream obtained successfully. Setting up FFmpeg input streams...');
203
- await videoParams.setInputStream(streamData.videostream);
204
- if (audioParams) {
205
- applyP2PAudioFormat(audioParams, streamData.metadata.audioCodec);
206
- await audioParams.setInputStream(streamData.audiostream);
207
- }
208
- this.log.debug('FFmpeg input streams configured.');
209
- return true;
210
- }
211
- /** Delay before extracting a snapshot from a running livestream (ms). */
212
- static LIVESTREAM_SNAPSHOT_DELAY_MS = 2_000;
213
- /** Grace period for a P2P audio process before it is killed for inactivity (ms). */
214
- static P2P_AUDIO_TIMEOUT_MS = 8_000;
215
- /**
216
- * Starts the video (and optionally separate audio) FFmpeg processes.
217
- *
218
- * For P2P streams the video and audio inputs arrive on separate TCP
219
- * connections. Some camera models advertise an audio codec in their
220
- * stream metadata but never deliver any audio data. When video and
221
- * audio share a single FFmpeg process the stalled audio input blocks
222
- * video output, causing HomeKit to time out the stream.
223
- *
224
- * To prevent that, P2P streams always use separate FFmpeg processes:
225
- * the video process starts immediately and independently of the audio
226
- * process. If the audio process fails to produce output within
227
- * {@link P2P_AUDIO_TIMEOUT_MS} it is killed silently so that resources
228
- * are not wasted on a stalled input.
229
- */
230
- async startFFmpegProcesses(activeSession, videoParams, audioParams, request, callback, isP2P = false) {
231
- const videoProcess = new FFmpeg('[Video Process]', !isP2P && audioParams ? [videoParams, audioParams] : videoParams, this.ffmpegLog);
232
- videoProcess.on('started', () => callback());
233
- videoProcess.on('error', (error) => {
234
- this.log.error('Video process ended with error: ' + error);
235
- this.stopStream(request.sessionID);
236
- });
237
- activeSession.videoProcess = videoProcess;
238
- await videoProcess.start();
239
- if (isP2P && audioParams) {
240
- const audioProcess = new FFmpeg('[Audio Process]', audioParams, this.ffmpegLog);
241
- if (isP2P) {
242
- // For P2P, audio failure must not tear down the video stream.
243
- // Set up a timeout: if FFmpeg never reports progress (i.e. the
244
- // camera is not providing audio data), kill the process early.
245
- let audioStarted = false;
246
- const audioTimeout = setTimeout(() => {
247
- if (!audioStarted) {
248
- this.log.warn(`No audio data received from ${this.device.getName()} — ` + 'killing audio process (video continues).');
249
- audioProcess.stop();
250
- activeSession.audioProcess = undefined;
251
- }
252
- }, StreamingDelegate.P2P_AUDIO_TIMEOUT_MS);
253
- audioProcess.on('started', () => {
254
- audioStarted = true;
255
- clearTimeout(audioTimeout);
256
- });
257
- audioProcess.on('error', (error) => {
258
- clearTimeout(audioTimeout);
259
- if (audioStarted) {
260
- // Audio was working but failed mid-stream — log but keep video.
261
- this.log.warn('P2P audio process ended unexpectedly: ' + error);
262
- }
263
- activeSession.audioProcess = undefined;
264
- });
265
- }
266
- else {
267
- audioProcess.on('error', (error) => {
268
- this.log.error('Audio process ended with error: ' + error);
269
- this.stopStream(request.sessionID);
270
- });
271
- }
272
- activeSession.audioProcess = audioProcess;
273
- await audioProcess.start();
274
- }
275
- }
276
- /**
277
- * Sets up talkback (return audio) if enabled in the camera config.
278
- *
279
- * The pipeline: HomeKit SRTP → FFmpeg (decode & re-encode to AAC ADTS)
280
- * → TalkbackStream → eufy P2P talkback channel.
281
- */
282
- async setupTalkback(activeSession, sessionInfo, request) {
283
- if (!this.camera.cameraConfig.talkback) {
284
- return;
285
- }
286
- const talkbackParams = await FFmpegParameters.forAudio(this.videoConfig.debug);
287
- await talkbackParams.setTalkbackInput(sessionInfo, request);
288
- if (this.camera.cameraConfig.talkbackChannels) {
289
- talkbackParams.setTalkbackChannels(this.camera.cameraConfig.talkbackChannels);
290
- }
291
- activeSession.talkbackStream = new TalkbackStream(this.camera.platform, this.device, this.log);
292
- activeSession.returnProcess = new FFmpeg('[Talkback Process]', talkbackParams, this.ffmpegLog);
293
- activeSession.returnProcess.on('error', (error) => {
294
- this.log.error('Talkback process ended with error: ' + error);
295
- });
296
- await activeSession.returnProcess.start();
297
- activeSession.returnProcess.stdout?.pipe(activeSession.talkbackStream);
298
- }
299
- /**
300
- * Transfers session from pending to ongoing, or stops it immediately if it was cancelled.
301
- */
302
- finalizeSession(sessionId, activeSession) {
303
- const pendingSession = this.pendingSessions.get(sessionId);
304
- this.ongoingSessions.set(sessionId, activeSession);
305
- if (pendingSession) {
306
- this.pendingSessions.delete(sessionId);
307
- }
308
- else {
309
- this.log.info('Session was cancelled before start completed. Stopping immediately.');
310
- this.stopStream(sessionId);
311
- }
312
- }
313
- /**
314
- * Captures a snapshot from the currently running livestream after a brief
315
- * delay to allow the stream to produce stable frames.
316
- */
317
- captureSnapshotFromLivestream() {
318
- setTimeout(() => {
319
- this.snapshotDelegate.captureSnapshotFromActiveLivestream().catch((error) => {
320
- this.log.debug('Snapshot capture from livestream failed: ' + error);
321
- });
322
- }, StreamingDelegate.LIVESTREAM_SNAPSHOT_DELAY_MS);
323
- }
324
- handleStreamRequest(request, callback) {
325
- switch (request.type) {
326
- case "start" /* StreamRequestTypes.START */:
327
- this.log.debug(`Received request to start stream with id ${request.sessionID}`, request);
328
- this.startStream(request, callback);
329
- break;
330
- case "reconfigure" /* StreamRequestTypes.RECONFIGURE */:
331
- this.log.debug(`Reconfigure request: ${request.video.width}x${request.video.height}, ` +
332
- `${request.video.fps} fps, ${request.video.max_bit_rate} kbps (Ignored)`);
333
- callback();
334
- break;
335
- case "stop" /* StreamRequestTypes.STOP */:
336
- this.log.debug('Receive Apple HK Stop request', request);
337
- this.stopStream(request.sessionID);
338
- callback();
339
- break;
340
- }
341
- }
342
- stopStream(sessionId) {
343
- this.log.debug('Stopping session with id: ' + sessionId);
344
- this.pendingSessions.delete(sessionId);
345
- const session = this.ongoingSessions.get(sessionId);
346
- if (!session) {
347
- this.log.debug('No session to stop.');
348
- return;
349
- }
350
- if (session.timeout) {
351
- clearTimeout(session.timeout);
352
- }
353
- if (session.graceTimeout) {
354
- clearTimeout(session.graceTimeout);
355
- }
356
- const cleanupSteps = [
357
- [
358
- 'returnAudio FFmpeg process',
359
- () => {
360
- session.talkbackStream?.stopTalkbackStream();
361
- session.returnProcess?.stdout?.unpipe();
362
- session.returnProcess?.stop();
363
- },
364
- ],
365
- ['video FFmpeg process', () => session.videoProcess?.stop()],
366
- ['audio FFmpeg process', () => session.audioProcess?.stop()],
367
- ['socket', () => session.socket?.close()],
368
- [
369
- 'Eufy Station livestream',
370
- () => {
371
- if (!isRtspReady(this.device, this.camera.cameraConfig)) {
372
- this.localLivestreamManager.stopLocalLiveStream();
373
- }
374
- },
375
- ],
376
- ];
377
- for (const [label, cleanup] of cleanupSteps) {
378
- try {
379
- cleanup();
380
- }
381
- catch (error) {
382
- this.log.error(`Error occurred terminating ${label}: ${error}`);
383
- }
384
- }
385
- this.ongoingSessions.delete(sessionId);
386
- this.log.info('Stopped video stream.');
387
- }
388
- }
389
- //# sourceMappingURL=streamingDelegate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"streamingDelegate.js","sourceRoot":"","sources":["../../src/controller/streamingDelegate.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=interfaces.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":""}
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,162 +0,0 @@
1
- import { Writable } from 'stream';
2
- /** Maximum bytes to buffer while waiting for the P2P talkback channel to open. */
3
- const STARTUP_BUFFER_MAX = 4096;
4
- /** Default idle timeout (ms) before talkback is stopped after the last audio data. */
5
- const DEFAULT_IDLE_TIMEOUT_MS = 5_000;
6
- /**
7
- * Manages the return-audio (talkback) pipeline for a single camera session.
8
- *
9
- * Audio data written to this stream is forwarded to the eufy P2P talkback
10
- * channel. While the channel is opening, data is buffered (up to
11
- * {@link STARTUP_BUFFER_MAX} bytes) so early frames are not lost.
12
- */
13
- export class TalkbackStream extends Writable {
14
- eufyClient;
15
- log;
16
- cameraSN;
17
- idleTimeoutMs;
18
- startupBuffer = [];
19
- startupBufferSize = 0;
20
- talkbackStarted = false;
21
- talkbackRequested = false;
22
- targetStream;
23
- idleTimeout;
24
- constructor(platform, camera, log, idleTimeoutMs) {
25
- super();
26
- this.eufyClient = platform.eufyClient;
27
- this.cameraSN = camera.getSerial();
28
- this.log = log;
29
- this.idleTimeoutMs = idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
30
- this.eufyClient.on('station talkback start', this.onTalkbackStarted);
31
- this.eufyClient.on('station talkback stop', this.onTalkbackStopped);
32
- }
33
- // --- Event handlers (arrow functions to preserve `this` context) ---
34
- onTargetStreamError = (err) => {
35
- this.log.warn('Talkback target stream error: ' + err);
36
- };
37
- onTalkbackStarted = (station, device, stream) => {
38
- if (device.getSerial() !== this.cameraSN) {
39
- return;
40
- }
41
- this.log.debug('Talkback started via station ' + station.getName());
42
- this.talkbackStarted = true;
43
- if (this.targetStream) {
44
- this.targetStream.removeListener('error', this.onTargetStreamError);
45
- }
46
- this.targetStream = stream;
47
- this.targetStream.on('error', this.onTargetStreamError);
48
- this.drainStartupBuffer();
49
- };
50
- onTalkbackStopped = (_station, device) => {
51
- if (device.getSerial() !== this.cameraSN) {
52
- return;
53
- }
54
- this.log.debug('Talkback stopped.');
55
- this.talkbackStarted = false;
56
- this.talkbackRequested = false;
57
- this.targetStream = undefined;
58
- };
59
- // --- Writable implementation ---
60
- _write(chunk, _encoding, callback) {
61
- this.resetIdleTimeout();
62
- if (this.targetStream) {
63
- // Channel is open — write directly
64
- this.targetStream.write(chunk, callback);
65
- }
66
- else {
67
- // Channel not yet open — buffer and request talkback
68
- this.bufferChunk(chunk);
69
- this.requestTalkback();
70
- callback();
71
- }
72
- }
73
- _final(callback) {
74
- this.stopTalkback();
75
- callback();
76
- }
77
- _destroy(_error, callback) {
78
- this.cleanup();
79
- callback();
80
- }
81
- // --- Public API ---
82
- /** Gracefully stop the talkback session and clean up all resources. */
83
- stopTalkbackStream() {
84
- this.cleanup();
85
- this.destroy();
86
- }
87
- // --- Internal helpers ---
88
- requestTalkback() {
89
- if (this.talkbackRequested) {
90
- return;
91
- }
92
- this.talkbackRequested = true;
93
- this.log.debug('Requesting talkback start...');
94
- this.eufyClient.startStationTalkback(this.cameraSN).catch((error) => {
95
- this.log.error('Talkback could not be started: ' + error);
96
- this.talkbackRequested = false;
97
- });
98
- }
99
- stopTalkback() {
100
- if (this.idleTimeout) {
101
- clearTimeout(this.idleTimeout);
102
- this.idleTimeout = undefined;
103
- }
104
- if (this.talkbackStarted || this.talkbackRequested) {
105
- this.log.debug('Stopping talkback.');
106
- this.talkbackStarted = false;
107
- this.talkbackRequested = false;
108
- this.eufyClient.stopStationTalkback(this.cameraSN).catch((error) => {
109
- this.log.error('Talkback could not be stopped: ' + error);
110
- });
111
- }
112
- }
113
- bufferChunk(chunk) {
114
- if (chunk.length >= STARTUP_BUFFER_MAX) {
115
- // Single chunk exceeds buffer — keep only this chunk
116
- this.clearStartupBuffer();
117
- this.startupBuffer.push(chunk);
118
- this.startupBufferSize = chunk.length;
119
- return;
120
- }
121
- while (this.startupBuffer.length > 0 && this.startupBufferSize + chunk.length > STARTUP_BUFFER_MAX) {
122
- const dropped = this.startupBuffer.shift();
123
- this.startupBufferSize -= dropped.length;
124
- }
125
- this.startupBuffer.push(chunk);
126
- this.startupBufferSize += chunk.length;
127
- }
128
- drainStartupBuffer() {
129
- if (!this.targetStream || this.startupBuffer.length === 0) {
130
- return;
131
- }
132
- this.log.debug(`Draining ${this.startupBufferSize} bytes of buffered audio.`);
133
- for (const chunk of this.startupBuffer) {
134
- this.targetStream.write(chunk);
135
- }
136
- this.clearStartupBuffer();
137
- }
138
- clearStartupBuffer() {
139
- this.startupBuffer = [];
140
- this.startupBufferSize = 0;
141
- }
142
- resetIdleTimeout() {
143
- if (this.idleTimeout) {
144
- clearTimeout(this.idleTimeout);
145
- }
146
- this.idleTimeout = setTimeout(() => {
147
- this.log.debug('Talkback idle timeout — stopping.');
148
- this.stopTalkback();
149
- }, this.idleTimeoutMs);
150
- }
151
- cleanup() {
152
- this.eufyClient.removeListener('station talkback start', this.onTalkbackStarted);
153
- this.eufyClient.removeListener('station talkback stop', this.onTalkbackStopped);
154
- this.stopTalkback();
155
- this.clearStartupBuffer();
156
- if (this.targetStream) {
157
- this.targetStream.removeListener('error', this.onTargetStreamError);
158
- this.targetStream = undefined;
159
- }
160
- }
161
- }
162
- //# sourceMappingURL=Talkback.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Talkback.js","sourceRoot":"","sources":["../../src/utils/Talkback.ts"],"names":[],"mappings":"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"}