@camstack/addon-provider-reolink 1.2.5 → 1.2.6
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/addon.js +52 -17
- package/dist/addon.mjs +52 -17
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -222620,6 +222620,33 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
222620
222620
|
markWakeIssued() {
|
|
222621
222621
|
this.lastProactiveWakeAt = Date.now();
|
|
222622
222622
|
}
|
|
222623
|
+
/**
|
|
222624
|
+
* Gate for a PROACTIVE camera read, checked BEFORE `ensureApi()`.
|
|
222625
|
+
*
|
|
222626
|
+
* The login itself is the wake. On a sleeping UDP/battery camera the
|
|
222627
|
+
* lib's discovery + handshake nudges the firmware awake (same reason
|
|
222628
|
+
* `refreshParentSettingsSnapshot` refuses to call `ensureApi` while
|
|
222629
|
+
* asleep), so gating only the explicit `wakeUp()` call is useless —
|
|
222630
|
+
* by the time we reach it the camera is already up. Production logs
|
|
222631
|
+
* showed exactly that: a background read produced a full
|
|
222632
|
+
* `Connecting to Reolink` → BCUDP discovery → `battery sleep state
|
|
222633
|
+
* committed` (awake) → whole refresh cascade, on a camera that had
|
|
222634
|
+
* been asleep for six minutes.
|
|
222635
|
+
*
|
|
222636
|
+
* Returns `false` when the caller must serve cache / bail out without
|
|
222637
|
+
* touching the socket. Stamps the cooldown when it does let a wake
|
|
222638
|
+
* through, so "at most one proactive wake per
|
|
222639
|
+
* `PROACTIVE_WAKE_COOLDOWN_MS`" holds across ALL proactive callers
|
|
222640
|
+
* rather than per-caller.
|
|
222641
|
+
*
|
|
222642
|
+
* Demand-driven paths never call this — see `canProactivelyWake`.
|
|
222643
|
+
*/
|
|
222644
|
+
allowProactiveCameraAccess(reason) {
|
|
222645
|
+
if (!this.isBattery || !this.sleeping) return true;
|
|
222646
|
+
if (!this.canProactivelyWake(reason)) return false;
|
|
222647
|
+
this.markWakeIssued();
|
|
222648
|
+
return true;
|
|
222649
|
+
}
|
|
222623
222650
|
updateBatteryCache(info) {
|
|
222624
222651
|
this.setCapSlice(batteryCapability, this.mapBatteryInfo(info));
|
|
222625
222652
|
}
|
|
@@ -222865,6 +222892,10 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
222865
222892
|
}
|
|
222866
222893
|
async fetchSnapshotWithSingleFlight() {
|
|
222867
222894
|
if (this.snapshotInFlight) return this.snapshotInFlight;
|
|
222895
|
+
if (!this.allowProactiveCameraAccess("snapshot")) {
|
|
222896
|
+
this.ctx.logger.debug("snapshot: skipped — sleeping battery cam inside wake cooldown", { tags: { deviceId: this.id } });
|
|
222897
|
+
return null;
|
|
222898
|
+
}
|
|
222868
222899
|
const promise = (async () => {
|
|
222869
222900
|
let api;
|
|
222870
222901
|
try {
|
|
@@ -222882,23 +222913,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
222882
222913
|
} catch {
|
|
222883
222914
|
return true;
|
|
222884
222915
|
}
|
|
222885
|
-
})()) {
|
|
222886
|
-
|
|
222887
|
-
|
|
222888
|
-
|
|
222889
|
-
}
|
|
222890
|
-
|
|
222891
|
-
try {
|
|
222892
|
-
|
|
222893
|
-
|
|
222894
|
-
|
|
222895
|
-
});
|
|
222896
|
-
} catch (err) {
|
|
222897
|
-
this.ctx.logger.debug("snapshot: pre-wake failed (will still try getSnapshot)", {
|
|
222898
|
-
tags: { deviceId: this.id },
|
|
222899
|
-
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
222900
|
-
});
|
|
222901
|
-
}
|
|
222916
|
+
})()) try {
|
|
222917
|
+
await api.wakeUp(this.getChannel(), {
|
|
222918
|
+
waitAfterWakeMs: 1500,
|
|
222919
|
+
attempts: 2
|
|
222920
|
+
});
|
|
222921
|
+
} catch (err) {
|
|
222922
|
+
this.ctx.logger.debug("snapshot: pre-wake failed (will still try getSnapshot)", {
|
|
222923
|
+
tags: { deviceId: this.id },
|
|
222924
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
222925
|
+
});
|
|
222902
222926
|
}
|
|
222903
222927
|
const tryOnce = async (timeoutMs) => {
|
|
222904
222928
|
const buf = await api.getSnapshot(this.getChannel(), {
|
|
@@ -225262,6 +225286,10 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
225262
225286
|
if (this.batteryUpdateInFlight) return this.batteryUpdateInFlight;
|
|
225263
225287
|
const cycle = (async () => {
|
|
225264
225288
|
try {
|
|
225289
|
+
if (!this.allowProactiveCameraAccess("battery-update")) {
|
|
225290
|
+
this.ctx.logger.debug("battery-update: cam sleeping — skipping cycle without connecting", { tags: { deviceId: this.id } });
|
|
225291
|
+
return;
|
|
225292
|
+
}
|
|
225265
225293
|
let api;
|
|
225266
225294
|
try {
|
|
225267
225295
|
api = await this.ensureApi();
|
|
@@ -227113,6 +227141,13 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
227113
227141
|
}
|
|
227114
227142
|
if (this.api) return this.api;
|
|
227115
227143
|
if (this.loginPromise) return this.loginPromise;
|
|
227144
|
+
if (this.isBattery && this.sleeping) {
|
|
227145
|
+
const frames = (/* @__PURE__ */ new Error("wake-attribution")).stack?.split("\n").slice(2, 7).join(" | ");
|
|
227146
|
+
this.ctx.logger.info("battery cam login while sleeping — this wakes the camera", {
|
|
227147
|
+
tags: { deviceId: this.id },
|
|
227148
|
+
meta: { caller: frames ?? "unavailable" }
|
|
227149
|
+
});
|
|
227150
|
+
}
|
|
227116
227151
|
const host = this.config.get("host");
|
|
227117
227152
|
const port = this.config.get("port");
|
|
227118
227153
|
const username = this.config.get("username");
|
package/dist/addon.mjs
CHANGED
|
@@ -222600,6 +222600,33 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
222600
222600
|
markWakeIssued() {
|
|
222601
222601
|
this.lastProactiveWakeAt = Date.now();
|
|
222602
222602
|
}
|
|
222603
|
+
/**
|
|
222604
|
+
* Gate for a PROACTIVE camera read, checked BEFORE `ensureApi()`.
|
|
222605
|
+
*
|
|
222606
|
+
* The login itself is the wake. On a sleeping UDP/battery camera the
|
|
222607
|
+
* lib's discovery + handshake nudges the firmware awake (same reason
|
|
222608
|
+
* `refreshParentSettingsSnapshot` refuses to call `ensureApi` while
|
|
222609
|
+
* asleep), so gating only the explicit `wakeUp()` call is useless —
|
|
222610
|
+
* by the time we reach it the camera is already up. Production logs
|
|
222611
|
+
* showed exactly that: a background read produced a full
|
|
222612
|
+
* `Connecting to Reolink` → BCUDP discovery → `battery sleep state
|
|
222613
|
+
* committed` (awake) → whole refresh cascade, on a camera that had
|
|
222614
|
+
* been asleep for six minutes.
|
|
222615
|
+
*
|
|
222616
|
+
* Returns `false` when the caller must serve cache / bail out without
|
|
222617
|
+
* touching the socket. Stamps the cooldown when it does let a wake
|
|
222618
|
+
* through, so "at most one proactive wake per
|
|
222619
|
+
* `PROACTIVE_WAKE_COOLDOWN_MS`" holds across ALL proactive callers
|
|
222620
|
+
* rather than per-caller.
|
|
222621
|
+
*
|
|
222622
|
+
* Demand-driven paths never call this — see `canProactivelyWake`.
|
|
222623
|
+
*/
|
|
222624
|
+
allowProactiveCameraAccess(reason) {
|
|
222625
|
+
if (!this.isBattery || !this.sleeping) return true;
|
|
222626
|
+
if (!this.canProactivelyWake(reason)) return false;
|
|
222627
|
+
this.markWakeIssued();
|
|
222628
|
+
return true;
|
|
222629
|
+
}
|
|
222603
222630
|
updateBatteryCache(info) {
|
|
222604
222631
|
this.setCapSlice(batteryCapability, this.mapBatteryInfo(info));
|
|
222605
222632
|
}
|
|
@@ -222845,6 +222872,10 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
222845
222872
|
}
|
|
222846
222873
|
async fetchSnapshotWithSingleFlight() {
|
|
222847
222874
|
if (this.snapshotInFlight) return this.snapshotInFlight;
|
|
222875
|
+
if (!this.allowProactiveCameraAccess("snapshot")) {
|
|
222876
|
+
this.ctx.logger.debug("snapshot: skipped — sleeping battery cam inside wake cooldown", { tags: { deviceId: this.id } });
|
|
222877
|
+
return null;
|
|
222878
|
+
}
|
|
222848
222879
|
const promise = (async () => {
|
|
222849
222880
|
let api;
|
|
222850
222881
|
try {
|
|
@@ -222862,23 +222893,16 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
222862
222893
|
} catch {
|
|
222863
222894
|
return true;
|
|
222864
222895
|
}
|
|
222865
|
-
})()) {
|
|
222866
|
-
|
|
222867
|
-
|
|
222868
|
-
|
|
222869
|
-
}
|
|
222870
|
-
|
|
222871
|
-
try {
|
|
222872
|
-
|
|
222873
|
-
|
|
222874
|
-
|
|
222875
|
-
});
|
|
222876
|
-
} catch (err) {
|
|
222877
|
-
this.ctx.logger.debug("snapshot: pre-wake failed (will still try getSnapshot)", {
|
|
222878
|
-
tags: { deviceId: this.id },
|
|
222879
|
-
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
222880
|
-
});
|
|
222881
|
-
}
|
|
222896
|
+
})()) try {
|
|
222897
|
+
await api.wakeUp(this.getChannel(), {
|
|
222898
|
+
waitAfterWakeMs: 1500,
|
|
222899
|
+
attempts: 2
|
|
222900
|
+
});
|
|
222901
|
+
} catch (err) {
|
|
222902
|
+
this.ctx.logger.debug("snapshot: pre-wake failed (will still try getSnapshot)", {
|
|
222903
|
+
tags: { deviceId: this.id },
|
|
222904
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
222905
|
+
});
|
|
222882
222906
|
}
|
|
222883
222907
|
const tryOnce = async (timeoutMs) => {
|
|
222884
222908
|
const buf = await api.getSnapshot(this.getChannel(), {
|
|
@@ -225242,6 +225266,10 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
225242
225266
|
if (this.batteryUpdateInFlight) return this.batteryUpdateInFlight;
|
|
225243
225267
|
const cycle = (async () => {
|
|
225244
225268
|
try {
|
|
225269
|
+
if (!this.allowProactiveCameraAccess("battery-update")) {
|
|
225270
|
+
this.ctx.logger.debug("battery-update: cam sleeping — skipping cycle without connecting", { tags: { deviceId: this.id } });
|
|
225271
|
+
return;
|
|
225272
|
+
}
|
|
225245
225273
|
let api;
|
|
225246
225274
|
try {
|
|
225247
225275
|
api = await this.ensureApi();
|
|
@@ -227093,6 +227121,13 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
227093
227121
|
}
|
|
227094
227122
|
if (this.api) return this.api;
|
|
227095
227123
|
if (this.loginPromise) return this.loginPromise;
|
|
227124
|
+
if (this.isBattery && this.sleeping) {
|
|
227125
|
+
const frames = (/* @__PURE__ */ new Error("wake-attribution")).stack?.split("\n").slice(2, 7).join(" | ");
|
|
227126
|
+
this.ctx.logger.info("battery cam login while sleeping — this wakes the camera", {
|
|
227127
|
+
tags: { deviceId: this.id },
|
|
227128
|
+
meta: { caller: frames ?? "unavailable" }
|
|
227129
|
+
});
|
|
227130
|
+
}
|
|
227096
227131
|
const host = this.config.get("host");
|
|
227097
227132
|
const port = this.config.get("port");
|
|
227098
227133
|
const username = this.config.get("username");
|