@apocaliss92/scrypted-reolink-native 0.1.10 → 0.1.11

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/plugin.zip CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apocaliss92/scrypted-reolink-native",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "Use any reolink camera with Scrypted, even older/unsupported models without HTTP protocol support",
5
5
  "author": "@apocaliss92",
6
6
  "license": "Apache",
@@ -35,7 +35,7 @@ export class BaichuanLogger implements Console {
35
35
  }
36
36
 
37
37
  private formatMessage(level: string, ...args: any[]): string {
38
- const timestamp = new Date().toISOString();
38
+ const timestamp = new Date().toLocaleString();
39
39
  const prefix = `[${this.deviceName}] [${timestamp}] [${level}]`;
40
40
  return `${prefix} ${args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ')}`;
41
41
  }
@@ -36,16 +36,19 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
36
36
  }
37
37
 
38
38
  async takePicture(options?: RequestPictureOptions): Promise<MediaObject> {
39
+ const logger = this.getBaichuanLogger();
39
40
  // Allow new snapshot if:
40
41
  // 1. forceNewSnapshot is true, OR
41
42
  // 2. Camera is awake AND last snapshot was taken at least 10 seconds ago
42
- const minSnapshotIntervalMs = 10_000; // 10 seconds
43
- const now = Date.now();
44
- const shouldTakeNewSnapshot = this.forceNewSnapshot ||
45
- (!this.sleeping && this.lastPicture && (now - this.lastPicture.atMs >= minSnapshotIntervalMs));
43
+ // const minSnapshotIntervalMs = 10_000; // 10 seconds
44
+ // const now = Date.now();
45
+ const shouldTakeNewSnapshot = this.forceNewSnapshot;
46
+ // const now = Date.now();
47
+ // const shouldTakeNewSnapshot = this.forceNewSnapshot ||
48
+ // (!this.sleeping && this.lastPicture && (now - this.lastPicture.atMs >= minSnapshotIntervalMs));
46
49
 
47
50
  if (!shouldTakeNewSnapshot && this.lastPicture) {
48
- this.getBaichuanLogger().debug(`Returning cached snapshot, taken at ${new Date(this.lastPicture.atMs).toLocaleString()}`);
51
+ logger.debug(`Returning cached snapshot, taken at ${new Date(this.lastPicture.atMs).toLocaleString()}`);
49
52
  return this.lastPicture.mo;
50
53
  }
51
54
 
@@ -53,7 +56,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
53
56
  return await this.takePictureInFlight;
54
57
  }
55
58
 
56
- this.getBaichuanLogger().log(`Taking new snapshot from camera (forceNewSnapshot: ${this.forceNewSnapshot})`);
59
+ logger.log(`Taking new snapshot from camera (forceNewSnapshot: ${this.forceNewSnapshot})`);
57
60
  this.forceNewSnapshot = false;
58
61
 
59
62
  this.takePictureInFlight = (async () => {
@@ -63,7 +66,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
63
66
  });
64
67
  const mo = await sdk.mediaManager.createMediaObject(snapshotBuffer, 'image/jpeg');
65
68
  this.lastPicture = { mo, atMs: Date.now() };
66
- this.getBaichuanLogger().log(`Snapshot taken at ${new Date(this.lastPicture.atMs).toLocaleString()}`);
69
+ logger.log(`Snapshot taken at ${new Date(this.lastPicture.atMs).toLocaleString()}`);
67
70
  return mo;
68
71
  })();
69
72
 
@@ -104,9 +107,10 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
104
107
 
105
108
  private startPeriodicTasks(): void {
106
109
  if (this.periodicStarted) return;
110
+ const logger = this.getBaichuanLogger();
107
111
  this.periodicStarted = true;
108
112
 
109
- this.getBaichuanLogger().log('Starting periodic tasks for battery camera');
113
+ logger.log('Starting periodic tasks for battery camera');
110
114
 
111
115
  // Check sleeping state every 5 seconds (non-blocking)
112
116
  if (!this.nvrDevice) {
@@ -117,7 +121,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
117
121
 
118
122
  if (!api) {
119
123
  if (!this.sleeping) {
120
- this.getBaichuanLogger().log('Camera is sleeping: no active Baichuan client');
124
+ logger.log('Camera is sleeping: no active Baichuan client');
121
125
  this.sleeping = true;
122
126
  }
123
127
  return;
@@ -126,7 +130,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
126
130
  const sleepStatus = api.getSleepStatus({ channel });
127
131
  await this.updateSleepingState(sleepStatus);
128
132
  } catch (e) {
129
- this.getBaichuanLogger().warn('Error checking sleeping state:', e);
133
+ logger.warn('Error checking sleeping state:', e);
130
134
  }
131
135
  }, 5_000);
