@homebridge-plugins/homebridge-eufy-security 5.0.0-beta.4 → 5.0.0-beta.41
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.
- package/CONTRIBUTING.md +9 -17
- package/config.schema.json +60 -0
- package/dist/account/ownership.js +16 -16
- package/dist/account/ownership.js.map +1 -1
- package/dist/account/persistence.js +24 -74
- package/dist/account/persistence.js.map +1 -1
- package/dist/account/temporary-authentication.js +5 -3
- package/dist/account/temporary-authentication.js.map +1 -1
- package/dist/configuration.js +50 -13
- package/dist/configuration.js.map +1 -1
- package/dist/device/member-evidence.js +11 -4
- package/dist/device/member-evidence.js.map +1 -1
- package/dist/device/member-trust.js +14 -32
- package/dist/device/member-trust.js.map +1 -1
- package/dist/device/snapshot.js +6 -18
- package/dist/device/snapshot.js.map +1 -1
- package/dist/diagnostics.js +966 -337
- package/dist/diagnostics.js.map +1 -1
- package/dist/homekit/adapter.js +4 -1
- package/dist/homekit/adapter.js.map +1 -1
- package/dist/homekit/adapters/battery.js +3 -3
- package/dist/homekit/adapters/battery.js.map +1 -1
- package/dist/homekit/adapters/camera-controls.js +15 -37
- package/dist/homekit/adapters/camera-controls.js.map +1 -1
- package/dist/homekit/adapters/camera-streaming.js +74 -48
- package/dist/homekit/adapters/camera-streaming.js.map +1 -1
- package/dist/homekit/adapters/contact.js +5 -5
- package/dist/homekit/adapters/contact.js.map +1 -1
- package/dist/homekit/adapters/doorbell.js +3 -15
- package/dist/homekit/adapters/doorbell.js.map +1 -1
- package/dist/homekit/adapters/lock.js +72 -221
- package/dist/homekit/adapters/lock.js.map +1 -1
- package/dist/homekit/adapters/motion.js +3 -3
- package/dist/homekit/adapters/motion.js.map +1 -1
- package/dist/homekit/adapters/package-sensor.js +63 -0
- package/dist/homekit/adapters/package-sensor.js.map +1 -0
- package/dist/homekit/adapters/registry.js +2 -0
- package/dist/homekit/adapters/registry.js.map +1 -1
- package/dist/homekit/adapters/security-system.js +106 -250
- package/dist/homekit/adapters/security-system.js.map +1 -1
- package/dist/homekit/adapters/siren.js +5 -33
- package/dist/homekit/adapters/siren.js.map +1 -1
- package/dist/homekit/adapters/smart-light.js +19 -217
- package/dist/homekit/adapters/smart-light.js.map +1 -1
- package/dist/homekit/coverage-matrix.js +8 -67
- package/dist/homekit/coverage-matrix.js.map +1 -1
- package/dist/homekit/device-control.js +249 -13
- package/dist/homekit/device-control.js.map +1 -1
- package/dist/homekit/reconciler.js +25 -9
- package/dist/homekit/reconciler.js.map +1 -1
- package/dist/media/last-successful-image.js +8 -23
- package/dist/media/last-successful-image.js.map +1 -1
- package/dist/media/live-preview.js +217 -0
- package/dist/media/live-preview.js.map +1 -0
- package/dist/media/live-stream.js +689 -160
- package/dist/media/live-stream.js.map +1 -1
- package/dist/media/recording.js +41 -118
- package/dist/media/recording.js.map +1 -1
- package/dist/media/snapshot.js +22 -17
- package/dist/media/snapshot.js.map +1 -1
- package/dist/media/station-live-sessions.js +40 -51
- package/dist/media/station-live-sessions.js.map +1 -1
- package/dist/platform.js +61 -10
- package/dist/platform.js.map +1 -1
- package/dist/runtime/channel.js +227 -40
- package/dist/runtime/channel.js.map +1 -1
- package/dist/runtime/device-settings.js +88 -0
- package/dist/runtime/device-settings.js.map +1 -0
- package/dist/runtime/owner.js +30 -5
- package/dist/runtime/owner.js.map +1 -1
- package/dist/runtime/sdk-client.js +21 -17
- package/dist/runtime/sdk-client.js.map +1 -1
- package/dist/runtime/tracker.js +8 -38
- package/dist/runtime/tracker.js.map +1 -1
- package/dist/storage.js +1 -1
- package/dist/storage.js.map +1 -1
- package/dist/ui/dashboard.js +36 -16
- package/dist/ui/dashboard.js.map +1 -1
- package/dist/ui/runtime-channel-client.js +155 -184
- package/dist/ui/runtime-channel-client.js.map +1 -1
- package/dist/ui/server.js +94 -41
- package/dist/ui/server.js.map +1 -1
- package/homebridge-ui/public/app.css +531 -239
- package/homebridge-ui/public/assets/icons/auto_fix_high.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_0.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_1.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_2.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_3.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_4.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_5.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_6.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_full.svg +1 -0
- package/homebridge-ui/public/assets/icons/contact_support.svg +1 -0
- package/homebridge-ui/public/assets/icons/delete.svg +1 -0
- package/homebridge-ui/public/assets/icons/download.svg +1 -0
- package/homebridge-ui/public/assets/icons/extension_off.svg +1 -0
- package/homebridge-ui/public/assets/icons/info.svg +1 -0
- package/homebridge-ui/public/assets/icons/key_off.svg +1 -0
- package/homebridge-ui/public/assets/icons/keyboard_arrow_left.svg +1 -0
- package/homebridge-ui/public/assets/icons/keyboard_arrow_right.svg +1 -0
- package/homebridge-ui/public/assets/icons/keyboard_double_arrow_left.svg +1 -0
- package/homebridge-ui/public/assets/icons/keyboard_double_arrow_right.svg +1 -0
- package/homebridge-ui/public/assets/icons/movie_off.svg +1 -0
- package/homebridge-ui/public/assets/icons/play_arrow.svg +1 -0
- package/homebridge-ui/public/assets/icons/refresh.svg +1 -0
- package/homebridge-ui/public/assets/icons/satellite_alt.svg +1 -0
- package/homebridge-ui/public/assets/icons/search_off.svg +1 -0
- package/homebridge-ui/public/assets/icons/sensors_off.svg +1 -0
- package/homebridge-ui/public/assets/icons/settings_photo_camera.svg +1 -0
- package/homebridge-ui/public/assets/icons/solar_power.svg +1 -0
- package/homebridge-ui/public/assets/icons/stop.svg +1 -0
- package/homebridge-ui/public/assets/icons/videocam_off.svg +1 -0
- package/homebridge-ui/public/i18n/en.json +161 -82
- package/homebridge-ui/public/i18n/fr.json +162 -83
- package/homebridge-ui/public/index.html +224 -96
- package/homebridge-ui/public/js/app.js +821 -435
- package/homebridge-ui/public/js/dashboard.js +148 -31
- package/i18n/runtime/en.json +10 -3
- package/package.json +10 -11
- package/homebridge-ui/public/js/legacy-settings.js +0 -37
- package/homebridge-ui/public/js/profile-wizard.js +0 -61
|
@@ -1,88 +1,76 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* The claims served over a connection of their own, which therefore contend with nothing on the station.
|
|
3
3
|
*
|
|
4
|
-
* A
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
* A live view and a recording each get their own connection to the station, so both run at full rate together.
|
|
5
|
+
* A still opens none: it rides the station's own session and takes it from whatever that session carries, so it
|
|
6
|
+
* is the one claim that stands aside and the one claim that is asked to.
|
|
7
|
+
*/
|
|
8
|
+
const CONTINUOUS = new Set(['live', 'recording']);
|
|
9
|
+
/**
|
|
10
|
+
* The one registry of the work each station's own session is carrying, keyed by station serial.
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* - A recording writes to a file, so it survives being interrupted less well than being jittery, but it is
|
|
14
|
-
* not free to abandon the way a still is: a missed event cannot be re-taken.
|
|
15
|
-
* - A still fills a tile that is off screen exactly while a live view is on it, and re-running it costs
|
|
16
|
-
* nobody anything. Where it cannot run, the last good image stands in.
|
|
12
|
+
* Both sides of the question read it: HomeKit records a live view and a recording on their camera's station,
|
|
13
|
+
* and snapshot acquisition asks whether a station is carrying anything before opening a burst on it.
|
|
17
14
|
*
|
|
18
|
-
* A
|
|
19
|
-
*
|
|
20
|
-
*
|
|
15
|
+
* A still fills a tile that is off screen exactly while continuous work is running, re-running it costs nobody
|
|
16
|
+
* anything, and the last good image stands in where it cannot run — so it defers and nothing defers to it. A
|
|
17
|
+
* still asks a holder to yield rather than seizing the station: each holder registered how to abandon its own
|
|
18
|
+
* work, and a holder that registered none is left alone.
|
|
21
19
|
*
|
|
22
20
|
* None of it applies WITHIN one camera. Every egress on a camera shares one pull, so a recording and a live
|
|
23
|
-
* view of the same camera are served together and neither yields to the other.
|
|
24
|
-
* notification produces once the operator taps the tile, and it is the common shape rather than the exception.
|
|
25
|
-
*/
|
|
26
|
-
const CLAIM_RANK = { live: 3, recording: 2, snapshot: 1 };
|
|
27
|
-
/**
|
|
28
|
-
* The one registry of live sessions a station is serving, keyed by station serial.
|
|
29
|
-
*
|
|
30
|
-
* Both sides of the question read it: HomeKit records a live session on its camera's station, and snapshot
|
|
31
|
-
* acquisition asks whether a station is already serving one before opening a burst on it.
|
|
21
|
+
* view of the same camera are served together and neither yields to the other.
|
|
32
22
|
*/
|
|
33
23
|
export class StationLiveSessions {
|
|
24
|
+
decided;
|
|
34
25
|
sessions = new Map();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return this.sessions.size;
|
|
38
|
-
}
|
|
39
|
-
/** The strongest claim currently held on `stationSn`, or `undefined` where nothing holds it. */
|
|
40
|
-
heldFor(stationSn) {
|
|
41
|
-
let strongest;
|
|
42
|
-
for (const session of this.sessions.get(stationSn) ?? []) {
|
|
43
|
-
if (strongest === undefined || CLAIM_RANK[session.claim] > CLAIM_RANK[strongest]) {
|
|
44
|
-
strongest = session.claim;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return strongest;
|
|
26
|
+
constructor(decided = () => undefined) {
|
|
27
|
+
this.decided = decided;
|
|
48
28
|
}
|
|
49
29
|
/**
|
|
50
30
|
* Whether `claim` may take this station now.
|
|
51
31
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
32
|
+
* A continuous pull is never refused: it opens a connection of its own. A still is refused while any other
|
|
33
|
+
* camera holds the station, including for another still, because a capture rides the station's own session.
|
|
54
34
|
*/
|
|
55
35
|
admits(stationSn, camera, claim) {
|
|
56
|
-
let
|
|
36
|
+
let holderElsewhere;
|
|
57
37
|
for (const session of this.sessions.get(stationSn) ?? []) {
|
|
58
38
|
if (session.camera === camera) {
|
|
59
39
|
return true;
|
|
60
40
|
}
|
|
61
|
-
if (
|
|
62
|
-
|
|
41
|
+
if (holderElsewhere === undefined || CONTINUOUS.has(session.claim)) {
|
|
42
|
+
holderElsewhere = session.claim;
|
|
63
43
|
}
|
|
64
44
|
}
|
|
65
|
-
|
|
45
|
+
if (CONTINUOUS.has(claim) || holderElsewhere === undefined) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
this.decided({ action: 'refused', claim, by: holderElsewhere });
|
|
49
|
+
return false;
|
|
66
50
|
}
|
|
67
51
|
/**
|
|
68
|
-
* Record one session on `stationSn`, asking
|
|
69
|
-
* it.
|
|
52
|
+
* Record one session on `stationSn`, asking any still on another camera to yield first, and answer the
|
|
53
|
+
* release that ends it.
|
|
70
54
|
*
|
|
71
55
|
* `abandon` is how this session gives the station back before it would have finished. It is called at most
|
|
72
56
|
* once, and never on the session that is taking the station.
|
|
73
57
|
*/
|
|
74
58
|
hold(stationSn, camera, claim, abandon) {
|
|
75
|
-
const yielding =
|
|
59
|
+
const yielding = CONTINUOUS.has(claim)
|
|
60
|
+
? [...(this.sessions.get(stationSn) ?? [])].filter((session) => session.camera !== camera && !CONTINUOUS.has(session.claim))
|
|
61
|
+
: [];
|
|
76
62
|
const session = abandon ? { camera, claim, abandon } : { camera, claim };
|
|
77
63
|
const held = this.sessions.get(stationSn) ?? new Set();
|
|
78
64
|
held.add(session);
|
|
79
65
|
this.sessions.set(stationSn, held);
|
|
80
|
-
|
|
81
|
-
|
|
66
|
+
this.decided({ action: 'held', claim });
|
|
67
|
+
for (const standing of yielding) {
|
|
68
|
+
if (standing.asked) {
|
|
82
69
|
continue;
|
|
83
70
|
}
|
|
84
|
-
|
|
85
|
-
|
|
71
|
+
standing.asked = true;
|
|
72
|
+
this.decided({ action: 'yielded', claim: standing.claim, to: claim });
|
|
73
|
+
standing.abandon?.();
|
|
86
74
|
}
|
|
87
75
|
let released = false;
|
|
88
76
|
return () => {
|
|
@@ -90,6 +78,7 @@ export class StationLiveSessions {
|
|
|
90
78
|
return;
|
|
91
79
|
}
|
|
92
80
|
released = true;
|
|
81
|
+
this.decided({ action: 'released', claim });
|
|
93
82
|
const remaining = this.sessions.get(stationSn);
|
|
94
83
|
remaining?.delete(session);
|
|
95
84
|
if (remaining && remaining.size === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"station-live-sessions.js","sourceRoot":"","sources":["../../src/media/station-live-sessions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"station-live-sessions.js","sourceRoot":"","sources":["../../src/media/station-live-sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/platform.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { ffmpegPathSource, parseConfig } from './configuration.js';
|
|
2
|
-
import { createDiagnosticLogger, DiagnosticConditions,
|
|
1
|
+
import { ffmpegPathSource, parseConfig, resolveLiveVideoSettings } from './configuration.js';
|
|
2
|
+
import { createDiagnosticLogger, DiagnosticConditions, recordFleet, recordHostEnvironment, reportAdaptationNotice, reportLivePreview, reportLiveVideoEncoders, reportHomeKitEvent, unconfirmedWriteCondition, reportRuntimeNotice, reportStationClaim, } from './diagnostics.js';
|
|
3
3
|
import { deviceSnapshotLabel } from './device/snapshot.js';
|
|
4
4
|
import { HomeKitReconciler } from './homekit/reconciler.js';
|
|
5
|
-
import {
|
|
5
|
+
import { describeHomeKitRepresentation } from './homekit/representation.js';
|
|
6
|
+
import { FfmpegLiveMedia, resolveFfmpegIdentity, SMALL_VIDEO_PACKET_SIZE } from './media/live-stream.js';
|
|
6
7
|
import { FfmpegRecordingMedia } from './media/recording.js';
|
|
7
8
|
import { PersistedLastSuccessfulImages } from './media/last-successful-image.js';
|
|
9
|
+
import { startLivePreview } from './media/live-preview.js';
|
|
8
10
|
import { SnapshotAcquisition } from './media/snapshot.js';
|
|
9
11
|
import { DeclaredMediaSessionBudget } from './media/session-budget.js';
|
|
10
12
|
import { StationLiveSessions } from './media/station-live-sessions.js';
|
|
@@ -18,6 +20,7 @@ export function createEufyPlatform(clientFactory, shutdownTimeoutMs = 10_000, si
|
|
|
18
20
|
cachedAccessories = [];
|
|
19
21
|
reconciler;
|
|
20
22
|
unconfirmedWrites;
|
|
23
|
+
fleet;
|
|
21
24
|
constructor(log, config, api) {
|
|
22
25
|
const configuredConfig = parseConfig(config);
|
|
23
26
|
const storageRoot = api.user ? resolveStorageRoot(api.user.storagePath()) : undefined;
|
|
@@ -30,24 +33,54 @@ export function createEufyPlatform(clientFactory, shutdownTimeoutMs = 10_000, si
|
|
|
30
33
|
report: (notice) => reportAdaptationNotice(diagnosticLog, notice),
|
|
31
34
|
};
|
|
32
35
|
const liveMedia = configuredConfig.ffmpegPath
|
|
33
|
-
? new FfmpegLiveMedia(configuredConfig.ffmpegPath, adaptationDiagnostics)
|
|
36
|
+
? new FfmpegLiveMedia(configuredConfig.ffmpegPath, adaptationDiagnostics, undefined, undefined, undefined, configuredConfig.smallVideoPackets ? SMALL_VIDEO_PACKET_SIZE : undefined, configuredConfig.liveVideoPassthrough, configuredConfig.ignoreHomeBitRate)
|
|
34
37
|
: undefined;
|
|
35
38
|
const recordingMedia = configuredConfig.ffmpegPath
|
|
36
39
|
? new FfmpegRecordingMedia(configuredConfig.ffmpegPath, adaptationDiagnostics)
|
|
37
40
|
: undefined;
|
|
38
41
|
const mediaBudget = new DeclaredMediaSessionBudget(configuredConfig.maxConcurrentMediaSessions);
|
|
39
|
-
const stationLiveSessions = new StationLiveSessions();
|
|
42
|
+
const stationLiveSessions = new StationLiveSessions((decision) => reportStationClaim(diagnosticLog, decision));
|
|
40
43
|
const snapshotMedia = new SnapshotAcquisition(storageRoot
|
|
41
|
-
? new PersistedLastSuccessfulImages(storageRoot, () =>
|
|
44
|
+
? new PersistedLastSuccessfulImages(storageRoot, () => reportRuntimeNotice(diagnosticLog, 'camera-snapshot-cache-invalid'))
|
|
42
45
|
: undefined, mediaBudget, undefined, undefined, stationLiveSessions);
|
|
43
46
|
if (configuredConfig.discardedV4Settings.length > 0 && !configuredConfig.discardedV4Acknowledged) {
|
|
44
|
-
|
|
47
|
+
reportRuntimeNotice(diagnosticLog, 'discarded-v4-settings-unacknowledged');
|
|
45
48
|
}
|
|
46
49
|
this.runtime = new RuntimeOwner(diagnosticLog, configuredConfig, clientFactory, {
|
|
47
50
|
storageRoot,
|
|
48
51
|
shutdownTimeoutMs,
|
|
52
|
+
conditions: () => diagnostics.current(),
|
|
53
|
+
livePreview: (device, adaptation, onPicture, onEnd) => {
|
|
54
|
+
const camera = device.camera?.();
|
|
55
|
+
const ffmpegPath = configuredConfig.ffmpegPath;
|
|
56
|
+
if (!ffmpegPath || !liveMedia || typeof camera?.live !== 'function')
|
|
57
|
+
return undefined;
|
|
58
|
+
const live = camera.live.bind(camera);
|
|
59
|
+
const claim = mediaBudget.claim();
|
|
60
|
+
if (!claim)
|
|
61
|
+
return undefined;
|
|
62
|
+
const releaseStation = stationLiveSessions.hold(device.stationSn, device.sn, 'live');
|
|
63
|
+
return startLivePreview(ffmpegPath, liveMedia, { live }, adaptation, onPicture, (result) => reportLivePreview(diagnosticLog, { ...result, accessory: diagnostics.aliasFor(device.sn) }), (unplayable) => {
|
|
64
|
+
claim.release();
|
|
65
|
+
releaseStation();
|
|
66
|
+
onEnd(unplayable);
|
|
67
|
+
}, adaptationDiagnostics);
|
|
68
|
+
},
|
|
49
69
|
});
|
|
50
70
|
this.runtime.subscribeState((state) => diagnostics.reportRuntimeState(state));
|
|
71
|
+
if (storageRoot) {
|
|
72
|
+
this.fleet ??= this.runtime.subscribeRegistry((view) => recordFleet(storageRoot, view.snapshot.devices.map((manifest) => {
|
|
73
|
+
const admission = describeHomeKitRepresentation(manifest);
|
|
74
|
+
const station = view.registry.get(manifest.sn)?.stationSn;
|
|
75
|
+
return {
|
|
76
|
+
accessory: diagnostics.aliasFor(manifest.sn) ?? 'accessory-unaliased',
|
|
77
|
+
...(manifest.model === undefined ? {} : { model: manifest.model }),
|
|
78
|
+
represented: admission.represented,
|
|
79
|
+
attached: station !== undefined && station !== manifest.sn,
|
|
80
|
+
services: admission.services,
|
|
81
|
+
};
|
|
82
|
+
})));
|
|
83
|
+
}
|
|
51
84
|
const signals = ['SIGHUP', 'SIGINT', 'SIGTERM'];
|
|
52
85
|
let listeningForSignals = Boolean(signalTarget);
|
|
53
86
|
const stop = () => {
|
|
@@ -71,12 +104,30 @@ export function createEufyPlatform(clientFactory, shutdownTimeoutMs = 10_000, si
|
|
|
71
104
|
});
|
|
72
105
|
api.on('didFinishLaunching', () => {
|
|
73
106
|
const ffmpegPath = configuredConfig.ffmpegPath;
|
|
74
|
-
|
|
75
|
-
|
|
107
|
+
const qualification = ffmpegPath && liveMedia && configuredConfig.hardwareVideoEncoder
|
|
108
|
+
? liveMedia.qualify({
|
|
109
|
+
platform: process.platform,
|
|
110
|
+
arch: process.arch,
|
|
111
|
+
configured: ffmpegPathSource(ffmpegPath) === 'configured',
|
|
112
|
+
})
|
|
113
|
+
: undefined;
|
|
114
|
+
void qualification?.then((encoders) => reportLiveVideoEncoders(diagnosticLog, encoders));
|
|
115
|
+
if (storageRoot) {
|
|
116
|
+
const homebridge = typeof api.serverVersion === 'string' ? { homebridge: api.serverVersion } : {};
|
|
117
|
+
recordHostEnvironment(storageRoot, homebridge);
|
|
118
|
+
if (ffmpegPath) {
|
|
119
|
+
void resolveFfmpegIdentity(ffmpegPath, ffmpegPathSource(ffmpegPath)).then(async (ffmpeg) => {
|
|
120
|
+
recordHostEnvironment(storageRoot, { ...homebridge, ffmpeg });
|
|
121
|
+
const encoders = await qualification;
|
|
122
|
+
if (encoders) {
|
|
123
|
+
recordHostEnvironment(storageRoot, { ...homebridge, ffmpeg: { ...ffmpeg, encoders } });
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
76
127
|
}
|
|
77
128
|
const accessoryStore = createAccessoryStore(api);
|
|
78
129
|
if (accessoryStore) {
|
|
79
|
-
this.reconciler ??= new HomeKitReconciler(this.runtime, accessoryStore, (diagnostic, affectedDeviceIds = []) => diagnostics.reportHomeKit(diagnostic, affectedDeviceIds), this.cachedAccessories, (trace) => reportHomeKitEvent(diagnosticLog, trace), configuredConfig.entityPreferences, liveMedia, snapshotMedia, recordingMedia, mediaBudget, stationLiveSessions);
|
|
130
|
+
this.reconciler ??= new HomeKitReconciler(this.runtime, accessoryStore, (diagnostic, affectedDeviceIds = []) => diagnostics.reportHomeKit(diagnostic, affectedDeviceIds), this.cachedAccessories, (trace) => reportHomeKitEvent(diagnosticLog, trace, (serial) => diagnostics.aliasFor(serial)), configuredConfig.entityPreferences, liveMedia, snapshotMedia, recordingMedia, mediaBudget, stationLiveSessions, configuredConfig.hdLiveVideo, (serial) => resolveLiveVideoSettings(configuredConfig, serial));
|
|
80
131
|
this.reconciler.start();
|
|
81
132
|
}
|
|
82
133
|
void this.runtime.start();
|
package/dist/platform.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../src/platform.ts"],"names":[],"mappings":"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"}
|