@apocaliss92/scrypted-reolink-native 0.1.15 → 0.1.16
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/common.ts +33 -18
- package/src/nvr.ts +18 -18
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/common.ts
CHANGED
|
@@ -263,6 +263,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
263
263
|
defaultValue: [],
|
|
264
264
|
choices: getDebugLogChoices(),
|
|
265
265
|
onPut: async (ov, value) => {
|
|
266
|
+
const logger = this.getBaichuanLogger();
|
|
266
267
|
const oldApiOptions = getApiRelevantDebugLogs(ov || []);
|
|
267
268
|
const newApiOptions = getApiRelevantDebugLogs(value || []);
|
|
268
269
|
|
|
@@ -288,7 +289,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
288
289
|
// Trigger reconnection
|
|
289
290
|
await this.ensureClient();
|
|
290
291
|
} catch (e) {
|
|
291
|
-
|
|
292
|
+
logger.warn('Failed to reset client after debug logs change', e);
|
|
292
293
|
}
|
|
293
294
|
}, 2000);
|
|
294
295
|
}
|
|
@@ -691,6 +692,8 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
691
692
|
}
|
|
692
693
|
|
|
693
694
|
onSimpleEvent = (ev: ReolinkSimpleEvent) => {
|
|
695
|
+
const logger = this.getBaichuanLogger();
|
|
696
|
+
|
|
694
697
|
try {
|
|
695
698
|
const logger = this.getBaichuanLogger();
|
|
696
699
|
|
|
@@ -737,7 +740,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
737
740
|
});
|
|
738
741
|
}
|
|
739
742
|
catch (e) {
|
|
740
|
-
|
|
743
|
+
logger.warn('Error in onSimpleEvent handler', e);
|
|
741
744
|
}
|
|
742
745
|
}
|
|
743
746
|
|
|
@@ -832,6 +835,8 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
832
835
|
|
|
833
836
|
// PanTiltZoom interface implementation
|
|
834
837
|
async ptzCommand(command: PanTiltZoomCommand): Promise<void> {
|
|
838
|
+
const logger = this.getBaichuanLogger();
|
|
839
|
+
|
|
835
840
|
const client = await this.ensureClient();
|
|
836
841
|
if (!client) {
|
|
837
842
|
return;
|
|
@@ -844,13 +849,13 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
844
849
|
if (preset !== undefined && preset !== null) {
|
|
845
850
|
const presetId = Number(preset);
|
|
846
851
|
if (!Number.isFinite(presetId)) {
|
|
847
|
-
|
|
852
|
+
logger.warn(`Invalid PTZ preset id: ${preset}`);
|
|
848
853
|
return;
|
|
849
854
|
}
|
|
850
855
|
if (this.ptzPresets) {
|
|
851
856
|
await this.ptzPresets.moveToPreset(presetId);
|
|
852
857
|
} else {
|
|
853
|
-
|
|
858
|
+
logger.warn('PTZ presets not available');
|
|
854
859
|
}
|
|
855
860
|
return;
|
|
856
861
|
}
|
|
@@ -885,14 +890,14 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
885
890
|
|
|
886
891
|
const step = Number(this.storageSettings.values.ptzZoomStep);
|
|
887
892
|
if (!Number.isFinite(step) || step <= 0) {
|
|
888
|
-
|
|
893
|
+
logger.warn('Invalid PTZ zoom step, using default 0.1');
|
|
889
894
|
return;
|
|
890
895
|
}
|
|
891
896
|
|
|
892
897
|
// Get current zoom factor and apply step
|
|
893
898
|
const info = await client.getZoomFocus(channel);
|
|
894
899
|
if (!info?.zoom) {
|
|
895
|
-
|
|
900
|
+
logger.warn('Zoom command requested but camera did not report zoom support.');
|
|
896
901
|
return;
|
|
897
902
|
}
|
|
898
903
|
|
|
@@ -1100,6 +1105,8 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1100
1105
|
}
|
|
1101
1106
|
|
|
1102
1107
|
async updateDeviceInfo(): Promise<void> {
|
|
1108
|
+
const logger = this.getBaichuanLogger();
|
|
1109
|
+
|
|
1103
1110
|
const { ipAddress, rtspChannel } = this.storageSettings.values;
|
|
1104
1111
|
try {
|
|
1105
1112
|
const api = await this.ensureClient();
|
|
@@ -1110,8 +1117,10 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1110
1117
|
ipAddress,
|
|
1111
1118
|
deviceData,
|
|
1112
1119
|
});
|
|
1120
|
+
|
|
1121
|
+
logger.log(`Device info updated: ${JSON.stringify(deviceData)}`);
|
|
1113
1122
|
} catch (e) {
|
|
1114
|
-
|
|
1123
|
+
logger.warn('Failed to fetch device info', e);
|
|
1115
1124
|
}
|
|
1116
1125
|
}
|
|
1117
1126
|
|
|
@@ -1187,6 +1196,8 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1187
1196
|
* This should be called periodically for regular cameras and once when battery cameras wake up.
|
|
1188
1197
|
*/
|
|
1189
1198
|
async alignAuxDevicesState(): Promise<void> {
|
|
1199
|
+
const logger = this.getBaichuanLogger();
|
|
1200
|
+
|
|
1190
1201
|
const api = this.baichuanApi;
|
|
1191
1202
|
if (!api) return;
|
|
1192
1203
|
|
|
@@ -1200,7 +1211,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1200
1211
|
const sirenState = await api.getSiren(channel);
|
|
1201
1212
|
this.siren.on = sirenState.enabled;
|
|
1202
1213
|
} catch (e) {
|
|
1203
|
-
|
|
1214
|
+
logger.debug('Failed to align siren state', e);
|
|
1204
1215
|
}
|
|
1205
1216
|
}
|
|
1206
1217
|
|
|
@@ -1213,7 +1224,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1213
1224
|
this.floodlight.brightness = wl.brightness;
|
|
1214
1225
|
}
|
|
1215
1226
|
} catch (e) {
|
|
1216
|
-
|
|
1227
|
+
logger.debug('Failed to align floodlight state', e);
|
|
1217
1228
|
}
|
|
1218
1229
|
}
|
|
1219
1230
|
|
|
@@ -1237,16 +1248,18 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1237
1248
|
}
|
|
1238
1249
|
}
|
|
1239
1250
|
} catch (e) {
|
|
1240
|
-
|
|
1251
|
+
logger.debug('Failed to align PIR state', e);
|
|
1241
1252
|
}
|
|
1242
1253
|
}
|
|
1243
1254
|
} catch (e) {
|
|
1244
|
-
|
|
1255
|
+
logger.debug('Failed to align auxiliary devices state', e);
|
|
1245
1256
|
}
|
|
1246
1257
|
}
|
|
1247
1258
|
|
|
1248
1259
|
// Video stream helper methods
|
|
1249
1260
|
protected addRtspCredentials(rtspUrl: string): string {
|
|
1261
|
+
const logger = this.getBaichuanLogger();
|
|
1262
|
+
|
|
1250
1263
|
const { username, password } = this.storageSettings.values;
|
|
1251
1264
|
if (!username) {
|
|
1252
1265
|
return rtspUrl;
|
|
@@ -1271,7 +1284,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1271
1284
|
return url.toString();
|
|
1272
1285
|
} catch (e) {
|
|
1273
1286
|
// If URL parsing fails, return original URL
|
|
1274
|
-
|
|
1287
|
+
logger.warn('Failed to parse URL for credentials', e);
|
|
1275
1288
|
return rtspUrl;
|
|
1276
1289
|
}
|
|
1277
1290
|
}
|
|
@@ -1289,6 +1302,8 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1289
1302
|
}
|
|
1290
1303
|
|
|
1291
1304
|
protected async ensureNetPortCache(): Promise<void> {
|
|
1305
|
+
const logger = this.getBaichuanLogger();
|
|
1306
|
+
|
|
1292
1307
|
if (this.cachedNetPort) {
|
|
1293
1308
|
return;
|
|
1294
1309
|
}
|
|
@@ -1312,7 +1327,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1312
1327
|
} catch (e) {
|
|
1313
1328
|
// Only log if it's not a recoverable error to avoid spam
|
|
1314
1329
|
if (!this.isRecoverableBaichuanError?.(e)) {
|
|
1315
|
-
|
|
1330
|
+
logger.warn('Failed to get net port, using defaults', e);
|
|
1316
1331
|
}
|
|
1317
1332
|
// Use defaults if we can't get the ports
|
|
1318
1333
|
this.cachedNetPort = {
|
|
@@ -1368,7 +1383,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1368
1383
|
}
|
|
1369
1384
|
|
|
1370
1385
|
if (streams.length) {
|
|
1371
|
-
|
|
1386
|
+
logger.log('Fetched video stream options', { streams, netPort: this.cachedNetPort });
|
|
1372
1387
|
this.cachedVideoStreamOptions = streams;
|
|
1373
1388
|
return streams;
|
|
1374
1389
|
}
|
|
@@ -1497,14 +1512,14 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1497
1512
|
info: this.info,
|
|
1498
1513
|
};
|
|
1499
1514
|
|
|
1500
|
-
|
|
1515
|
+
logger.log(`Updating device interfaces: ${JSON.stringify(device)}`);
|
|
1501
1516
|
|
|
1502
1517
|
await sdk.deviceManager.onDeviceDiscovered(device);
|
|
1503
1518
|
} catch (e) {
|
|
1504
|
-
|
|
1519
|
+
logger.error('Failed to update device interfaces', e);
|
|
1505
1520
|
}
|
|
1506
1521
|
|
|
1507
|
-
|
|
1522
|
+
logger.log(`Refreshed device capabilities: ${JSON.stringify({ capabilities, abilities, support, presets })}`);
|
|
1508
1523
|
}
|
|
1509
1524
|
catch (e) {
|
|
1510
1525
|
logger.error('Failed to refresh abilities', e);
|
|
@@ -1566,7 +1581,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
|
|
|
1566
1581
|
|
|
1567
1582
|
this.streamManager = new StreamManager({
|
|
1568
1583
|
createStreamClient: () => this.createStreamClient(),
|
|
1569
|
-
getLogger: () =>
|
|
1584
|
+
getLogger: () => logger as Console,
|
|
1570
1585
|
credentials: {
|
|
1571
1586
|
username,
|
|
1572
1587
|
password
|
package/src/nvr.ts
CHANGED
|
@@ -53,7 +53,7 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
53
53
|
rtspChannel: number;
|
|
54
54
|
deviceData: DeviceInfoResponse;
|
|
55
55
|
}>();
|
|
56
|
-
|
|
56
|
+
lastNvrInfoCheck: number | undefined;
|
|
57
57
|
lastErrorsCheck: number | undefined;
|
|
58
58
|
lastDevicesStatusCheck: number | undefined;
|
|
59
59
|
cameraNativeMap = new Map<string, ReolinkNativeCamera | ReolinkNativeBatteryCamera>();
|
|
@@ -169,7 +169,7 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
169
169
|
// Find camera for this channel
|
|
170
170
|
const channel = ev?.channel;
|
|
171
171
|
if (channel === undefined) {
|
|
172
|
-
logger.
|
|
172
|
+
logger.error('Event has no channel, ignoring');
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
175
175
|
|
|
@@ -177,7 +177,7 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
177
177
|
const targetCamera = nativeId ? this.cameraNativeMap.get(nativeId) : undefined;
|
|
178
178
|
|
|
179
179
|
if (!targetCamera) {
|
|
180
|
-
logger.
|
|
180
|
+
logger.error(`No camera found for channel ${channel}, ignoring event`);
|
|
181
181
|
return;
|
|
182
182
|
}
|
|
183
183
|
|
|
@@ -211,7 +211,7 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
211
211
|
motion = true;
|
|
212
212
|
break;
|
|
213
213
|
default:
|
|
214
|
-
logger.
|
|
214
|
+
logger.error(`Unknown event type: ${ev?.type}`);
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
217
|
|
|
@@ -309,13 +309,12 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
309
309
|
// Note: ReolinkCgiApi doesn't have checkErrors, skip for now
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
-
if (!this.
|
|
313
|
-
logger.log('Starting
|
|
314
|
-
this.
|
|
315
|
-
const {
|
|
312
|
+
if (!this.lastNvrInfoCheck || now - this.lastNvrInfoCheck > 1000 * 60 * 5) {
|
|
313
|
+
logger.log('Starting NVR info data fetch');
|
|
314
|
+
this.lastNvrInfoCheck = now;
|
|
315
|
+
const { nvrData } = await api.getNvrInfo();
|
|
316
316
|
const { devicesData, channelsResponse, response } = await api.getDevicesInfo();
|
|
317
|
-
logger.log(
|
|
318
|
-
logger.debug(`${JSON.stringify({ hubData, devicesData, channelsResponse, response })}`);
|
|
317
|
+
logger.log(`NVR info data fetched: ${JSON.stringify({ nvrData, devicesData, channelsResponse, response })}`);
|
|
319
318
|
|
|
320
319
|
await this.discoverDevices(true);
|
|
321
320
|
}
|
|
@@ -355,6 +354,8 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
355
354
|
}
|
|
356
355
|
|
|
357
356
|
async updateDeviceInfo(): Promise<void> {
|
|
357
|
+
const logger = this.getBaichuanLogger();
|
|
358
|
+
|
|
358
359
|
const { ipAddress } = this.storageSettings.values;
|
|
359
360
|
try {
|
|
360
361
|
const api = await this.ensureClient();
|
|
@@ -365,8 +366,10 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
365
366
|
ipAddress,
|
|
366
367
|
deviceData,
|
|
367
368
|
});
|
|
369
|
+
|
|
370
|
+
logger.log(`Device info updated: ${JSON.stringify(deviceData)}`);
|
|
368
371
|
} catch (e) {
|
|
369
|
-
|
|
372
|
+
logger.warn('Failed to fetch device info', e);
|
|
370
373
|
}
|
|
371
374
|
}
|
|
372
375
|
|
|
@@ -422,12 +425,8 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
422
425
|
const api = await this.ensureClient();
|
|
423
426
|
const logger = this.getBaichuanLogger();
|
|
424
427
|
|
|
425
|
-
logger.log('Starting channels discovery using getDevicesInfo...');
|
|
426
|
-
|
|
427
428
|
const { devicesData, channels } = await api.getDevicesInfo();
|
|
428
|
-
|
|
429
|
-
logger.log(`getDevicesInfo completed. Found ${channels.length} channels.`);
|
|
430
|
-
|
|
429
|
+
logger.log(`Sync entities from remote for ${channels.length} channels`);
|
|
431
430
|
// Process each channel that was successfully discovered
|
|
432
431
|
for (const channel of channels) {
|
|
433
432
|
try {
|
|
@@ -479,7 +478,7 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
479
478
|
}
|
|
480
479
|
}
|
|
481
480
|
|
|
482
|
-
logger.log(`Channel discovery completed.
|
|
481
|
+
logger.log(`Channel discovery completed. ${JSON.stringify({ devicesData, channels })}`);
|
|
483
482
|
}
|
|
484
483
|
|
|
485
484
|
async discoverDevices(scan?: boolean): Promise<DiscoveredDevice[]> {
|
|
@@ -532,7 +531,8 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
532
531
|
await sdk.deviceManager.onDeviceDiscovered(actualDevice);
|
|
533
532
|
|
|
534
533
|
const device = await this.getDevice(adopt.nativeId);
|
|
535
|
-
this.getBaichuanLogger()
|
|
534
|
+
const logger = this.getBaichuanLogger();
|
|
535
|
+
logger.log('Adopted device', entry, device?.name);
|
|
536
536
|
const { username, password, ipAddress } = this.storageSettings.values;
|
|
537
537
|
|
|
538
538
|
device.storageSettings.values.rtspChannel = entry.rtspChannel;
|