132
136
  }
@@ -138,7 +142,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
138
142
  this.updateBatteryAndSnapshot().catch(() => { });
139
143
  }, updateIntervalMs);
140
144
 
141
- this.getBaichuanLogger().log(`Periodic tasks started: sleep check every 5s, battery update every ${batteryUpdateIntervalMinutes} minutes`);
145
+ logger.log(`Periodic tasks started: sleep check every 5s, battery update every ${batteryUpdateIntervalMinutes} minutes`);
142
146
  }
143
147
 
144
148
  async updateSleepingState(sleepStatus: SleepStatus): Promise<void> {
@@ -182,7 +186,7 @@ export class ReolinkNativeBatteryCamera extends CommonCameraMixin {
182
186
 
183
187
  const batteryInfo = await api.getBatteryInfo(channel);
184
188
  if (this.isBatteryInfoLoggingEnabled()) {
185
- this.getBaichuanLogger().debug('getBatteryInfo result:', JSON.stringify(batteryInfo));
189
+ this.getBaichuanLogger().debug('getBatteryInfo result:', JSON.stringify(batteryInfo));
186
190
  }
187
191
 
188
192
  if (batteryInfo.batteryPercent !== undefined) {
package/src/common.ts CHANGED
@@ -1277,7 +1277,7 @@ export abstract class CommonCameraMixin extends BaseBaichuanClass implements Vid
1277
1277
  client,
1278
1278
  ipAddress,
1279
1279
  cachedNetPort: this.cachedNetPort,
1280
- isFromNvr,
1280
+ nvrDevice: this.nvrDevice,
1281
1281
  rtspChannel,
1282
1282
  logger,
1283
1283
  },
@@ -12,6 +12,7 @@ import sdk, {
12
12
  } from "@scrypted/sdk";
13
13
 
14
14
  import type { UrlMediaStreamOptions } from "../../scrypted/plugins/rtsp/src/rtsp";
15
+ import { ReolinkNativeNvrDevice } from "./nvr";
15
16
 
16
17
  export interface StreamManagerOptions {
17
18
  /**
@@ -101,12 +102,12 @@ export async function buildVideoStreamOptionsFromRtspRtmp(
101
102
  client: ReolinkBaichuanApi,
102
103
  ipAddress: string,
103
104
  cachedNetPort: { rtsp?: { port?: number; enable?: number }; rtmp?: { port?: number; enable?: number } },
104
- isFromNvr: boolean,
105
+ nvrDevice?: ReolinkNativeNvrDevice,
105
106
  rtspChannel: number,
106
107
  logger: Console
107
108
  },
108
109
  ): Promise<UrlMediaStreamOptions[]> {
109
- const { client, ipAddress, cachedNetPort, rtspChannel, logger } = props;
110
+ const { client, ipAddress, cachedNetPort, rtspChannel, logger, nvrDevice } = props;
110
111
  const rtspStreams: UrlMediaStreamOptions[] = [];
111
112
  const rtmpStreams: UrlMediaStreamOptions[] = [];
112
113
 
@@ -179,11 +180,21 @@ export async function buildVideoStreamOptionsFromRtspRtmp(
179
180
 
180
181
  const nativeStreams = await fetchVideoStreamOptionsFromApi(client, rtspChannel, logger);
181
182
 
182
- const streams: UrlMediaStreamOptions[] = [
183
- ...rtspStreams,
184
- ...rtmpStreams,
185
- ...nativeStreams,
186
- ];
183
+ let streams: UrlMediaStreamOptions[] = [];
184
+
185
+ if (nvrDevice && nvrDevice.info.model === 'HOMEHUB') {
186
+ streams = [
187
+ ...nativeStreams,
188
+ ...rtspStreams,
189
+ ...rtmpStreams,
190
+ ];
191
+ } else {
192
+ streams = [
193
+ ...rtspStreams,
194
+ ...rtmpStreams,
195
+ ...nativeStreams,
196
+ ];
197
+ }
187
198
 
188
199
  return streams;
189
200
  }