@homebridge-plugins/homebridge-eufy-security 5.0.0-beta.4 → 5.0.0-beta.40

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 (121) hide show
  1. package/CONTRIBUTING.md +9 -17
  2. package/config.schema.json +60 -0
  3. package/dist/account/ownership.js +16 -16
  4. package/dist/account/ownership.js.map +1 -1
  5. package/dist/account/persistence.js +24 -74
  6. package/dist/account/persistence.js.map +1 -1
  7. package/dist/account/temporary-authentication.js +5 -3
  8. package/dist/account/temporary-authentication.js.map +1 -1
  9. package/dist/configuration.js +50 -13
  10. package/dist/configuration.js.map +1 -1
  11. package/dist/device/member-evidence.js +11 -4
  12. package/dist/device/member-evidence.js.map +1 -1
  13. package/dist/device/member-trust.js +14 -32
  14. package/dist/device/member-trust.js.map +1 -1
  15. package/dist/device/snapshot.js +6 -18
  16. package/dist/device/snapshot.js.map +1 -1
  17. package/dist/diagnostics.js +951 -334
  18. package/dist/diagnostics.js.map +1 -1
  19. package/dist/homekit/adapter.js +4 -1
  20. package/dist/homekit/adapter.js.map +1 -1
  21. package/dist/homekit/adapters/battery.js +3 -3
  22. package/dist/homekit/adapters/battery.js.map +1 -1
  23. package/dist/homekit/adapters/camera-controls.js +15 -37
  24. package/dist/homekit/adapters/camera-controls.js.map +1 -1
  25. package/dist/homekit/adapters/camera-streaming.js +74 -48
  26. package/dist/homekit/adapters/camera-streaming.js.map +1 -1
  27. package/dist/homekit/adapters/contact.js +5 -5
  28. package/dist/homekit/adapters/contact.js.map +1 -1
  29. package/dist/homekit/adapters/doorbell.js +3 -15
  30. package/dist/homekit/adapters/doorbell.js.map +1 -1
  31. package/dist/homekit/adapters/lock.js +72 -221
  32. package/dist/homekit/adapters/lock.js.map +1 -1
  33. package/dist/homekit/adapters/motion.js +3 -3
  34. package/dist/homekit/adapters/motion.js.map +1 -1
  35. package/dist/homekit/adapters/package-sensor.js +63 -0
  36. package/dist/homekit/adapters/package-sensor.js.map +1 -0
  37. package/dist/homekit/adapters/registry.js +2 -0
  38. package/dist/homekit/adapters/registry.js.map +1 -1
  39. package/dist/homekit/adapters/security-system.js +106 -250
  40. package/dist/homekit/adapters/security-system.js.map +1 -1
  41. package/dist/homekit/adapters/siren.js +5 -33
  42. package/dist/homekit/adapters/siren.js.map +1 -1
  43. package/dist/homekit/adapters/smart-light.js +19 -217
  44. package/dist/homekit/adapters/smart-light.js.map +1 -1
  45. package/dist/homekit/coverage-matrix.js +8 -67
  46. package/dist/homekit/coverage-matrix.js.map +1 -1
  47. package/dist/homekit/device-control.js +249 -13
  48. package/dist/homekit/device-control.js.map +1 -1
  49. package/dist/homekit/reconciler.js +25 -9
  50. package/dist/homekit/reconciler.js.map +1 -1
  51. package/dist/media/last-successful-image.js +8 -23
  52. package/dist/media/last-successful-image.js.map +1 -1
  53. package/dist/media/live-preview.js +217 -0
  54. package/dist/media/live-preview.js.map +1 -0
  55. package/dist/media/live-stream.js +689 -160
  56. package/dist/media/live-stream.js.map +1 -1
  57. package/dist/media/recording.js +41 -118
  58. package/dist/media/recording.js.map +1 -1
  59. package/dist/media/snapshot.js +22 -17
  60. package/dist/media/snapshot.js.map +1 -1
  61. package/dist/media/station-live-sessions.js +40 -51
  62. package/dist/media/station-live-sessions.js.map +1 -1
  63. package/dist/platform.js +61 -10
  64. package/dist/platform.js.map +1 -1
  65. package/dist/runtime/channel.js +227 -40
  66. package/dist/runtime/channel.js.map +1 -1
  67. package/dist/runtime/device-settings.js +88 -0
  68. package/dist/runtime/device-settings.js.map +1 -0
  69. package/dist/runtime/owner.js +30 -5
  70. package/dist/runtime/owner.js.map +1 -1
  71. package/dist/runtime/sdk-client.js +21 -17
  72. package/dist/runtime/sdk-client.js.map +1 -1
  73. package/dist/runtime/tracker.js +8 -38
  74. package/dist/runtime/tracker.js.map +1 -1
  75. package/dist/storage.js +1 -1
  76. package/dist/storage.js.map +1 -1
  77. package/dist/ui/dashboard.js +36 -16
  78. package/dist/ui/dashboard.js.map +1 -1
  79. package/dist/ui/runtime-channel-client.js +155 -184
  80. package/dist/ui/runtime-channel-client.js.map +1 -1
  81. package/dist/ui/server.js +81 -38
  82. package/dist/ui/server.js.map +1 -1
  83. package/homebridge-ui/public/app.css +531 -239
  84. package/homebridge-ui/public/assets/icons/auto_fix_high.svg +1 -0
  85. package/homebridge-ui/public/assets/icons/battery_0.svg +1 -0
  86. package/homebridge-ui/public/assets/icons/battery_1.svg +1 -0
  87. package/homebridge-ui/public/assets/icons/battery_2.svg +1 -0
  88. package/homebridge-ui/public/assets/icons/battery_3.svg +1 -0
  89. package/homebridge-ui/public/assets/icons/battery_4.svg +1 -0
  90. package/homebridge-ui/public/assets/icons/battery_5.svg +1 -0
  91. package/homebridge-ui/public/assets/icons/battery_6.svg +1 -0
  92. package/homebridge-ui/public/assets/icons/battery_full.svg +1 -0
  93. package/homebridge-ui/public/assets/icons/contact_support.svg +1 -0
  94. package/homebridge-ui/public/assets/icons/delete.svg +1 -0
  95. package/homebridge-ui/public/assets/icons/download.svg +1 -0
  96. package/homebridge-ui/public/assets/icons/extension_off.svg +1 -0
  97. package/homebridge-ui/public/assets/icons/info.svg +1 -0
  98. package/homebridge-ui/public/assets/icons/key_off.svg +1 -0
  99. package/homebridge-ui/public/assets/icons/keyboard_arrow_left.svg +1 -0
  100. package/homebridge-ui/public/assets/icons/keyboard_arrow_right.svg +1 -0
  101. package/homebridge-ui/public/assets/icons/keyboard_double_arrow_left.svg +1 -0
  102. package/homebridge-ui/public/assets/icons/keyboard_double_arrow_right.svg +1 -0
  103. package/homebridge-ui/public/assets/icons/movie_off.svg +1 -0
  104. package/homebridge-ui/public/assets/icons/play_arrow.svg +1 -0
  105. package/homebridge-ui/public/assets/icons/refresh.svg +1 -0
  106. package/homebridge-ui/public/assets/icons/satellite_alt.svg +1 -0
  107. package/homebridge-ui/public/assets/icons/search_off.svg +1 -0
  108. package/homebridge-ui/public/assets/icons/sensors_off.svg +1 -0
  109. package/homebridge-ui/public/assets/icons/settings_photo_camera.svg +1 -0
  110. package/homebridge-ui/public/assets/icons/solar_power.svg +1 -0
  111. package/homebridge-ui/public/assets/icons/stop.svg +1 -0
  112. package/homebridge-ui/public/assets/icons/videocam_off.svg +1 -0
  113. package/homebridge-ui/public/i18n/en.json +160 -82
  114. package/homebridge-ui/public/i18n/fr.json +161 -83
  115. package/homebridge-ui/public/index.html +225 -96
  116. package/homebridge-ui/public/js/app.js +814 -435
  117. package/homebridge-ui/public/js/dashboard.js +148 -31
  118. package/i18n/runtime/en.json +10 -3
  119. package/package.json +10 -11
  120. package/homebridge-ui/public/js/legacy-settings.js +0 -37
  121. package/homebridge-ui/public/js/profile-wizard.js +0 -61
