@apocaliss92/scrypted-reolink-native 0.4.43 → 0.4.44

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.4.43",
3
+ "version": "0.4.44",
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",
@@ -57,6 +57,31 @@ export class ReolinkCameraChime
57
57
  return this.storageSettings.values.wirelessChimeId ?? -1;
58
58
  }
59
59
 
60
+ /**
61
+ * Refresh chime ID from device when -1.
62
+ * Python lib: GetDingDongList uses deviceId; GetDingDongCfg uses ringId (skips if < 0).
63
+ * Returns true if we have a valid chimeId; false if still not discovered.
64
+ */
65
+ private async ensureChimeId(): Promise<boolean> {
66
+ if (this.wirelessChimeId >= 0) return true;
67
+ const channel = this.camera.storageSettings.values.rtspChannel;
68
+ const api = await this.camera.ensureClient();
69
+ const list = await api.getDingDongList(channel);
70
+ if (list.length > 0 && list[0].id >= 0) {
71
+ this.storageSettings.values.wirelessChimeId = list[0].id;
72
+ this.logger.log(`Chime: discovered chimeId=${list[0].id} from GetDingDongList`);
73
+ return true;
74
+ }
75
+ const configs = await api.getDingDongCfg(channel);
76
+ const cfg = configs.find(c => c.id >= 0);
77
+ if (cfg) {
78
+ this.storageSettings.values.wirelessChimeId = cfg.id;
79
+ this.logger.log(`Chime: discovered chimeId=${cfg.id} from GetDingDongCfg`);
80
+ return true;
81
+ }
82
+ return false;
83
+ }
84
+
60
85
  private async getChimeCfg(): Promise<ChimeCfg | undefined> {
61
86
  const channel = this.camera.storageSettings.values.rtspChannel;
62
87
  const chimeId = this.wirelessChimeId;
@@ -70,6 +95,7 @@ export class ReolinkCameraChime
70
95
  * Determine if the chime is active by checking if any event type is enabled.
71
96
  */
72
97
  async syncStateFromDevice(): Promise<boolean | undefined> {
98
+ await this.ensureChimeId();
73
99
  const cfg = await this.getChimeCfg();
74
100
  if (!cfg) return undefined;
75
101
  const eventTypes = Object.values(cfg.type);
@@ -78,12 +104,18 @@ export class ReolinkCameraChime
78
104
  }
79
105
 
80
106
  async turnOn(): Promise<void> {
81
- const channel = this.camera.storageSettings.values.rtspChannel;
82
- const chimeId = this.wirelessChimeId;
83
- this.logger.log(`Chime: enable all events (device=${this.nativeId}, chimeId=${chimeId})`);
84
107
  this.camera.auxDeviceCooldowns.chime = Date.now();
85
108
  try {
86
109
  await this.camera.withBaichuanRetry(async () => {
110
+ const discovered = await this.ensureChimeId();
111
+ if (!discovered) {
112
+ throw new Error(
113
+ "Wireless chime not discovered. Ensure a Reolink Chime is paired with the doorbell and try again.",
114
+ );
115
+ }
116
+ const channel = this.camera.storageSettings.values.rtspChannel;
117
+ const chimeId = this.wirelessChimeId;
118
+ this.logger.log(`Chime: enable all events (device=${this.nativeId}, chimeId=${chimeId})`);
87
119
  const cfg = await this.getChimeCfg();
88
120
  if (!cfg) throw new Error(`Chime config not found for chimeId=${chimeId}`);
89
121
  const api = await this.camera.ensureClient();
@@ -106,12 +138,18 @@ export class ReolinkCameraChime
106
138
  }
107
139
 
108
140
  async turnOff(): Promise<void> {
109
- const channel = this.camera.storageSettings.values.rtspChannel;
110
- const chimeId = this.wirelessChimeId;
111
- this.logger.log(`Chime: disable all events (device=${this.nativeId}, chimeId=${chimeId})`);
112
141
  this.camera.auxDeviceCooldowns.chime = Date.now();
113
142
  try {
114
143
  await this.camera.withBaichuanRetry(async () => {
144
+ const discovered = await this.ensureChimeId();
145
+ if (!discovered) {
146
+ throw new Error(
147
+ "Wireless chime not discovered. Ensure a Reolink Chime is paired with the doorbell and try again.",
148
+ );
149
+ }
150
+ const channel = this.camera.storageSettings.values.rtspChannel;
151
+ const chimeId = this.wirelessChimeId;
152
+ this.logger.log(`Chime: disable all events (device=${this.nativeId}, chimeId=${chimeId})`);
115
153
  const cfg = await this.getChimeCfg();
116
154
  if (!cfg) throw new Error(`Chime config not found for chimeId=${chimeId}`);
117
155
  const api = await this.camera.ensureClient();
package/src/camera.ts CHANGED
@@ -126,6 +126,30 @@ export class ReolinkCamera
126
126
  title: "Debug logs",
127
127
  type: "boolean",
128
128
  immediate: true,
129
+ onPut: async (ov, value) => {
130
+ if (ov === value) return;
131
+ const logger = this.getBaichuanLogger();
132
+ if (this.resetBaichuanClient) {
133
+ if (this.debugLogsResetTimeout) {
134
+ clearTimeout(this.debugLogsResetTimeout);
135
+ this.debugLogsResetTimeout = undefined;
136
+ }
137
+ this.debugLogsResetTimeout = setTimeout(async () => {
138
+ this.debugLogsResetTimeout = undefined;
139
+ try {
140
+ await this.resetBaichuanClient("debugLogs changed");
141
+ this.baichuanApi = undefined;
142
+ this.ensureClientPromise = undefined;
143
+ await this.ensureClient();
144
+ } catch (e) {
145
+ logger.warn(
146
+ "Failed to reset client after debug logs change",
147
+ e?.message || String(e),
148
+ );
149
+ }
150
+ }, 2000);
151
+ }
152
+ },
129
153
  },
130
154
  // Basic connection settings
131
155
  ipAddress: {
package/src/nvr.ts CHANGED
@@ -51,6 +51,26 @@ export class ReolinkNativeNvrDevice
51
51
  title: "Debug Events",
52
52
  type: "boolean",
53
53
  immediate: true,
54
+ onPut: async (ov, value) => {
55
+ if (ov === value) return;
56
+ const logger = this.getBaichuanLogger();
57
+ if (this.debugLogsResetTimeout) {
58
+ clearTimeout(this.debugLogsResetTimeout);
59
+ this.debugLogsResetTimeout = undefined;
60
+ }
61
+ this.debugLogsResetTimeout = setTimeout(async () => {
62
+ this.debugLogsResetTimeout = undefined;
63
+ try {
64
+ await this.cleanupBaichuanApi();
65
+ await this.ensureBaichuanClient();
66
+ } catch (e) {
67
+ logger.warn(
68
+ "Failed to reset client after debug logs change",
69
+ e?.message || String(e),
70
+ );
71
+ }
72
+ }, 2000);
73
+ },
54
74
  },
55
75
  // eventSource: {
56
76
  // title: 'Event Source',