@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/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/baichuan-base.ts
CHANGED
|
@@ -248,11 +248,10 @@ export abstract class BaseBaichuanClass extends ScryptedDeviceBase {
|
|
|
248
248
|
username: config.username,
|
|
249
249
|
password: config.password,
|
|
250
250
|
uid: config.uid,
|
|
251
|
-
logger
|
|
251
|
+
logger,
|
|
252
252
|
debugOptions: config.debugOptions,
|
|
253
253
|
},
|
|
254
254
|
transport: config.transport,
|
|
255
|
-
logger: logger as Console,
|
|
256
255
|
});
|
|
257
256
|
|
|
258
257
|
await api.login();
|
package/src/camera-battery.ts
CHANGED
|
@@ -374,18 +374,12 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
|
|
|
374
374
|
}
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
-
async withBaichuanRetry<T>(fn: () => Promise<T>): Promise<T> {
|
|
378
|
-
return await fn();
|
|
379
|
-
}
|
|
380
|
-
|
|
381
377
|
protected async withBaichuanClient<T>(fn: (api: ReolinkBaichuanApi) => Promise<T>): Promise<T> {
|
|
382
378
|
const client = await this.ensureClient();
|
|
383
379
|
return fn(client);
|
|
384
380
|
}
|
|
385
381
|
|
|
386
382
|
async createStreamClient(): Promise<ReolinkBaichuanApi> {
|
|
387
|
-
// Reuse the main Baichuan client connection instead of creating a new one
|
|
388
|
-
// This ensures we use a single session for everything (general + streams)
|
|
389
383
|
return await this.ensureClient();
|
|
390
384
|
}
|
|
391
385
|
}
|
package/src/camera.ts
CHANGED
|
@@ -31,8 +31,8 @@ export class ReolinkNativeCamera extends CommonCameraMixin {
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
constructor(
|
|
34
|
-
nativeId: string,
|
|
35
|
-
public plugin: ReolinkNativePlugin,
|
|
34
|
+
nativeId: string,
|
|
35
|
+
public plugin: ReolinkNativePlugin,
|
|
36
36
|
nvrDevice?: ReolinkNativeNvrDevice,
|
|
37
37
|
multiFocalDevice?: ReolinkNativeMultiFocalDevice
|
|
38
38
|
) {
|
|
@@ -67,27 +67,6 @@ export class ReolinkNativeCamera extends CommonCameraMixin {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
async withBaichuanRetry<T>(fn: () => Promise<T>): Promise<T> {
|
|
71
|
-
try {
|
|
72
|
-
return await fn();
|
|
73
|
-
}
|
|
74
|
-
catch (e) {
|
|
75
|
-
if (!this.isRecoverableBaichuanError(e)) {
|
|
76
|
-
throw e;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Reset client and clear cache on recoverable error
|
|
80
|
-
await this.resetBaichuanClient(e);
|
|
81
|
-
|
|
82
|
-
// Important: callers must re-acquire the client inside fn.
|
|
83
|
-
try {
|
|
84
|
-
return await fn();
|
|
85
|
-
} catch (retryError) {
|
|
86
|
-
throw retryError;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
70
|
|
|
92
71
|
async init() {
|
|
93
72
|
this.startPeriodicTasks();
|
|
@@ -97,6 +76,7 @@ export class ReolinkNativeCamera extends CommonCameraMixin {
|
|
|
97
76
|
|
|
98
77
|
async createStreamClient(): Promise<ReolinkBaichuanApi> {
|
|
99
78
|
const { ipAddress, username, password } = this.storageSettings.values;
|
|
79
|
+
const logger = this.getBaichuanLogger();
|
|
100
80
|
|
|
101
81
|
const debugOptions = this.getBaichuanDebugOptions();
|
|
102
82
|
const api = await createBaichuanApi(
|
|
@@ -105,11 +85,10 @@ export class ReolinkNativeCamera extends CommonCameraMixin {
|
|
|
105
85
|
host: ipAddress,
|
|
106
86
|
username: username,
|
|
107
87
|
password: password,
|
|
108
|
-
logger
|
|
88
|
+
logger,
|
|
109
89
|
debugOptions
|
|
110
90
|
},
|
|
111
91
|
transport: 'tcp',
|
|
112
|
-
logger: this.console,
|
|
113
92
|
},
|
|
114
93
|
);
|
|
115
94
|
await api.login();
|
package/src/common.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { DeviceCapabilities, PtzCommand, PtzPreset, ReolinkBaichuanApi, ReolinkSimpleEvent, ReolinkSupportedStream, StreamSamplingSelection } from "@apocaliss92/reolink-baichuan-js" with { "resolution-mode": "import" };
|
|
2
2
|
import sdk, { BinarySensor, Brightness, Camera, Device, DeviceProvider, Intercom, MediaObject, MediaStreamUrl, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, OnOff, PanTiltZoom, PanTiltZoomCommand, RequestMediaStreamOptions, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera, VideoTextOverlay, VideoTextOverlays } from "@scrypted/sdk";
|
|
3
3
|
import { StorageSettings } from "@scrypted/sdk/storage-settings";
|
|
4
|
+
import path from 'path';
|
|
4
5
|
import type { UrlMediaStreamOptions } from "../../scrypted/plugins/rtsp/src/rtsp";
|
|
5
6
|
import { BaseBaichuanClass, type BaichuanConnectionCallbacks, type BaichuanConnectionConfig } from "./baichuan-base";
|
|
6
7
|
import { normalizeUid, type BaichuanTransport } from "./connect";
|
|
7
8
|
import { convertDebugLogsToApiOptions, DebugLogDisplayNames, DebugLogOption, getApiRelevantDebugLogs, getDebugLogChoices } from "./debug-options";
|
|
8
9
|
import { ReolinkBaichuanIntercom } from "./intercom";
|
|
9
10
|
import ReolinkNativePlugin from "./main";
|
|
10
|
-
import { ReolinkNativeNvrDevice } from "./nvr";
|
|
11
11
|
import { ReolinkNativeMultiFocalDevice } from "./multiFocal";
|
|
12
|
+
import { ReolinkNativeNvrDevice } from "./nvr";
|
|
12
13
|
import { ReolinkPtzPresets } from "./presets";
|
|
13
14
|
import {
|
|
14
15
|
createRfc4571MediaObjectFromStreamManager,
|
|
@@ -17,10 +18,9 @@ import {
|
|
|
17
18
|
selectStreamOption,
|
|
18
19
|
StreamManager
|
|
19
20
|
} from "./stream-utils";
|
|
20
|
-
import { getDeviceInterfaces, updateDeviceInfo } from "./utils";
|
|
21
|
-
import path from 'path';
|
|
21
|
+
import { floodlightSuffix, getDeviceInterfaces, pirSuffix, sirenSuffix, updateDeviceInfo } from "./utils";
|
|
22
22
|
|
|
23
|
-
export type CameraType = 'battery' | 'regular';
|
|
23
|
+
export type CameraType = 'battery' | 'regular' | 'multi-focal' | 'multi-focal-battery';
|
|
24
24
|
|
|
25
25
|
export interface CommonCameraMixinOptions {
|
|
26
26
|
type: CameraType;
|
|
@@ -197,6 +197,12 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
197
197
|
await this.credentialsChanged();
|
|
198
198
|
}
|
|
199
199
|
},
|
|
200
|
+
debugEvents: {
|
|
201
|
+
title: 'Debug Events',
|
|
202
|
+
type: 'boolean',
|
|
203
|
+
immediate: true,
|
|
204
|
+
hide: true,
|
|
205
|
+
},
|
|
200
206
|
username: {
|
|
201
207
|
type: 'string',
|
|
202
208
|
title: 'Username',
|
|
@@ -220,7 +226,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
220
226
|
json: true,
|
|
221
227
|
hide: true,
|
|
222
228
|
},
|
|
223
|
-
|
|
229
|
+
multifocalInfo: {
|
|
224
230
|
json: true,
|
|
225
231
|
hide: true,
|
|
226
232
|
},
|
|
@@ -515,7 +521,6 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
515
521
|
// Abstract init method that subclasses must implement
|
|
516
522
|
abstract init(): Promise<void>;
|
|
517
523
|
|
|
518
|
-
abstract withBaichuanRetry<T>(fn: () => Promise<T>): Promise<T>;
|
|
519
524
|
protected withBaichuanClient?<T>(fn: (api: ReolinkBaichuanApi) => Promise<T>): Promise<T>;
|
|
520
525
|
motionTimeout?: NodeJS.Timeout;
|
|
521
526
|
doorbellBinaryTimeout?: NodeJS.Timeout;
|
|
@@ -532,13 +537,15 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
532
537
|
public options: CommonCameraMixinOptions
|
|
533
538
|
) {
|
|
534
539
|
super(nativeId);
|
|
535
|
-
this.protocol = !options.nvrDevice && !options.multiFocalDevice && options.type === 'battery' ? 'udp' : 'tcp';
|
|
536
540
|
|
|
537
541
|
// Store NVR device reference if provided
|
|
538
542
|
this.nvrDevice = options.nvrDevice;
|
|
539
543
|
this.multiFocalDevice = options.multiFocalDevice;
|
|
540
544
|
this.thisDevice = sdk.systemManager.getDeviceById<Settings>(this.id);
|
|
541
545
|
|
|
546
|
+
const isBattery = options.type === 'battery' || options.type === 'multi-focal-battery';
|
|
547
|
+
this.protocol = isBattery ? 'udp' : 'tcp';
|
|
548
|
+
|
|
542
549
|
setTimeout(async () => {
|
|
543
550
|
await this.parentInit();
|
|
544
551
|
}, 2000);
|
|
@@ -601,7 +608,31 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
601
608
|
return this.name || 'Camera';
|
|
602
609
|
}
|
|
603
610
|
|
|
604
|
-
|
|
611
|
+
async withBaichuanRetry<T>(fn: () => Promise<T>): Promise<T> {
|
|
612
|
+
if (this.protocol === 'udp') {
|
|
613
|
+
return await fn();
|
|
614
|
+
} else {
|
|
615
|
+
try {
|
|
616
|
+
return await fn();
|
|
617
|
+
} catch (e) {
|
|
618
|
+
if (!this.isRecoverableBaichuanError(e)) {
|
|
619
|
+
throw e;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Reset client and clear cache on recoverable error
|
|
623
|
+
await this.resetBaichuanClient(e);
|
|
624
|
+
|
|
625
|
+
// Important: callers must re-acquire the client inside fn.
|
|
626
|
+
try {
|
|
627
|
+
return await fn();
|
|
628
|
+
} catch (retryError) {
|
|
629
|
+
throw retryError;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
async runDiagnostics(): Promise<void> {
|
|
605
636
|
const logger = this.getBaichuanLogger();
|
|
606
637
|
const outputPath = this.storageSettings.values.diagnosticsOutputPath || process.env.SCRYPTED_PLUGIN_VOLUME || "";
|
|
607
638
|
|
|
@@ -654,8 +685,8 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
654
685
|
}
|
|
655
686
|
|
|
656
687
|
public getAbilities(): DeviceCapabilities {
|
|
657
|
-
if (this.
|
|
658
|
-
return this.
|
|
688
|
+
if (this.multiFocalDevice) {
|
|
689
|
+
return this.multiFocalDevice.getInterfaces(this.storageSettings.values.rtspChannel).capabilities;
|
|
659
690
|
} else {
|
|
660
691
|
return this.storageSettings.values.capabilities;
|
|
661
692
|
}
|
|
@@ -690,9 +721,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
690
721
|
|
|
691
722
|
// Event subscription methods
|
|
692
723
|
unsubscribedToEvents(): void {
|
|
693
|
-
// Use base class unsubscribe
|
|
694
724
|
this.unsubscribeFromEvents().catch(() => {
|
|
695
|
-
// ignore
|
|
696
725
|
});
|
|
697
726
|
|
|
698
727
|
if (this.motionDetected) {
|
|
@@ -1024,20 +1053,17 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1024
1053
|
this.binaryState = false;
|
|
1025
1054
|
}
|
|
1026
1055
|
|
|
1027
|
-
// Report devices (siren, floodlight, PIR)
|
|
1028
1056
|
async reportDevices(): Promise<void> {
|
|
1029
|
-
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1057
|
+
const abilities = this.getAbilities();
|
|
1032
1058
|
|
|
1033
|
-
const { hasSiren, hasFloodlight, hasPir } =
|
|
1059
|
+
const { hasSiren, hasFloodlight, hasPir } = abilities;
|
|
1034
1060
|
|
|
1035
1061
|
const devices: Device[] = [];
|
|
1036
1062
|
|
|
1037
1063
|
if (hasSiren) {
|
|
1038
|
-
const sirenNativeId = `${this.nativeId}
|
|
1064
|
+
const sirenNativeId = `${this.nativeId}${sirenSuffix}`;
|
|
1039
1065
|
devices.push({
|
|
1040
|
-
providerNativeId: this.
|
|
1066
|
+
providerNativeId: this.nativeId,
|
|
1041
1067
|
name: `${this.name} Siren`,
|
|
1042
1068
|
nativeId: sirenNativeId,
|
|
1043
1069
|
info: {
|
|
@@ -1049,9 +1075,9 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1049
1075
|
}
|
|
1050
1076
|
|
|
1051
1077
|
if (hasFloodlight) {
|
|
1052
|
-
const floodlightNativeId = `${this.nativeId}
|
|
1078
|
+
const floodlightNativeId = `${this.nativeId}${floodlightSuffix}`;
|
|
1053
1079
|
devices.push({
|
|
1054
|
-
providerNativeId: this.
|
|
1080
|
+
providerNativeId: this.nativeId,
|
|
1055
1081
|
name: `${this.name} Floodlight`,
|
|
1056
1082
|
nativeId: floodlightNativeId,
|
|
1057
1083
|
info: {
|
|
@@ -1063,9 +1089,9 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1063
1089
|
}
|
|
1064
1090
|
|
|
1065
1091
|
if (hasPir) {
|
|
1066
|
-
const pirNativeId = `${this.nativeId}
|
|
1092
|
+
const pirNativeId = `${this.nativeId}${pirSuffix}`;
|
|
1067
1093
|
devices.push({
|
|
1068
|
-
providerNativeId: this.
|
|
1094
|
+
providerNativeId: this.nativeId,
|
|
1069
1095
|
name: `${this.name} PIR`,
|
|
1070
1096
|
nativeId: pirNativeId,
|
|
1071
1097
|
info: {
|
|
@@ -1116,8 +1142,8 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1116
1142
|
async updateDeviceInfo(): Promise<void> {
|
|
1117
1143
|
const logger = this.getBaichuanLogger();
|
|
1118
1144
|
|
|
1119
|
-
if (this.
|
|
1120
|
-
this.info = this.
|
|
1145
|
+
if (this.multiFocalDevice) {
|
|
1146
|
+
this.info = this.multiFocalDevice.info;
|
|
1121
1147
|
return;
|
|
1122
1148
|
}
|
|
1123
1149
|
|
|
@@ -1130,9 +1156,9 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1130
1156
|
device: this,
|
|
1131
1157
|
ipAddress,
|
|
1132
1158
|
deviceData,
|
|
1159
|
+
logger,
|
|
1133
1160
|
});
|
|
1134
1161
|
|
|
1135
|
-
logger.log(`Device info updated: ${JSON.stringify(deviceData)}`);
|
|
1136
1162
|
} catch (e) {
|
|
1137
1163
|
logger.warn('Failed to fetch device info', e);
|
|
1138
1164
|
}
|
|
@@ -1140,24 +1166,24 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1140
1166
|
|
|
1141
1167
|
// Device provider methods
|
|
1142
1168
|
async getDevice(nativeId: string): Promise<any> {
|
|
1143
|
-
if (nativeId.endsWith(
|
|
1169
|
+
if (nativeId.endsWith(sirenSuffix)) {
|
|
1144
1170
|
this.siren ||= new ReolinkCameraSiren(this, nativeId);
|
|
1145
1171
|
return this.siren;
|
|
1146
|
-
} else if (nativeId.endsWith(
|
|
1172
|
+
} else if (nativeId.endsWith(floodlightSuffix)) {
|
|
1147
1173
|
this.floodlight ||= new ReolinkCameraFloodlight(this, nativeId);
|
|
1148
1174
|
return this.floodlight;
|
|
1149
|
-
} else if (nativeId.endsWith(
|
|
1175
|
+
} else if (nativeId.endsWith(pirSuffix)) {
|
|
1150
1176
|
this.pirSensor ||= new ReolinkCameraPirSensor(this, nativeId);
|
|
1151
1177
|
return this.pirSensor;
|
|
1152
1178
|
}
|
|
1153
1179
|
}
|
|
1154
1180
|
|
|
1155
1181
|
async releaseDevice(id: string, nativeId: string): Promise<void> {
|
|
1156
|
-
if (nativeId.endsWith(
|
|
1182
|
+
if (nativeId.endsWith(sirenSuffix)) {
|
|
1157
1183
|
this.siren = undefined;
|
|
1158
|
-
} else if (nativeId.endsWith(
|
|
1184
|
+
} else if (nativeId.endsWith(floodlightSuffix)) {
|
|
1159
1185
|
this.floodlight = undefined;
|
|
1160
|
-
} else if (nativeId.endsWith(
|
|
1186
|
+
} else if (nativeId.endsWith(pirSuffix)) {
|
|
1161
1187
|
this.pirSensor = undefined;
|
|
1162
1188
|
}
|
|
1163
1189
|
}
|
|
@@ -1357,7 +1383,8 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1357
1383
|
}
|
|
1358
1384
|
|
|
1359
1385
|
if (streams.length) {
|
|
1360
|
-
logger.log('Fetched video stream options',
|
|
1386
|
+
logger.log('Fetched video stream options', streams.map((s) => s.name).join(', '));
|
|
1387
|
+
logger.debug(JSON.stringify(streams));
|
|
1361
1388
|
this.cachedVideoStreamOptions = streams;
|
|
1362
1389
|
return streams;
|
|
1363
1390
|
}
|
|
@@ -1451,41 +1478,41 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1451
1478
|
const channel = this.storageSettings.values.rtspChannel;
|
|
1452
1479
|
|
|
1453
1480
|
try {
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1481
|
+
const { capabilities, abilities, support, presets, objects } = await this.withBaichuanRetry(async () => {
|
|
1482
|
+
const api = await this.ensureClient();
|
|
1483
|
+
return await api.getDeviceCapabilities(channel);
|
|
1484
|
+
});
|
|
1485
|
+
this.classes = objects;
|
|
1486
|
+
this.presets = presets;
|
|
1487
|
+
this.ptzPresets.setCachedPtzPresets(presets);
|
|
1488
|
+
|
|
1489
|
+
try {
|
|
1490
|
+
const { interfaces, type } = getDeviceInterfaces({
|
|
1491
|
+
capabilities,
|
|
1492
|
+
logger: this.console,
|
|
1460
1493
|
});
|
|
1461
|
-
this.classes = objects;
|
|
1462
|
-
this.presets = presets;
|
|
1463
|
-
this.ptzPresets.setCachedPtzPresets(presets);
|
|
1464
1494
|
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
info: this.info,
|
|
1478
|
-
};
|
|
1479
|
-
|
|
1480
|
-
logger.log(`Updating device interfaces: ${JSON.stringify(device)}`);
|
|
1481
|
-
|
|
1482
|
-
await sdk.deviceManager.onDeviceDiscovered(device);
|
|
1483
|
-
} catch (e) {
|
|
1484
|
-
logger.error('Failed to update device interfaces', e);
|
|
1485
|
-
}
|
|
1495
|
+
const device: Device = {
|
|
1496
|
+
nativeId: this.nativeId,
|
|
1497
|
+
providerNativeId: this.nvrDevice?.nativeId ??
|
|
1498
|
+
this.multiFocalDevice?.nativeId ??
|
|
1499
|
+
this.plugin?.nativeId,
|
|
1500
|
+
name: this.name,
|
|
1501
|
+
interfaces,
|
|
1502
|
+
type,
|
|
1503
|
+
info: this.info,
|
|
1504
|
+
};
|
|
1505
|
+
|
|
1506
|
+
await sdk.deviceManager.onDeviceDiscovered(device);
|
|
1486
1507
|
|
|
1487
|
-
logger.log(`
|
|
1508
|
+
logger.log(`Device interfaces updated`);
|
|
1509
|
+
logger.debug(`${JSON.stringify(device)}`);
|
|
1510
|
+
} catch (e) {
|
|
1511
|
+
logger.error('Failed to update device interfaces', e);
|
|
1488
1512
|
}
|
|
1513
|
+
|
|
1514
|
+
logger.log(`Refreshed device capabilities: ${JSON.stringify(capabilities)}`);
|
|
1515
|
+
logger.debug(`Refreshed device capabilities: ${JSON.stringify({ abilities, support, presets, objects })}`);
|
|
1489
1516
|
}
|
|
1490
1517
|
catch (e) {
|
|
1491
1518
|
logger.error('Failed to refresh abilities', e);
|
|
@@ -1505,65 +1532,28 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1505
1532
|
logger.warn('Failed to update device info during init', e);
|
|
1506
1533
|
}
|
|
1507
1534
|
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
await this.reportDevices();
|
|
1517
|
-
}
|
|
1518
|
-
catch (e) {
|
|
1519
|
-
logger.warn('Failed to report devices during init', e);
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
const { hasIntercom, hasPtz } = this.getAbilities();
|
|
1523
|
-
|
|
1524
|
-
if (hasIntercom) {
|
|
1525
|
-
this.intercom = new ReolinkBaichuanIntercom(this);
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
if (hasPtz) {
|
|
1529
|
-
const choices = (this.presets || []).map((preset: any) => preset.id + '=' + preset.name);
|
|
1530
|
-
|
|
1531
|
-
this.storageSettings.settings.presets.choices = choices;
|
|
1532
|
-
this.storageSettings.settings.ptzSelectedPreset.choices = choices;
|
|
1533
|
-
|
|
1534
|
-
this.storageSettings.settings.presets.hide = false;
|
|
1535
|
-
this.storageSettings.settings.ptzMoveDurationMs.hide = false;
|
|
1536
|
-
this.storageSettings.settings.ptzZoomStep.hide = false;
|
|
1537
|
-
this.storageSettings.settings.ptzCreatePreset.hide = false;
|
|
1538
|
-
this.storageSettings.settings.ptzSelectedPreset.hide = false;
|
|
1539
|
-
this.storageSettings.settings.ptzUpdateSelectedPreset.hide = false;
|
|
1540
|
-
this.storageSettings.settings.ptzDeleteSelectedPreset.hide = false;
|
|
1541
|
-
|
|
1542
|
-
this.updatePtzCaps();
|
|
1535
|
+
if (!this.multiFocalDevice) {
|
|
1536
|
+
try {
|
|
1537
|
+
await this.refreshDeviceState();
|
|
1538
|
+
await this.reportDevices();
|
|
1539
|
+
}
|
|
1540
|
+
catch (e) {
|
|
1541
|
+
logger.warn('Failed to connect/refresh during init', e);
|
|
1542
|
+
}
|
|
1543
1543
|
}
|
|
1544
1544
|
|
|
1545
|
-
const isBattery = this.options.type === 'battery';
|
|
1546
1545
|
const { username, password } = this.storageSettings.values;
|
|
1546
|
+
const isCamera = this.options.type === 'regular' || this.options.type === 'battery';
|
|
1547
|
+
const isBatteryCamera = this.options.type === 'battery';
|
|
1548
|
+
const isBatteryMultiFocal = this.options.type === 'multi-focal-battery';
|
|
1549
|
+
const isBattery = isBatteryCamera || isBatteryMultiFocal;
|
|
1547
1550
|
|
|
1548
|
-
this.streamManager = new StreamManager({
|
|
1549
|
-
createStreamClient: () => this.createStreamClient(),
|
|
1550
|
-
getLogger: () => logger as Console,
|
|
1551
|
-
credentials: {
|
|
1552
|
-
username,
|
|
1553
|
-
password
|
|
1554
|
-
},
|
|
1555
|
-
// For battery cameras, we use a shared connection
|
|
1556
|
-
sharedConnection: isBattery,
|
|
1557
|
-
});
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
// this.storageSettings.settings.snapshotCacheMinutes.hide = !isBattery;
|
|
1561
1551
|
this.storageSettings.settings.uid.hide = !isBattery;
|
|
1562
1552
|
this.storageSettings.settings.batteryUpdateIntervalMinutes.hide = !isBattery;
|
|
1563
1553
|
this.storageSettings.settings.lowThresholdBatteryRecording.hide = !isBattery;
|
|
1564
1554
|
this.storageSettings.settings.highThresholdBatteryRecording.hide = !isBattery;
|
|
1565
1555
|
|
|
1566
|
-
if (
|
|
1556
|
+
if (isBatteryCamera && !this.storageSettings.values.mixinsSetup) {
|
|
1567
1557
|
try {
|
|
1568
1558
|
const device = sdk.systemManager.getDeviceById<Settings>(this.id);
|
|
1569
1559
|
if (device) {
|
|
@@ -1585,30 +1575,54 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1585
1575
|
logger.warn('Failed to subscribe to Baichuan events', e);
|
|
1586
1576
|
}
|
|
1587
1577
|
|
|
1578
|
+
if (isCamera) {
|
|
1579
|
+
this.streamManager = new StreamManager({
|
|
1580
|
+
createStreamClient: () => this.createStreamClient(),
|
|
1581
|
+
getLogger: () => logger as Console,
|
|
1582
|
+
credentials: {
|
|
1583
|
+
username,
|
|
1584
|
+
password
|
|
1585
|
+
},
|
|
1586
|
+
sharedConnection: isBattery,
|
|
1587
|
+
});
|
|
1588
|
+
|
|
1589
|
+
const { hasIntercom, hasPtz } = this.getAbilities();
|
|
1588
1590
|
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
this.storageSettings.settings.ipAddress.hide = true;
|
|
1593
|
-
this.storageSettings.settings.uid.hide = true;
|
|
1591
|
+
if (hasIntercom) {
|
|
1592
|
+
this.intercom = new ReolinkBaichuanIntercom(this);
|
|
1593
|
+
}
|
|
1594
1594
|
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1595
|
+
if (hasPtz) {
|
|
1596
|
+
const choices = (this.presets || []).map((preset: any) => preset.id + '=' + preset.name);
|
|
1597
|
+
|
|
1598
|
+
this.storageSettings.settings.presets.choices = choices;
|
|
1599
|
+
this.storageSettings.settings.ptzSelectedPreset.choices = choices;
|
|
1600
|
+
|
|
1601
|
+
this.storageSettings.settings.presets.hide = false;
|
|
1602
|
+
this.storageSettings.settings.ptzMoveDurationMs.hide = false;
|
|
1603
|
+
this.storageSettings.settings.ptzZoomStep.hide = false;
|
|
1604
|
+
this.storageSettings.settings.ptzCreatePreset.hide = false;
|
|
1605
|
+
this.storageSettings.settings.ptzSelectedPreset.hide = false;
|
|
1606
|
+
this.storageSettings.settings.ptzUpdateSelectedPreset.hide = false;
|
|
1607
|
+
this.storageSettings.settings.ptzDeleteSelectedPreset.hide = false;
|
|
1608
|
+
|
|
1609
|
+
this.updatePtzCaps();
|
|
1610
|
+
}
|
|
1598
1611
|
}
|
|
1599
1612
|
|
|
1600
|
-
if (this.multiFocalDevice) {
|
|
1613
|
+
if (this.nvrDevice || this.multiFocalDevice) {
|
|
1601
1614
|
this.storageSettings.settings.username.hide = true;
|
|
1602
1615
|
this.storageSettings.settings.password.hide = true;
|
|
1603
1616
|
this.storageSettings.settings.ipAddress.hide = true;
|
|
1604
1617
|
this.storageSettings.settings.uid.hide = true;
|
|
1605
1618
|
|
|
1606
|
-
this.storageSettings.settings.username.defaultValue = this.
|
|
1607
|
-
this.storageSettings.settings.password.defaultValue = this.
|
|
1608
|
-
this.storageSettings.settings.ipAddress.defaultValue = this.
|
|
1619
|
+
this.storageSettings.settings.username.defaultValue = this.nvrDevice.storageSettings.values.username;
|
|
1620
|
+
this.storageSettings.settings.password.defaultValue = this.nvrDevice.storageSettings.values.password;
|
|
1621
|
+
this.storageSettings.settings.ipAddress.defaultValue = this.nvrDevice.storageSettings.values.ipAddress;
|
|
1609
1622
|
}
|
|
1610
1623
|
|
|
1611
1624
|
await this.init();
|
|
1625
|
+
|
|
1612
1626
|
this.initComplete = true;
|
|
1613
1627
|
}
|
|
1614
1628
|
}
|
package/src/connect.ts
CHANGED
|
@@ -19,16 +19,16 @@ export function normalizeUid(uid?: string): string | undefined {
|
|
|
19
19
|
export async function createBaichuanApi(props: {
|
|
20
20
|
inputs: BaichuanConnectInputs,
|
|
21
21
|
transport: BaichuanTransport,
|
|
22
|
-
logger: Console,
|
|
23
22
|
}): Promise<ReolinkBaichuanApi> {
|
|
24
|
-
const { inputs, transport
|
|
23
|
+
const { inputs, transport } = props;
|
|
24
|
+
const { logger } = inputs;
|
|
25
25
|
const { ReolinkBaichuanApi } = await import("@apocaliss92/reolink-baichuan-js");
|
|
26
26
|
|
|
27
27
|
const base: BaichuanClientOptions = {
|
|
28
28
|
host: inputs.host,
|
|
29
29
|
username: inputs.username,
|
|
30
30
|
password: inputs.password,
|
|
31
|
-
logger
|
|
31
|
+
logger,
|
|
32
32
|
debugOptions: inputs.debugOptions ?? {}
|
|
33
33
|
};
|
|
34
34
|
|