@@ -0,0 +1,217 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { adaptationReporter, AdaptationStderr, commonArguments, stopProcess, } from './live-stream.js';
3
+ /** How long one preview runs before it ends on its own, so a page left open does not hold a camera. */
4
+ const LIVE_PREVIEW_MAX_MS = 3 * 60_000;
5
+ /** How long coded video may flow without decoding to a picture before the HomeKit side ends as unplayable. */
6
+ export const LIVE_PREVIEW_PICTURE_MS = 10_000;
7
+ /** The most bytes one picture may reach before FFmpeg's output is taken as no longer pictures. */
8
+ const MAX_PICTURE_BYTES = 1024 * 1024;
9
+ const JPEG_END = Buffer.from([0xff, 0xd9]);
10
+ /** The JPEG output both preview sides are decoded into: five pictures a second, 640 pixels wide, on stdout. */
11
+ const STILLS = ['-an', '-vf', 'fps=5,scale=640:-2', '-q:v', '8', '-f', 'image2pipe', '-c:v', 'mjpeg', 'pipe:1'];
12
+ /** What an iPhone asks a camera for, on Wi-Fi and on cellular: High 4.0 at 30 fps over a 1378-byte MTU. */
13
+ const IPHONE = { fps: 30, profile: 'high', level: '4.0', payloadType: 99, ssrc: 1, mtu: 1378, rtcpInterval: 0.5 };
14
+ const IPHONE_ASKS = {
15
+ wifi: { ...IPHONE, width: 1280, height: 720, maxBitRate: 299 },
16
+ cellular: { ...IPHONE, width: 640, height: 360, maxBitRate: 132 },
17
+ };
18
+ /**
19
+ * A camera's live video as JPEG pictures for the settings page, five a second and 640 pixels wide, on two sides:
20
+ * `raw` decoded straight from the camera, and `homekit` coded as a live session configured with `adaptation`
21
+ * codes it for that iPhone ask, and decoded again.
22
+ *
23
+ * Each picture carries its side, the encoder of the HomeKit side and, once that has written for a second, the
24
+ * kilobits a second it wrote.
25
+ *
26
+ * The SDK source is fanned out to two FFmpegs: one decodes it into the `raw` pictures, one runs the session's own
27
+ * encoder and argument list and writes the coded H.264 elementary stream, which a third decodes into the
28
+ * `homekit` pictures. The camera side starts at the first keyframe, and each HomeKit run at a keyframe too. No
29
+ * audio. A write either refuses holds the SDK source until it drains, so the SDK's keyframe-aware queue is the
30
+ * only one, and the HomeKit decoder holds the encoder the same way.
31
+ *
32
+ * `adapt` ends the HomeKit run and starts the next with other settings at the next keyframe, leaving the source
33
+ * and the camera side running. A HomeKit run that fails, or yields no picture within
34
+ * {@link LIVE_PREVIEW_PICTURE_MS}, ends alone with an empty `homekit` picture while the camera side showed, and
35
+ * no other starts until `adapt`. `onRun` is called once with each run's result, and with one result where none
36
+ * started. A codec change, a source or camera side failure, the time limit and `stop` end the whole preview, and
37
+ * `onEnd` is called exactly once, saying whether the last run was unplayable. `diagnostics` receives each
38
+ * process's `started` and `output` notices as a live session's do, under the `preview-raw`, `preview-encode` and
39
+ * `preview-decode` roles.
40
+ */
41
+ export function startLivePreview(executable, media, source, adaptation, onPicture, onRun, onEnd, diagnostics) {
42
+ const report = adaptationReporter(diagnostics);
43
+ const abandonment = new AbortController();
44
+ let live;
45
+ let raw;
46
+ let rawPictures = 0;
47
+ let codec;
48
+ let homekit;
49
+ let latest;
50
+ let wanted = true;
51
+ let last;
52
+ let ended = false;
53
+ const finish = (stopped) => {
54
+ const run = homekit;
55
+ homekit = undefined;
56
+ clearTimeout(run?.pictureless);
57
+ run?.processes.forEach(stopProcess);
58
+ const { profile, level, width, height, fps, maxBitRate } = IPHONE_ASKS[adaptation.ask];
59
+ last = {
60
+ outcome: run?.pictures ? 'picture' : stopped ? 'stopped' : rawPictures ? 'unplayable' : 'no-video',
61
+ selection: { profile, level, width, height, fps, maxBitRate },
62
+ ...adaptation,
63
+ ...(run ? { encoder: run.coding.encoder } : {}),
64
+ ...(codec ? { source: codec } : {}),
65
+ ...(run?.coding.kbps === undefined ? {} : { kbps: run.coding.kbps }),
66
+ };
67
+ onRun(last);
68
+ };
69
+ const end = (stopped = false) => {
70
+ if (ended)
71
+ return;
72
+ ended = true;
73
+ clearTimeout(deadline);
74
+ abandonment.abort();
75
+ try {
76
+ live?.stop();
77
+ }
78
+ catch {
79
+ live = undefined;
80
+ }
81
+ if (homekit || !last)
82
+ finish(stopped);
83
+ if (raw)
84
+ stopProcess(raw);
85
+ onEnd(last?.outcome === 'unplayable');
86
+ };
87
+ const fail = () => {
88
+ if (!rawPictures)
89
+ return end();
90
+ const encoder = homekit.coding.encoder;
91
+ finish(false);
92
+ onPicture(Buffer.alloc(0), { side: 'homekit', encoder });
93
+ };
94
+ const deadline = setTimeout(() => end(), LIVE_PREVIEW_MAX_MS);
95
+ deadline.unref();
96
+ const spawnRole = (role, args) => {
97
+ const process = spawn(executable, args, { stdio: ['pipe', 'pipe', 'pipe'] });
98
+ const stderr = new AdaptationStderr();
99
+ const lost = () => {
100
+ if (process === raw)
101
+ end();
102
+ else if (homekit?.processes.includes(process))
103
+ fail();
104
+ };
105
+ process.stderr.on('data', (chunk) => stderr.observe(chunk));
106
+ process.once('error', lost);
107
+ process.once('exit', (code, signal) => {
108
+ report(role, 'output', stderr, code, signal);
109
+ lost();
110
+ });
111
+ process.stdin.on('error', lost);
112
+ return process;
113
+ };
114
+ const stills = (output, side, run) => {
115
+ let pending = Buffer.alloc(0);
116
+ output.on('data', (chunk) => {
117
+ pending = Buffer.concat([pending, chunk]);
118
+ for (let at = pending.indexOf(JPEG_END); at !== -1; at = pending.indexOf(JPEG_END)) {
119
+ if (run && run !== homekit)
120
+ return;
121
+ if (run) {
122
+ clearTimeout(run.pictureless);
123
+ run.pictures += 1;
124
+ }
125
+ else
126
+ rawPictures += 1;
127
+ onPicture(pending.subarray(0, at + JPEG_END.length), { side, ...(run ?? latest).coding });
128
+ pending = pending.subarray(at + JPEG_END.length);
129
+ }
130
+ if (pending.length > MAX_PICTURE_BYTES)
131
+ end();
132
+ });
133
+ };
134
+ const startHomeKit = (input) => {
135
+ const ask = IPHONE_ASKS[adaptation.ask];
136
+ const { encoder, args } = media.videoAdaptation(input, ask, ['-f', 'h264', 'pipe:1'], adaptation);
137
+ const cause = last ? 'controller-selection' : 'first';
138
+ diagnostics?.report({ role: 'preview-encode', event: 'started', cause, encoder, source: input });
139
+ const encoding = spawnRole('preview-encode', args);
140
+ diagnostics?.report({ role: 'preview-decode', event: 'started', cause, source: 'h264' });
141
+ const decoding = spawnRole('preview-decode', [...commonArguments('h264'), ...STILLS]);
142
+ const run = { processes: [encoding, decoding], coding: { encoder }, pictures: 0 };
143
+ let firstCodedAt;
144
+ let countedBytes = 0;
145
+ encoding.stdout.on('data', (chunk) => {
146
+ const now = Date.now();
147
+ if (firstCodedAt === undefined) {
148
+ firstCodedAt = now;
149
+ run.pictureless = setTimeout(() => run === homekit && fail(), LIVE_PREVIEW_PICTURE_MS);
150
+ run.pictureless.unref();
151
+ return;
152
+ }
153
+ countedBytes += chunk.length;
154
+ if (now - firstCodedAt >= 1_000)
155
+ run.coding.kbps = Math.round((countedBytes * 8) / (now - firstCodedAt));
156
+ });
157
+ encoding.stdout.pipe(decoding.stdin);
158
+ stills(decoding.stdout, 'homekit', run);
159
+ return (latest = run);
160
+ };
161
+ source.live({ signal: abandonment.signal }).then((consumer) => {
162
+ if (ended) {
163
+ consumer.stop();
164
+ return;
165
+ }
166
+ live = consumer;
167
+ consumer.on('error', () => end());
168
+ consumer.on('stop', () => end());
169
+ consumer.on('budget', (notice) => notice.extend());
170
+ let held = 0;
171
+ const feed = (stdin, data) => {
172
+ if (stdin.write(data))
173
+ return;
174
+ held += 1;
175
+ consumer.pause();
176
+ const release = () => {
177
+ stdin.off('drain', release).off('close', release);
178
+ if (--held === 0)
179
+ consumer.resume();
180
+ };
181
+ stdin.on('drain', release).on('close', release);
182
+ };
183
+ consumer.on('video', (frame) => {
184
+ if (ended)
185
+ return;
186
+ if (!raw) {
187
+ if (!frame.keyframe)
188
+ return;
189
+ codec = frame.codec;
190
+ diagnostics?.report({ role: 'preview-raw', event: 'started', cause: 'first', source: codec });
191
+ raw = spawnRole('preview-raw', [...commonArguments(codec === 'h265' ? 'hevc' : codec), ...STILLS]);
192
+ stills(raw.stdout, 'raw');
193
+ }
194
+ if (frame.codec !== codec)
195
+ return end();
196
+ if (wanted && frame.keyframe) {
197
+ wanted = false;
198
+ homekit = startHomeKit(codec);
199
+ }
200
+ feed(raw.stdin, frame.data);
201
+ if (homekit)
202
+ feed(homekit.processes[0].stdin, frame.data);
203
+ });
204
+ }, () => end());
205
+ return {
206
+ stop: () => end(true),
207
+ adapt: (next) => {
208
+ if (ended)
209
+ return;
210
+ if (homekit)
211
+ finish(true);
212
+ adaptation = next;
213
+ wanted = true;
214
+ },
215
+ };
216
+ }
217
+ //# sourceMappingURL=live-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-preview.js","sourceRoot":"","sources":["../../src/media/live-preview.ts"],"names":[],"mappings":"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"}