@apocaliss92/scrypted-reolink-native 0.2.0 → 0.2.1
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/dist/main.nodejs.js +1 -1
- package/dist/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/camera.ts +3002 -90
- package/src/intercom.ts +2 -4
- package/src/main.ts +12 -38
- package/src/multiFocal.ts +70 -142
- package/src/nvr.ts +17 -193
- package/src/presets.ts +2 -2
- package/src/utils.ts +3 -4
- package/src/camera-battery.ts +0 -283
- package/src/common.ts +0 -2782
package/src/intercom.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { ReolinkBaichuanApi } from "@apocaliss92/reolink-baichuan-js" with { "resolution-mode": "import" };
|
|
2
2
|
import sdk, { FFmpegInput, MediaObject, ScryptedMimeTypes } from "@scrypted/sdk";
|
|
3
3
|
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
|
|
4
|
-
|
|
5
|
-
import type { ReolinkNativeCamera } from "./camera";
|
|
6
|
-
import { CommonCameraMixin } from "./common";
|
|
4
|
+
import { ReolinkCamera } from "./camera";
|
|
7
5
|
|
|
8
6
|
// Keep this low: Reolink blocks are ~64ms at 16kHz (1025 samples).
|
|
9
7
|
// A small backlog avoids multi-second latency when the pipeline stalls.
|
|
@@ -23,7 +21,7 @@ export class ReolinkBaichuanIntercom {
|
|
|
23
21
|
private sendChain: Promise<void> = Promise.resolve();
|
|
24
22
|
private pcmBuffer: Buffer = Buffer.alloc(0);
|
|
25
23
|
|
|
26
|
-
constructor(private camera:
|
|
24
|
+
constructor(private camera: ReolinkCamera) {
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
get blocksPerPayload(): number {
|
package/src/main.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import sdk, { DeviceCreator, DeviceCreatorSettings, DeviceProvider, HttpRequest, HttpResponse, MediaObject, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, ScryptedNativeId, Setting, VideoClips } from "@scrypted/sdk";
|
|
2
2
|
import { BaseBaichuanClass } from "./baichuan-base";
|
|
3
|
-
import { ReolinkNativeCamera } from "./camera";
|
|
4
|
-
import { ReolinkNativeBatteryCamera } from "./camera-battery";
|
|
5
|
-
import { CommonCameraMixin } from "./common";
|
|
6
3
|
import { ReolinkNativeMultiFocalDevice } from "./multiFocal";
|
|
7
4
|
import { ReolinkNativeNvrDevice } from "./nvr";
|
|
8
5
|
import { batteryCameraSuffix, batteryMultifocalSuffix, cameraSuffix, extractThumbnailFromVideo, getDeviceInterfaces, handleVideoClipRequest, multifocalSuffix, nvrSuffix } from "./utils";
|
|
9
6
|
import { randomBytes } from "crypto";
|
|
7
|
+
import { ReolinkCamera } from "./camera";
|
|
10
8
|
|
|
11
9
|
interface ThumbnailRequest {
|
|
12
10
|
deviceId: string;
|
|
@@ -14,7 +12,7 @@ interface ThumbnailRequest {
|
|
|
14
12
|
rtmpUrl?: string;
|
|
15
13
|
filePath?: string;
|
|
16
14
|
logger?: Console;
|
|
17
|
-
device?:
|
|
15
|
+
device?: ReolinkCamera;
|
|
18
16
|
resolve: (mo: MediaObject) => void;
|
|
19
17
|
reject: (error: Error) => void;
|
|
20
18
|
}
|
|
@@ -25,13 +23,12 @@ interface ThumbnailRequestInput {
|
|
|
25
23
|
rtmpUrl?: string;
|
|
26
24
|
filePath?: string;
|
|
27
25
|
logger?: Console;
|
|
28
|
-
device?:
|
|
26
|
+
device?: ReolinkCamera;
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider, DeviceCreator {
|
|
32
30
|
devices = new Map<string, BaseBaichuanClass>();
|
|
33
|
-
|
|
34
|
-
mixinsMap = new Map<string, CommonCameraMixin>();
|
|
31
|
+
camerasMap = new Map<string, ReolinkCamera>();
|
|
35
32
|
nvrDeviceId: string;
|
|
36
33
|
private thumbnailQueue: ThumbnailRequest[] = [];
|
|
37
34
|
private thumbnailProcessing = false;
|
|
@@ -48,36 +45,13 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
async getDevice(nativeId: ScryptedNativeId): Promise<BaseBaichuanClass> {
|
|
51
|
-
// Return existing device if available
|
|
52
48
|
if (this.devices.has(nativeId)) {
|
|
53
49
|
return this.devices.get(nativeId)!;
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return existingPromise;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Create device creation promise to handle concurrent requests
|
|
63
|
-
const creationPromise = (async () => {
|
|
64
|
-
try {
|
|
65
|
-
// Double-check after async operation
|
|
66
|
-
if (this.devices.has(nativeId)) {
|
|
67
|
-
return this.devices.get(nativeId)!;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const newCamera = this.createCamera(nativeId);
|
|
71
|
-
this.devices.set(nativeId, newCamera);
|
|
72
|
-
return newCamera;
|
|
73
|
-
} finally {
|
|
74
|
-
// Clean up the promise after creation completes
|
|
75
|
-
this.deviceCreationPromises.delete(nativeId);
|
|
76
|
-
}
|
|
77
|
-
})();
|
|
78
|
-
|
|
79
|
-
this.deviceCreationPromises.set(nativeId, creationPromise);
|
|
80
|
-
return creationPromise;
|
|
52
|
+
const newCamera = this.createCamera(nativeId);
|
|
53
|
+
this.devices.set(nativeId, newCamera);
|
|
54
|
+
return newCamera;
|
|
81
55
|
}
|
|
82
56
|
|
|
83
57
|
async createDevice(settings: DeviceCreatorSettings, nativeId?: string): Promise<string> {
|
|
@@ -206,7 +180,7 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
206
180
|
providerNativeId: this.nativeId,
|
|
207
181
|
});
|
|
208
182
|
|
|
209
|
-
const device = await this.getDevice(nativeId) as
|
|
183
|
+
const device = await this.getDevice(nativeId) as ReolinkCamera;
|
|
210
184
|
|
|
211
185
|
device.info = deviceInfo;
|
|
212
186
|
device.classes = objects;
|
|
@@ -223,7 +197,7 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
223
197
|
}
|
|
224
198
|
catch (e) {
|
|
225
199
|
this.console.error('Error adding Reolink device', e?.message || String(e));
|
|
226
|
-
throw e;
|
|
200
|
+
throw e;
|
|
227
201
|
}
|
|
228
202
|
}
|
|
229
203
|
|
|
@@ -265,7 +239,7 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
265
239
|
|
|
266
240
|
createCamera(nativeId: string) {
|
|
267
241
|
if (nativeId.endsWith(batteryCameraSuffix)) {
|
|
268
|
-
return new
|
|
242
|
+
return new ReolinkCamera(nativeId, this, { type: 'battery' });
|
|
269
243
|
} else if (nativeId.endsWith(nvrSuffix)) {
|
|
270
244
|
return new ReolinkNativeNvrDevice(nativeId, this);
|
|
271
245
|
} else if (nativeId.endsWith(batteryMultifocalSuffix)) {
|
|
@@ -273,7 +247,7 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
273
247
|
} else if (nativeId.endsWith(multifocalSuffix)) {
|
|
274
248
|
return new ReolinkNativeMultiFocalDevice(nativeId, this, "multi-focal");
|
|
275
249
|
} else {
|
|
276
|
-
return new
|
|
250
|
+
return new ReolinkCamera(nativeId, this, { type: 'regular' });
|
|
277
251
|
}
|
|
278
252
|
}
|
|
279
253
|
|
|
@@ -313,7 +287,7 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
313
287
|
// logger.log(`Webhook request: type=${type}, deviceId=${deviceId}, fileId=${fileId}`);
|
|
314
288
|
|
|
315
289
|
// Get the device
|
|
316
|
-
const device = this.
|
|
290
|
+
const device = this.camerasMap.get(deviceId);
|
|
317
291
|
if (!device) {
|
|
318
292
|
response.send('Device not found', { code: 404 });
|
|
319
293
|
return;
|
package/src/multiFocal.ts
CHANGED
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import type { DeviceCapabilities, DualLensChannelAnalysis, NativeVideoStreamVariant, ReolinkBaichuanApi, ReolinkSimpleEvent, SleepStatus
|
|
2
|
-
import type { BaichuanConnectionConfig } from "./baichuan-base";
|
|
1
|
+
import type { BatteryInfo, DeviceCapabilities, DualLensChannelAnalysis, NativeVideoStreamVariant, ReolinkBaichuanApi, ReolinkSimpleEvent, SleepStatus } from "@apocaliss92/reolink-baichuan-js" with { "resolution-mode": "import" };
|
|
3
2
|
import sdk, { Device, DeviceProvider, Reboot, ScryptedDeviceType, Settings } from "@scrypted/sdk";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { CameraType, CommonCameraMixin } from "./common";
|
|
3
|
+
import type { BaichuanConnectionConfig } from "./baichuan-base";
|
|
4
|
+
import { CameraType, ReolinkCamera } from "./camera";
|
|
7
5
|
import ReolinkNativePlugin from "./main";
|
|
8
|
-
import { batteryCameraSuffix, cameraSuffix, getDeviceInterfaces } from "./utils";
|
|
9
6
|
import { ReolinkNativeNvrDevice } from "./nvr";
|
|
10
|
-
import {
|
|
7
|
+
import { batteryCameraSuffix, cameraSuffix, getDeviceInterfaces } from "./utils";
|
|
11
8
|
|
|
12
|
-
export class ReolinkNativeMultiFocalDevice extends
|
|
9
|
+
export class ReolinkNativeMultiFocalDevice extends ReolinkCamera implements Settings, DeviceProvider, Reboot {
|
|
13
10
|
plugin: ReolinkNativePlugin;
|
|
14
|
-
|
|
11
|
+
lensDevicesMap = new Map<string, ReolinkCamera>();
|
|
15
12
|
private channelToNativeIdMap = new Map<number, string>();
|
|
16
|
-
isBattery: boolean;
|
|
17
13
|
|
|
18
14
|
constructor(nativeId: string, plugin: ReolinkNativePlugin, type: CameraType, nvrDevice?: ReolinkNativeNvrDevice) {
|
|
19
15
|
super(nativeId, plugin, { type, nvrDevice });
|
|
@@ -29,21 +25,6 @@ export class ReolinkNativeMultiFocalDevice extends CommonCameraMixin implements
|
|
|
29
25
|
return this.name || 'Multi-Focal Device';
|
|
30
26
|
}
|
|
31
27
|
|
|
32
|
-
async init(): Promise<void> {
|
|
33
|
-
const logger = this.getBaichuanLogger();
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
this.storageSettings.settings.uid.hide = !this.isBattery;
|
|
37
|
-
|
|
38
|
-
await this.ensureClient();
|
|
39
|
-
// subscribeToEvents in common.ts will check if this device has a parent (nvrDevice)
|
|
40
|
-
// and skip subscription if needed - events will be forwarded from parent
|
|
41
|
-
await this.subscribeToEvents();
|
|
42
|
-
} catch (e) {
|
|
43
|
-
logger.error('Failed to initialize multi-focal device', e?.message || String(e));
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
28
|
getInterfaces(lensType?: NativeVideoStreamVariant) {
|
|
48
29
|
const logger = this.getBaichuanLogger();
|
|
49
30
|
const { capabilities: caps, multifocalInfo } = this.storageSettings.values;
|
|
@@ -71,12 +52,14 @@ export class ReolinkNativeMultiFocalDevice extends CommonCameraMixin implements
|
|
|
71
52
|
logger,
|
|
72
53
|
});
|
|
73
54
|
|
|
74
|
-
logger.debug(`Interfaces found for lens ${lensType}: ${JSON.stringify({ interfaces, capabilities, multifocalInfo })}`);
|
|
55
|
+
// logger.debug(`Interfaces found for lens ${lensType}: ${JSON.stringify({ interfaces, capabilities, multifocalInfo })}`);
|
|
75
56
|
|
|
76
57
|
return { interfaces, capabilities };
|
|
77
58
|
}
|
|
78
59
|
|
|
79
60
|
async reportDevices(): Promise<void> {
|
|
61
|
+
await super.reportDevices();
|
|
62
|
+
|
|
80
63
|
const logger = this.getBaichuanLogger();
|
|
81
64
|
|
|
82
65
|
try {
|
|
@@ -150,14 +133,19 @@ export class ReolinkNativeMultiFocalDevice extends CommonCameraMixin implements
|
|
|
150
133
|
|
|
151
134
|
async getDevice(nativeId: string) {
|
|
152
135
|
if (nativeId.endsWith(cameraSuffix) || nativeId.endsWith(batteryCameraSuffix)) {
|
|
153
|
-
let device = this.
|
|
136
|
+
let device = this.lensDevicesMap.get(nativeId);
|
|
154
137
|
if (!device) {
|
|
155
138
|
if (nativeId.endsWith(batteryCameraSuffix)) {
|
|
156
|
-
device = new
|
|
139
|
+
device = new ReolinkCamera(nativeId, this.plugin, { type: 'battery', multiFocalDevice: this });
|
|
157
140
|
} else {
|
|
158
|
-
device = new
|
|
141
|
+
device = new ReolinkCamera(nativeId, this.plugin, { type: 'regular', multiFocalDevice: this });
|
|
159
142
|
}
|
|
160
143
|
}
|
|
144
|
+
|
|
145
|
+
if (device) {
|
|
146
|
+
this.lensDevicesMap.set(nativeId, device);
|
|
147
|
+
}
|
|
148
|
+
|
|
161
149
|
return device;
|
|
162
150
|
} else {
|
|
163
151
|
return super.getDevice(nativeId);
|
|
@@ -165,126 +153,14 @@ export class ReolinkNativeMultiFocalDevice extends CommonCameraMixin implements
|
|
|
165
153
|
}
|
|
166
154
|
|
|
167
155
|
async releaseDevice(id: string, nativeId: string) {
|
|
168
|
-
this.
|
|
156
|
+
this.lensDevicesMap.delete(nativeId);
|
|
169
157
|
super.releaseDevice(id, nativeId);
|
|
170
158
|
}
|
|
171
159
|
|
|
172
|
-
/**
|
|
173
|
-
* Forward events received from parent (NVR if child, or directly from Baichuan if standalone)
|
|
174
|
-
* to the MultiFocal device itself AND to ALL lens devices (camera children) of this MultiFocal.
|
|
175
|
-
* This ensures that:
|
|
176
|
-
* 1. The MultiFocal device itself receives events (it can have event handling capabilities)
|
|
177
|
-
* 2. All lenses receive the events, even if they share the same channel
|
|
178
|
-
* (e.g., wide and tele on the same channel on NVR).
|
|
179
|
-
* Only the root device (NVR or standalone MultiFocal) subscribes to events,
|
|
180
|
-
* and events are forwarded down the hierarchy.
|
|
181
|
-
*/
|
|
182
|
-
forwardNativeEvent(ev: ReolinkSimpleEvent): void {
|
|
183
|
-
const logger = this.getBaichuanLogger();
|
|
184
|
-
const eventChannel = ev?.channel;
|
|
185
|
-
|
|
186
|
-
// First, forward event to the MultiFocal device itself
|
|
187
|
-
try {
|
|
188
|
-
this.onSimpleEvent(ev);
|
|
189
|
-
} catch (e) {
|
|
190
|
-
logger.warn(`Error forwarding event to MultiFocal device itself:`, e?.message || String(e));
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Then, forward event to all lens devices (camera children) of this MultiFocal
|
|
194
|
-
// Even if event has a specific channel, we forward to all lenses because:
|
|
195
|
-
// 1. On NVR, wide and tele lenses can share the same channel
|
|
196
|
-
// 2. Events might be relevant to all lenses of the MultiFocal device
|
|
197
|
-
const lensDevices = Array.from(this.cameraNativeMap.values());
|
|
198
|
-
const forwardedCount = lensDevices.length;
|
|
199
|
-
|
|
200
|
-
if (forwardedCount === 0) {
|
|
201
|
-
logger.debug(`No lens devices found for MultiFocal, event forwarded only to MultiFocal itself`);
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
logger.debug(`Forwarding event (channel=${eventChannel}) to MultiFocal itself and ${forwardedCount} lens device(s)`);
|
|
206
|
-
|
|
207
|
-
// Forward event to all camera children (lens devices)
|
|
208
|
-
for (const camera of lensDevices) {
|
|
209
|
-
try {
|
|
210
|
-
// Each lens device will filter events based on its own channel if needed
|
|
211
|
-
camera.onSimpleEvent(ev);
|
|
212
|
-
} catch (e) {
|
|
213
|
-
logger.warn(`Error forwarding event to lens device ${camera.nativeId}:`, e?.message || String(e));
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
160
|
async unsubscribeFromAllEvents(): Promise<void> {
|
|
219
161
|
await super.unsubscribeFromEvents();
|
|
220
162
|
}
|
|
221
163
|
|
|
222
|
-
/**
|
|
223
|
-
* Update sleeping state for the MultiFocal device itself and propagate to all lens devices.
|
|
224
|
-
* This ensures that when the MultiFocal receives a sleeping/awake state update (from events or API calls),
|
|
225
|
-
* the state is synchronized across the MultiFocal and all its lens children.
|
|
226
|
-
*/
|
|
227
|
-
async updateSleepingState(sleepStatus: SleepStatus): Promise<void> {
|
|
228
|
-
const logger = this.getBaichuanLogger();
|
|
229
|
-
|
|
230
|
-
// First, update the MultiFocal device's own sleeping state
|
|
231
|
-
await super.updateSleepingState(sleepStatus);
|
|
232
|
-
|
|
233
|
-
// Then, propagate the state to all lens devices (camera children)
|
|
234
|
-
const lensDevices = Array.from(this.cameraNativeMap.values());
|
|
235
|
-
|
|
236
|
-
if (lensDevices.length === 0) {
|
|
237
|
-
logger.debug(`No lens devices found for MultiFocal, sleeping state updated only for MultiFocal itself`);
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
logger.debug(`Propagating sleeping state (state=${sleepStatus.state}) to ${lensDevices.length} lens device(s)`);
|
|
242
|
-
|
|
243
|
-
// Propagate sleeping state to all lens devices
|
|
244
|
-
await Promise.allSettled(
|
|
245
|
-
lensDevices.map(async (camera) => {
|
|
246
|
-
try {
|
|
247
|
-
await camera.updateSleepingState(sleepStatus);
|
|
248
|
-
} catch (e) {
|
|
249
|
-
logger.warn(`Error propagating sleeping state to lens device ${camera.nativeId}:`, e?.message || String(e));
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Update online state for the MultiFocal device itself and propagate to all lens devices.
|
|
257
|
-
* This ensures that when the MultiFocal receives an online/offline state update (from events or API calls),
|
|
258
|
-
* the state is synchronized across the MultiFocal and all its lens children.
|
|
259
|
-
*/
|
|
260
|
-
async updateOnlineState(isOnline: boolean): Promise<void> {
|
|
261
|
-
const logger = this.getBaichuanLogger();
|
|
262
|
-
|
|
263
|
-
// First, update the MultiFocal device's own online state
|
|
264
|
-
await super.updateOnlineState(isOnline);
|
|
265
|
-
|
|
266
|
-
// Then, propagate the state to all lens devices (camera children)
|
|
267
|
-
const lensDevices = Array.from(this.cameraNativeMap.values());
|
|
268
|
-
|
|
269
|
-
if (lensDevices.length === 0) {
|
|
270
|
-
logger.debug(`No lens devices found for MultiFocal, online state updated only for MultiFocal itself`);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
logger.debug(`Propagating online state (isOnline=${isOnline}) to ${lensDevices.length} lens device(s)`);
|
|
275
|
-
|
|
276
|
-
// Propagate online state to all lens devices
|
|
277
|
-
await Promise.allSettled(
|
|
278
|
-
lensDevices.map(async (camera) => {
|
|
279
|
-
try {
|
|
280
|
-
await camera.updateOnlineState(isOnline);
|
|
281
|
-
} catch (e) {
|
|
282
|
-
logger.warn(`Error propagating online state to lens device ${camera.nativeId}:`, e?.message || String(e));
|
|
283
|
-
}
|
|
284
|
-
})
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
164
|
public async runDiagnostics(): Promise<void> {
|
|
289
165
|
const logger = this.getBaichuanLogger();
|
|
290
166
|
logger.log(`Starting Multifocal diagnostics...`);
|
|
@@ -342,5 +218,57 @@ export class ReolinkNativeMultiFocalDevice extends CommonCameraMixin implements
|
|
|
342
218
|
// Otherwise, use base class createStreamClient which manages stream clients per streamKey
|
|
343
219
|
return await super.createStreamClient(streamKey);
|
|
344
220
|
}
|
|
221
|
+
|
|
222
|
+
getLensDevices() {
|
|
223
|
+
const devices = Array.from(this.lensDevicesMap.values());
|
|
224
|
+
// const logger = this.getBaichuanLogger();
|
|
225
|
+
// logger.debug(`Found ${devices.length} lens devices: ${devices.map(d => d.nativeId).join(', ')}`);
|
|
226
|
+
|
|
227
|
+
return devices;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async updateBatteryInfo() {
|
|
231
|
+
const batteryInfo = await super.updateBatteryInfo();
|
|
232
|
+
const lensDevices = this.getLensDevices();
|
|
233
|
+
|
|
234
|
+
for (const camera of lensDevices) {
|
|
235
|
+
await camera.updateBatteryInfo(batteryInfo);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return batteryInfo;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
onSimpleEvent(ev: ReolinkSimpleEvent) {
|
|
242
|
+
super.onSimpleEvent(ev);
|
|
243
|
+
const logger = this.getBaichuanLogger();
|
|
244
|
+
const lensDevices = this.getLensDevices();
|
|
245
|
+
|
|
246
|
+
for (const camera of lensDevices) {
|
|
247
|
+
logger.debug(`Forward ${ev.type} event to lens device ${camera.nativeId}`);
|
|
248
|
+
camera.onSimpleEvent(ev);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async updateSleepingState(sleepStatus: SleepStatus) {
|
|
253
|
+
const logger = this.getBaichuanLogger();
|
|
254
|
+
await super.updateSleepingState(sleepStatus);
|
|
255
|
+
const lensDevices = this.getLensDevices();
|
|
256
|
+
|
|
257
|
+
for (const camera of lensDevices) {
|
|
258
|
+
logger.debug(`Forward ${JSON.stringify(sleepStatus)} sleeping state to lens device ${camera.nativeId}`);
|
|
259
|
+
await camera.updateSleepingState(sleepStatus);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async updateOnlineState(isOnline: boolean) {
|
|
264
|
+
const logger = this.getBaichuanLogger();
|
|
265
|
+
await super.updateOnlineState(isOnline);
|
|
266
|
+
const lensDevices = this.getLensDevices();
|
|
267
|
+
|
|
268
|
+
for (const camera of lensDevices) {
|
|
269
|
+
logger.debug(`Forward ${isOnline ? 'online' : 'offline'} state to lens device ${camera.nativeId}`);
|
|
270
|
+
await camera.updateOnlineState(isOnline);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
345
273
|
}
|
|
346
274
|
|