@apocaliss92/scrypted-reolink-native 0.1.21 → 0.1.23
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/multifocal.ts +95 -76
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/multifocal.ts
CHANGED
|
@@ -61,6 +61,8 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
61
61
|
cameraNativeMap = new Map<string, ReolinkNativeCamera | ReolinkNativeBatteryCamera>();
|
|
62
62
|
private channelToNativeIdMap = new Map<number, string>();
|
|
63
63
|
processing = false;
|
|
64
|
+
private syncInProgress = false;
|
|
65
|
+
private syncPromise: Promise<void> | undefined;
|
|
64
66
|
private initReinitTimeout: NodeJS.Timeout | undefined;
|
|
65
67
|
|
|
66
68
|
constructor(nativeId: string, plugin: ReolinkNativePlugin, transport: BaichuanTransport = 'tcp') {
|
|
@@ -197,85 +199,102 @@ export class ReolinkNativeMultiFocalDevice extends BaseBaichuanClass implements
|
|
|
197
199
|
}
|
|
198
200
|
|
|
199
201
|
async syncEntitiesFromRemote() {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
// If sync is already in progress, wait for it to complete
|
|
203
|
+
if (this.syncInProgress && this.syncPromise) {
|
|
204
|
+
const logger = this.getBaichuanLogger();
|
|
205
|
+
logger.debug('Sync already in progress, waiting for completion...');
|
|
206
|
+
await this.syncPromise;
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
202
209
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
const
|
|
208
|
-
logger.log(`Sync entities from remote for ${channelNum} channels`);
|
|
209
|
-
const channels = Array.from({ length: channelNum }, (_, i) => i + 1);
|
|
210
|
-
|
|
211
|
-
const multifocalInfo = await api.getDualLensChannelInfo();
|
|
212
|
-
|
|
213
|
-
logger.log(`Multichannel info: ${JSON.stringify(multifocalInfo)}`);
|
|
214
|
-
|
|
215
|
-
// if (channelNum === 2) {
|
|
216
|
-
|
|
217
|
-
// }
|
|
218
|
-
|
|
219
|
-
for (const channel of channels) {
|
|
220
|
-
// try {
|
|
221
|
-
// const name = deviceInfo?.name || `Channel ${channel}`;
|
|
222
|
-
// const uid = deviceInfo?.uid;
|
|
223
|
-
// const isBattery = !!(abilities?.battery?.ver ?? 0);
|
|
224
|
-
|
|
225
|
-
// const nativeId = this.buildNativeId(channel, uid, isBattery);
|
|
226
|
-
// const interfaces = [ScryptedInterface.VideoCamera];
|
|
227
|
-
// if (isBattery) {
|
|
228
|
-
// interfaces.push(ScryptedInterface.Battery);
|
|
229
|
-
// }
|
|
230
|
-
// const type = abilities.supportDoorbellLight ? ScryptedDeviceType.Doorbell : ScryptedDeviceType.Camera;
|
|
231
|
-
|
|
232
|
-
// const device: Device = {
|
|
233
|
-
// nativeId,
|
|
234
|
-
// name,
|
|
235
|
-
// providerNativeId: this.nativeId,
|
|
236
|
-
// interfaces,
|
|
237
|
-
// type,
|
|
238
|
-
// info: {
|
|
239
|
-
// manufacturer: 'Reolink',
|
|
240
|
-
// model: channelInfo?.typeInfo,
|
|
241
|
-
// serialNumber: uid,
|
|
242
|
-
// }
|
|
243
|
-
// };
|
|
244
|
-
|
|
245
|
-
// this.channelToNativeIdMap.set(channel, nativeId);
|
|
246
|
-
|
|
247
|
-
// if (sdk.deviceManager.getNativeIds().includes(nativeId)) {
|
|
248
|
-
// continue;
|
|
249
|
-
// }
|
|
250
|
-
|
|
251
|
-
// if (this.discoveredDevices.has(nativeId)) {
|
|
252
|
-
// continue;
|
|
253
|
-
// }
|
|
254
|
-
|
|
255
|
-
// this.discoveredDevices.set(nativeId, {
|
|
256
|
-
// device,
|
|
257
|
-
// description: `${name} (Channel ${channel})`,
|
|
258
|
-
// rtspChannel: channel,
|
|
259
|
-
// deviceData: devicesData[channel],
|
|
260
|
-
// });
|
|
261
|
-
|
|
262
|
-
// logger.debug(`Discovered channel ${channel}: ${name}`);
|
|
263
|
-
// } catch (e: any) {
|
|
264
|
-
// logger.debug(`Error processing channel ${channel}: ${e?.message || String(e)}`);
|
|
265
|
-
// }
|
|
266
|
-
}
|
|
210
|
+
// Start new sync
|
|
211
|
+
this.syncInProgress = true;
|
|
212
|
+
this.syncPromise = (async () => {
|
|
213
|
+
const api = await this.ensureBaichuanClient();
|
|
214
|
+
const logger = this.getBaichuanLogger();
|
|
267
215
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
logger.
|
|
274
|
-
|
|
275
|
-
|
|
216
|
+
try {
|
|
217
|
+
// const channelsInfo = await api.getNvrChannelsInfo();
|
|
218
|
+
// const deviceInfo = await api.getInfo();
|
|
219
|
+
const { support, abilities, features, capabilities } = await api.getDeviceCapabilities();
|
|
220
|
+
const channelNum = support?.channelNum ?? 1;
|
|
221
|
+
logger.log(`Sync entities from remote for ${channelNum} channels`);
|
|
222
|
+
const channels = Array.from({ length: channelNum }, (_, i) => i + 1);
|
|
223
|
+
|
|
224
|
+
const multifocalInfo = await api.getDualLensChannelInfo();
|
|
225
|
+
|
|
226
|
+
logger.log(`Multichannel info: ${JSON.stringify({ multifocalInfo, abilities, features, capabilities })}`);
|
|
227
|
+
|
|
228
|
+
// if (channelNum === 2) {
|
|
229
|
+
|
|
230
|
+
// }
|
|
231
|
+
|
|
232
|
+
for (const channel of channels) {
|
|
233
|
+
// try {
|
|
234
|
+
// const name = deviceInfo?.name || `Channel ${channel}`;
|
|
235
|
+
// const uid = deviceInfo?.uid;
|
|
236
|
+
// const isBattery = !!(abilities?.battery?.ver ?? 0);
|
|
237
|
+
|
|
238
|
+
// const nativeId = this.buildNativeId(channel, uid, isBattery);
|
|
239
|
+
// const interfaces = [ScryptedInterface.VideoCamera];
|
|
240
|
+
// if (isBattery) {
|
|
241
|
+
// interfaces.push(ScryptedInterface.Battery);
|
|
242
|
+
// }
|
|
243
|
+
// const type = abilities.supportDoorbellLight ? ScryptedDeviceType.Doorbell : ScryptedDeviceType.Camera;
|
|
244
|
+
|
|
245
|
+
// const device: Device = {
|
|
246
|
+
// nativeId,
|
|
247
|
+
// name,
|
|
248
|
+
// providerNativeId: this.nativeId,
|
|
249
|
+
// interfaces,
|
|
250
|
+
// type,
|
|
251
|
+
// info: {
|
|
252
|
+
// manufacturer: 'Reolink',
|
|
253
|
+
// model: channelInfo?.typeInfo,
|
|
254
|
+
// serialNumber: uid,
|
|
255
|
+
// }
|
|
256
|
+
// };
|
|
257
|
+
|
|
258
|
+
// this.channelToNativeIdMap.set(channel, nativeId);
|
|
259
|
+
|
|
260
|
+
// if (sdk.deviceManager.getNativeIds().includes(nativeId)) {
|
|
261
|
+
// continue;
|
|
262
|
+
// }
|
|
263
|
+
|
|
264
|
+
// if (this.discoveredDevices.has(nativeId)) {
|
|
265
|
+
// continue;
|
|
266
|
+
// }
|
|
267
|
+
|
|
268
|
+
// this.discoveredDevices.set(nativeId, {
|
|
269
|
+
// device,
|
|
270
|
+
// description: `${name} (Channel ${channel})`,
|
|
271
|
+
// rtspChannel: channel,
|
|
272
|
+
// deviceData: devicesData[channel],
|
|
273
|
+
// });
|
|
274
|
+
|
|
275
|
+
// logger.debug(`Discovered channel ${channel}: ${name}`);
|
|
276
|
+
// } catch (e: any) {
|
|
277
|
+
// logger.debug(`Error processing channel ${channel}: ${e?.message || String(e)}`);
|
|
278
|
+
// }
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// logger.log(`Channel discovery completed. ${JSON.stringify({ devicesData, channels })}`);
|
|
282
|
+
} catch (e) {
|
|
283
|
+
logger.error('Failed to sync entities from remote', e);
|
|
284
|
+
if (e instanceof Error) {
|
|
285
|
+
logger.error(`Error in syncEntitiesFromRemote: ${e.message}`);
|
|
286
|
+
logger.error(`Stack: ${e.stack}`);
|
|
287
|
+
} else {
|
|
288
|
+
logger.error(`Error details: ${JSON.stringify(e)}`);
|
|
289
|
+
}
|
|
290
|
+
throw e;
|
|
291
|
+
} finally {
|
|
292
|
+
this.syncInProgress = false;
|
|
293
|
+
this.syncPromise = undefined;
|
|
276
294
|
}
|
|
277
|
-
|
|
278
|
-
|
|
295
|
+
})();
|
|
296
|
+
|
|
297
|
+
await this.syncPromise;
|
|
279
298
|
}
|
|
280
299
|
|
|
281
300
|
async discoverDevices(scan?: boolean): Promise<DiscoveredDevice[]> {
|