@apocaliss92/scrypted-reolink-native 0.1.25 → 0.1.27
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/baichuan-base.ts +1 -2
- package/src/camera-battery.ts +0 -6
- package/src/camera.ts +4 -25
- package/src/common.ts +140 -126
- package/src/connect.ts +3 -3
- package/src/main.ts +24 -16
- package/src/multiFocal.ts +48 -107
- package/src/nvr.ts +6 -6
- package/src/utils.ts +12 -3
package/src/main.ts
CHANGED
|
@@ -4,10 +4,9 @@ import { ReolinkNativeCamera } from "./camera";
|
|
|
4
4
|
import { ReolinkNativeBatteryCamera } from "./camera-battery";
|
|
5
5
|
import { CommonCameraMixin } from "./common";
|
|
6
6
|
import { createBaichuanApi } from "./connect";
|
|
7
|
-
import { ReolinkNativeMultiFocalDevice } from "./multiFocal";
|
|
8
7
|
import { ReolinkNativeNvrDevice } from "./nvr";
|
|
9
|
-
import { batteryCameraSuffix, cameraSuffix, getDeviceInterfaces, multifocalSuffix, nvrSuffix } from "./utils";
|
|
10
|
-
import {
|
|
8
|
+
import { batteryCameraSuffix, batteryMultifocalSuffix, cameraSuffix, getDeviceInterfaces, multifocalSuffix, nvrSuffix } from "./utils";
|
|
9
|
+
import { ReolinkNativeMultiFocalDevice } from "./multiFocal";
|
|
11
10
|
|
|
12
11
|
class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider, DeviceCreator {
|
|
13
12
|
devices = new Map<string, BaseBaichuanClass>();
|
|
@@ -65,18 +64,28 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
65
64
|
const deviceInfo = detection.deviceInfo || {};
|
|
66
65
|
const name = deviceInfo.name || 'Reolink Multi-Focal';
|
|
67
66
|
const serialNumber = deviceInfo.serialNumber || deviceInfo.itemNo || `multifocal-${Date.now()}`;
|
|
68
|
-
|
|
67
|
+
const isBattery = detection.transport === 'udp';
|
|
68
|
+
nativeId = `${serialNumber}${isBattery ? batteryMultifocalSuffix : multifocalSuffix}`;
|
|
69
69
|
|
|
70
70
|
settings.newCamera ||= name;
|
|
71
71
|
|
|
72
|
+
const interfaces = [
|
|
73
|
+
ScryptedInterface.Settings,
|
|
74
|
+
ScryptedInterface.DeviceProvider,
|
|
75
|
+
ScryptedInterface.Reboot,
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
if (isBattery) {
|
|
79
|
+
interfaces.push(
|
|
80
|
+
ScryptedInterface.Battery,
|
|
81
|
+
ScryptedInterface.Sleep
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
72
85
|
await sdk.deviceManager.onDeviceDiscovered({
|
|
73
86
|
nativeId,
|
|
74
87
|
name,
|
|
75
|
-
interfaces
|
|
76
|
-
ScryptedInterface.Settings,
|
|
77
|
-
ScryptedInterface.DeviceProvider,
|
|
78
|
-
ScryptedInterface.Reboot,
|
|
79
|
-
],
|
|
88
|
+
interfaces,
|
|
80
89
|
type: ScryptedDeviceType.DeviceProvider,
|
|
81
90
|
providerNativeId: this.nativeId,
|
|
82
91
|
});
|
|
@@ -89,7 +98,6 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
89
98
|
device.storageSettings.values.username = username;
|
|
90
99
|
device.storageSettings.values.password = password;
|
|
91
100
|
device.storageSettings.values.uid = detection.uid || '';
|
|
92
|
-
device.storageSettings.values.protocol = detection.transport || 'tcp' as BaichuanTransport;
|
|
93
101
|
|
|
94
102
|
return nativeId;
|
|
95
103
|
}
|
|
@@ -151,15 +159,12 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
151
159
|
logger: this.console,
|
|
152
160
|
},
|
|
153
161
|
transport: detection.transport,
|
|
154
|
-
logger: this.console,
|
|
155
162
|
});
|
|
156
163
|
|
|
157
164
|
try {
|
|
158
165
|
await api.login();
|
|
159
166
|
const rtspChannel = 0;
|
|
160
|
-
const {
|
|
161
|
-
|
|
162
|
-
this.console.log(nativeId, JSON.stringify({ abilities, capabilities, deviceInfo }));
|
|
167
|
+
const { capabilities, objects, presets } = await api.getDeviceCapabilities(rtspChannel);
|
|
163
168
|
|
|
164
169
|
const { interfaces, type } = getDeviceInterfaces({
|
|
165
170
|
capabilities,
|
|
@@ -175,7 +180,6 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
175
180
|
});
|
|
176
181
|
|
|
177
182
|
const device = await this.getDevice(nativeId) as CommonCameraMixin;
|
|
178
|
-
this.console.log(name, interfaces, type, device);
|
|
179
183
|
|
|
180
184
|
device.info = deviceInfo;
|
|
181
185
|
device.classes = objects;
|
|
@@ -214,10 +218,12 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
214
218
|
key: 'ip',
|
|
215
219
|
title: 'IP Address',
|
|
216
220
|
placeholder: '192.168.2.222',
|
|
221
|
+
value: '192.168.',
|
|
217
222
|
},
|
|
218
223
|
{
|
|
219
224
|
key: 'username',
|
|
220
225
|
title: 'Username',
|
|
226
|
+
value: 'admin',
|
|
221
227
|
},
|
|
222
228
|
{
|
|
223
229
|
key: 'password',
|
|
@@ -237,8 +243,10 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
237
243
|
return new ReolinkNativeBatteryCamera(nativeId, this);
|
|
238
244
|
} else if (nativeId.endsWith(nvrSuffix)) {
|
|
239
245
|
return new ReolinkNativeNvrDevice(nativeId, this);
|
|
246
|
+
} else if (nativeId.endsWith(batteryMultifocalSuffix)) {
|
|
247
|
+
return new ReolinkNativeMultiFocalDevice(nativeId, this, "multi-focal-battery");
|
|
240
248
|
} else if (nativeId.endsWith(multifocalSuffix)) {
|
|
241
|
-
return new ReolinkNativeMultiFocalDevice(nativeId, this);
|
|
249
|
+
return new ReolinkNativeMultiFocalDevice(nativeId, this, "multi-focal");
|
|
242
250
|
} else {
|
|
243
251
|
return new ReolinkNativeCamera(nativeId, this);
|
|
244
252
|
}
|
package/src/multiFocal.ts
CHANGED
|
@@ -1,110 +1,50 @@
|
|
|
1
1
|
import type { DeviceCapabilities, DualLensChannelAnalysis, ReolinkSimpleEvent } from "@apocaliss92/reolink-baichuan-js" with { "resolution-mode": "import" };
|
|
2
|
-
import sdk, { Device, DeviceProvider, Reboot, ScryptedDeviceType, Setting, Settings, SettingValue } from "@scrypted/sdk";
|
|
3
|
-
import {
|
|
4
|
-
import { BaseBaichuanClass, type BaichuanConnectionCallbacks, type BaichuanConnectionConfig } from "./baichuan-base";
|
|
2
|
+
import sdk, { Device, DeviceProvider, MediaObject, Reboot, ScryptedDeviceType, Setting, Settings, SettingValue } from "@scrypted/sdk";
|
|
3
|
+
import { type BaichuanConnectionCallbacks } from "./baichuan-base";
|
|
5
4
|
import { ReolinkNativeCamera } from "./camera";
|
|
6
5
|
import { ReolinkNativeBatteryCamera } from "./camera-battery";
|
|
7
|
-
import {
|
|
6
|
+
import { CameraType, CommonCameraMixin } from "./common";
|
|
8
7
|
import ReolinkNativePlugin from "./main";
|
|
9
8
|
import { batteryCameraSuffix, cameraSuffix, getDeviceInterfaces, updateDeviceInfo } from "./utils";
|
|
10
9
|
|
|
11
|
-
export class ReolinkNativeMultiFocalDevice extends
|
|
12
|
-
storageSettings = new StorageSettings(this, {
|
|
13
|
-
debugEvents: {
|
|
14
|
-
title: 'Debug Events',
|
|
15
|
-
type: 'boolean',
|
|
16
|
-
immediate: true,
|
|
17
|
-
},
|
|
18
|
-
ipAddress: {
|
|
19
|
-
title: 'IP address',
|
|
20
|
-
type: 'string',
|
|
21
|
-
onPut: async () => await this.reinit()
|
|
22
|
-
},
|
|
23
|
-
username: {
|
|
24
|
-
title: 'Username',
|
|
25
|
-
placeholder: 'admin',
|
|
26
|
-
defaultValue: 'admin',
|
|
27
|
-
type: 'string',
|
|
28
|
-
onPut: async () => await this.reinit()
|
|
29
|
-
},
|
|
30
|
-
password: {
|
|
31
|
-
title: 'Password',
|
|
32
|
-
type: 'password',
|
|
33
|
-
onPut: async () => await this.reinit()
|
|
34
|
-
},
|
|
35
|
-
uid: {
|
|
36
|
-
title: 'UID',
|
|
37
|
-
description: 'Reolink UID (required for UDP/battery multi-focal devices)',
|
|
38
|
-
type: 'string',
|
|
39
|
-
hide: true,
|
|
40
|
-
onPut: async () => await this.reinit()
|
|
41
|
-
},
|
|
42
|
-
protocol: {
|
|
43
|
-
type: 'string',
|
|
44
|
-
hide: true,
|
|
45
|
-
},
|
|
46
|
-
diagnosticsRun: {
|
|
47
|
-
subgroup: 'Diagnostics',
|
|
48
|
-
title: 'Run Diagnostics',
|
|
49
|
-
description: 'Collect diagnostics and display results in logs.',
|
|
50
|
-
type: 'button',
|
|
51
|
-
immediate: true,
|
|
52
|
-
onPut: async () => {
|
|
53
|
-
await this.runDiagnostics();
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
multifocalInfo: {
|
|
57
|
-
json: true,
|
|
58
|
-
hide: true,
|
|
59
|
-
},
|
|
60
|
-
capabilities: {
|
|
61
|
-
json: true,
|
|
62
|
-
hide: true,
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
|
|
10
|
+
export class ReolinkNativeMultiFocalDevice extends CommonCameraMixin implements Settings, DeviceProvider, Reboot {
|
|
66
11
|
plugin: ReolinkNativePlugin;
|
|
67
12
|
cameraNativeMap = new Map<string, ReolinkNativeCamera | ReolinkNativeBatteryCamera>();
|
|
68
13
|
private channelToNativeIdMap = new Map<number, string>();
|
|
69
14
|
private initReinitTimeout: NodeJS.Timeout | undefined;
|
|
70
15
|
isBattery: boolean;
|
|
71
16
|
|
|
72
|
-
constructor(nativeId: string, plugin: ReolinkNativePlugin) {
|
|
73
|
-
super(nativeId);
|
|
17
|
+
constructor(nativeId: string, plugin: ReolinkNativePlugin, type: CameraType) {
|
|
18
|
+
super(nativeId, plugin, { type });
|
|
74
19
|
this.plugin = plugin;
|
|
75
20
|
|
|
76
|
-
this.isBattery = this.storageSettings.values.protocol === 'udp';
|
|
77
|
-
|
|
78
21
|
this.scheduleInit();
|
|
79
22
|
}
|
|
80
23
|
|
|
24
|
+
getAbilities(): DeviceCapabilities {
|
|
25
|
+
const { capabilities } = this.storageSettings.values;
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
...capabilities,
|
|
29
|
+
hasPan: false,
|
|
30
|
+
hasTilt: false,
|
|
31
|
+
hasZoom: false,
|
|
32
|
+
hasPresets: false,
|
|
33
|
+
hasIntercom: false,
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
81
37
|
async reboot(): Promise<void> {
|
|
82
38
|
const api = await this.ensureBaichuanClient();
|
|
83
39
|
await api.reboot();
|
|
84
40
|
}
|
|
85
41
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
throw new Error('Missing device credentials');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const { protocol } = this.storageSettings.values;
|
|
93
|
-
|
|
94
|
-
const normalizedUid = this.isBattery ? normalizeUid(uid) : undefined;
|
|
95
|
-
|
|
96
|
-
if (protocol === 'udp' && !normalizedUid) {
|
|
97
|
-
throw new Error('UID is required for UDP multi-focal devices (BCUDP)');
|
|
98
|
-
}
|
|
42
|
+
takePicture(options?: any): Promise<MediaObject> {
|
|
43
|
+
throw new Error("Method not implemented.");
|
|
44
|
+
}
|
|
99
45
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
username,
|
|
103
|
-
password,
|
|
104
|
-
uid: normalizedUid,
|
|
105
|
-
transport: protocol,
|
|
106
|
-
logger: this.console,
|
|
107
|
-
};
|
|
46
|
+
getPictureOptions(): Promise<any[]> {
|
|
47
|
+
throw new Error("Method not implemented.");
|
|
108
48
|
}
|
|
109
49
|
|
|
110
50
|
protected getConnectionCallbacks(): BaichuanConnectionCallbacks {
|
|
@@ -134,7 +74,7 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
134
74
|
}
|
|
135
75
|
|
|
136
76
|
protected isDebugEnabled(): boolean {
|
|
137
|
-
return this.storageSettings.values.debugEvents;
|
|
77
|
+
return this.storageSettings.values.debugEvents || false;
|
|
138
78
|
}
|
|
139
79
|
|
|
140
80
|
protected getDeviceName(): string {
|
|
@@ -199,9 +139,8 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
199
139
|
device: this,
|
|
200
140
|
deviceData,
|
|
201
141
|
ipAddress: this.storageSettings.values.ipAddress,
|
|
142
|
+
logger,
|
|
202
143
|
});
|
|
203
|
-
|
|
204
|
-
logger.log(`Device info updated: ${JSON.stringify(deviceData)}`);
|
|
205
144
|
} catch (e) {
|
|
206
145
|
logger.warn('Failed to fetch device info', e);
|
|
207
146
|
}
|
|
@@ -242,13 +181,15 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
242
181
|
this.storageSettings.values.multifocalInfo = multifocalInfo;
|
|
243
182
|
this.storageSettings.values.capabilities = capabilities;
|
|
244
183
|
|
|
245
|
-
|
|
184
|
+
// TODO: Remove this after debugging
|
|
185
|
+
logger.log(`Multichannel info: ${JSON.stringify({ multifocalInfo, capabilities, support, abilities, features, objects, presets })}`);
|
|
186
|
+
// logger.debug(`Multichannel info: ${JSON.stringify({ multifocalInfo, capabilities, support, abilities, features, objects, presets })}`);
|
|
246
187
|
|
|
247
188
|
for (const channelInfo of multifocalInfo?.channels ?? []) {
|
|
248
189
|
const { channel, lensType } = channelInfo;
|
|
249
190
|
|
|
250
191
|
const name = `${this.name} - ${lensType}`;
|
|
251
|
-
const nativeId = this.
|
|
192
|
+
const nativeId = `${this.nativeId}-channel${channel}${this.isBattery ? batteryCameraSuffix : cameraSuffix}`;
|
|
252
193
|
|
|
253
194
|
this.channelToNativeIdMap.set(channel, nativeId);
|
|
254
195
|
const { interfaces, capabilities: deviceCapabilities } = this.getInterfaces(channel);
|
|
@@ -270,6 +211,9 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
270
211
|
|
|
271
212
|
await sdk.deviceManager.onDeviceDiscovered(device);
|
|
272
213
|
|
|
214
|
+
// TODO: Remove this after debugging
|
|
215
|
+
logger.log(`Discovering lens device ${nativeId}: ${JSON.stringify({ interfaces, deviceCapabilities })}`);
|
|
216
|
+
|
|
273
217
|
const camera = await this.getDevice(nativeId);
|
|
274
218
|
|
|
275
219
|
camera.storageSettings.values.rtspChannel = channel;
|
|
@@ -286,16 +230,19 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
286
230
|
}
|
|
287
231
|
|
|
288
232
|
async getDevice(nativeId: string) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
233
|
+
if (nativeId.endsWith(cameraSuffix) || nativeId.endsWith(batteryCameraSuffix)) {
|
|
234
|
+
let device = this.cameraNativeMap.get(nativeId);
|
|
235
|
+
if (!device) {
|
|
236
|
+
if (nativeId.endsWith(batteryCameraSuffix)) {
|
|
237
|
+
device = new ReolinkNativeBatteryCamera(nativeId, this.plugin, undefined, this);
|
|
238
|
+
} else {
|
|
239
|
+
device = new ReolinkNativeCamera(nativeId, this.plugin, undefined, this);
|
|
240
|
+
}
|
|
295
241
|
}
|
|
242
|
+
return device;
|
|
243
|
+
} else {
|
|
244
|
+
return super.getDevice(nativeId);
|
|
296
245
|
}
|
|
297
|
-
|
|
298
|
-
return device;
|
|
299
246
|
}
|
|
300
247
|
|
|
301
248
|
async getSettings(): Promise<Setting[]> {
|
|
@@ -309,11 +256,7 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
309
256
|
|
|
310
257
|
async releaseDevice(id: string, nativeId: string) {
|
|
311
258
|
this.cameraNativeMap.delete(nativeId);
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
buildNativeId(channel: number): string {
|
|
315
|
-
const { protocol } = this.storageSettings.values;
|
|
316
|
-
return `${this.nativeId}-channel${channel}${protocol === "udp" ? batteryCameraSuffix : cameraSuffix}`;
|
|
259
|
+
super.releaseDevice(id, nativeId);
|
|
317
260
|
}
|
|
318
261
|
|
|
319
262
|
forwardNativeEvent(ev: ReolinkSimpleEvent): void {
|
|
@@ -337,16 +280,14 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
337
280
|
return;
|
|
338
281
|
}
|
|
339
282
|
|
|
340
|
-
|
|
341
|
-
if (camera.onSimpleEvent) {
|
|
342
|
-
camera.onSimpleEvent(ev);
|
|
343
|
-
}
|
|
283
|
+
camera.onSimpleEvent(ev);
|
|
344
284
|
}
|
|
285
|
+
|
|
345
286
|
async unsubscribeFromAllEvents(): Promise<void> {
|
|
346
287
|
await super.unsubscribeFromEvents();
|
|
347
288
|
}
|
|
348
289
|
|
|
349
|
-
|
|
290
|
+
public async runDiagnostics(): Promise<void> {
|
|
350
291
|
const logger = this.getBaichuanLogger();
|
|
351
292
|
logger.log(`Starting Multifocal diagnostics...`);
|
|
352
293
|
|
package/src/nvr.ts
CHANGED
|
@@ -360,7 +360,8 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
360
360
|
this.lastNvrInfoCheck = now;
|
|
361
361
|
const { nvrData } = await api.getNvrInfo();
|
|
362
362
|
const { devicesData, channelsResponse, response } = await api.getDevicesInfo();
|
|
363
|
-
logger.log(`NVR info data fetched
|
|
363
|
+
logger.log(`NVR info data fetched`);
|
|
364
|
+
logger.debug(`${JSON.stringify({ nvrData, devicesData, channelsResponse, response })}`);
|
|
364
365
|
|
|
365
366
|
await this.discoverDevices(true);
|
|
366
367
|
}
|
|
@@ -372,7 +373,6 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
372
373
|
this.forwardCgiEvents(eventsRes.parsed);
|
|
373
374
|
}
|
|
374
375
|
|
|
375
|
-
// Always fetch battery info (not event-related)
|
|
376
376
|
const { batteryInfoData, response } = await api.getAllChannelsBatteryInfo();
|
|
377
377
|
|
|
378
378
|
logger.debug(`Battery info call result: ${JSON.stringify({ batteryInfoData, response })}`);
|
|
@@ -411,9 +411,8 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
411
411
|
device: this,
|
|
412
412
|
ipAddress,
|
|
413
413
|
deviceData,
|
|
414
|
+
logger
|
|
414
415
|
});
|
|
415
|
-
|
|
416
|
-
logger.log(`Device info updated: ${JSON.stringify(deviceData)}`);
|
|
417
416
|
} catch (e) {
|
|
418
417
|
logger.warn('Failed to fetch device info', e);
|
|
419
418
|
}
|
|
@@ -552,7 +551,7 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
552
551
|
}
|
|
553
552
|
}
|
|
554
553
|
|
|
555
|
-
logger.
|
|
554
|
+
logger.debug(`Channel discovery completed. ${JSON.stringify({ devicesData, channels })}`);
|
|
556
555
|
}
|
|
557
556
|
|
|
558
557
|
async discoverDevices(scan?: boolean): Promise<DiscoveredDevice[]> {
|
|
@@ -606,7 +605,8 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
606
605
|
|
|
607
606
|
const device = await this.getDevice(adopt.nativeId);
|
|
608
607
|
const logger = this.getBaichuanLogger();
|
|
609
|
-
logger.log('Adopted device',
|
|
608
|
+
logger.log('Adopted device', device?.name);
|
|
609
|
+
logger.log(JSON.stringify(entry));
|
|
610
610
|
const { username, password, ipAddress } = this.storageSettings.values;
|
|
611
611
|
|
|
612
612
|
device.storageSettings.values.rtspChannel = entry.rtspChannel;
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DeviceCapabilities, ReolinkDeviceInfo } from "@apocaliss92/reolink-baichuan-js" with { "resolution-mode": "import" };
|
|
2
|
-
import { DeviceBase, ScryptedDeviceType, ScryptedInterface } from "@scrypted/sdk";
|
|
2
|
+
import sdk, { Device, DeviceBase, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface } from "@scrypted/sdk";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Enumeration of operation types that may require specific channel assignments
|
|
@@ -23,7 +23,11 @@ export type OperationChannelMap = Partial<Record<OperationChannelType, number>>;
|
|
|
23
23
|
export const nvrSuffix = `-nvr`;
|
|
24
24
|
export const batteryCameraSuffix = `-battery-cam`;
|
|
25
25
|
export const multifocalSuffix = `-multifocal`;
|
|
26
|
+
export const batteryMultifocalSuffix = `-battery-multifocal`;
|
|
26
27
|
export const cameraSuffix = `-cam`;
|
|
28
|
+
export const sirenSuffix = `-siren`;
|
|
29
|
+
export const floodlightSuffix = `-floodlight`;
|
|
30
|
+
export const pirSuffix = `-pir`;
|
|
27
31
|
|
|
28
32
|
export const getDeviceInterfaces = (props: {
|
|
29
33
|
capabilities: DeviceCapabilities,
|
|
@@ -78,9 +82,10 @@ export const getDeviceInterfaces = (props: {
|
|
|
78
82
|
export const updateDeviceInfo = async (props: {
|
|
79
83
|
device: DeviceBase,
|
|
80
84
|
ipAddress: string,
|
|
81
|
-
deviceData: ReolinkDeviceInfo
|
|
85
|
+
deviceData: ReolinkDeviceInfo,
|
|
86
|
+
logger: Console
|
|
82
87
|
}) => {
|
|
83
|
-
const { device, ipAddress, deviceData } = props;
|
|
88
|
+
const { device, ipAddress, deviceData, logger } = props;
|
|
84
89
|
try {
|
|
85
90
|
const info = device.info || {};
|
|
86
91
|
|
|
@@ -101,5 +106,9 @@ export const updateDeviceInfo = async (props: {
|
|
|
101
106
|
device.info = info;
|
|
102
107
|
|
|
103
108
|
throw e;
|
|
109
|
+
} finally {
|
|
110
|
+
|
|
111
|
+
logger.log(`Device info updated`);
|
|
112
|
+
logger.debug(`${JSON.stringify({ newInfo: device.info, deviceData })}`);
|
|
104
113
|
}
|
|
105
114
|
}
|