@camstack/addon-provider-reolink 1.2.35 → 1.2.37
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 +48 -2
- package/dist/addon.mjs +48 -2
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -230966,10 +230966,13 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
230966
230966
|
const confirmDeadline = Date.now() + CONFIRM_TIMEOUT_MS;
|
|
230967
230967
|
const parent = await this.getParentHub();
|
|
230968
230968
|
let confirmed = false;
|
|
230969
|
+
let observedAwake = false;
|
|
230969
230970
|
while (Date.now() < confirmDeadline) {
|
|
230970
230971
|
if (parent !== null) try {
|
|
230971
|
-
|
|
230972
|
+
const entry = (await (await parent.getApi()).getNvrChannelsSummary({ channels: [this.getChannel()] })).devices.find((d) => d.channel === this.getChannel());
|
|
230973
|
+
if (entry !== void 0 && entry.online !== false) {
|
|
230972
230974
|
confirmed = true;
|
|
230975
|
+
observedAwake = entry.sleeping === false;
|
|
230973
230976
|
break;
|
|
230974
230977
|
}
|
|
230975
230978
|
} catch {}
|
|
@@ -230982,13 +230985,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
230982
230985
|
}
|
|
230983
230986
|
if (state === "awake") {
|
|
230984
230987
|
confirmed = true;
|
|
230988
|
+
observedAwake = true;
|
|
230985
230989
|
break;
|
|
230986
230990
|
}
|
|
230987
230991
|
}
|
|
230988
230992
|
await sleep$1(CONFIRM_POLL_MS);
|
|
230989
230993
|
}
|
|
230990
230994
|
const confirmSource = parent !== null ? "hub-summary" : "sleep-poll";
|
|
230991
|
-
if (
|
|
230995
|
+
if (observedAwake && this.commitSleepState(false, confirmSource)) {
|
|
230992
230996
|
this.ctx.logger.info("battery wakeForStream: wake confirmed — driving wake transition", {
|
|
230993
230997
|
tags: { deviceId: this.id },
|
|
230994
230998
|
meta: {
|
|
@@ -231008,6 +231012,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
231008
231012
|
durationMs: Date.now() - startedAt
|
|
231009
231013
|
};
|
|
231010
231014
|
}
|
|
231015
|
+
if (confirmed && !observedAwake && parent !== null) this.watchHubChildAwake(parent).catch(() => {});
|
|
231011
231016
|
return {
|
|
231012
231017
|
awoke: true,
|
|
231013
231018
|
durationMs: Date.now() - startedAt
|
|
@@ -231186,6 +231191,29 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
231186
231191
|
this.lastProactiveWakeAt = Date.now();
|
|
231187
231192
|
}
|
|
231188
231193
|
/**
|
|
231194
|
+
* Post-confirm watch for a hub child whose wake lands on the consumer's
|
|
231195
|
+
* relay dial: re-read the parent's channel summary a few times over the
|
|
231196
|
+
* dial's wake window and commit `sleeping: false` the moment the firmware
|
|
231197
|
+
* reports it. Ends EARLY once committed; bounded hard so a dead link can't
|
|
231198
|
+
* leak a timer. Costs the camera nothing — the summary is the hub's own
|
|
231199
|
+
* mains-powered read.
|
|
231200
|
+
*/
|
|
231201
|
+
async watchHubChildAwake(parent) {
|
|
231202
|
+
const deadline = Date.now() + 45e3;
|
|
231203
|
+
while (Date.now() < deadline) {
|
|
231204
|
+
await sleep$1(5e3);
|
|
231205
|
+
try {
|
|
231206
|
+
if ((await (await parent.getApi()).getNvrChannelsSummary({ channels: [this.getChannel()] })).devices.find((d) => d.channel === this.getChannel())?.sleeping === false) {
|
|
231207
|
+
if (this.commitSleepState(false, "hub-summary")) {
|
|
231208
|
+
this.ctx.logger.info("battery wakeForStream: hub child observed awake after the dial", { tags: { deviceId: this.id } });
|
|
231209
|
+
this.onWakeTransition("hub-summary").catch(() => {});
|
|
231210
|
+
}
|
|
231211
|
+
return;
|
|
231212
|
+
}
|
|
231213
|
+
} catch {}
|
|
231214
|
+
}
|
|
231215
|
+
}
|
|
231216
|
+
/**
|
|
231189
231217
|
* Close the transient "waking" window on a wake that did NOT produce a
|
|
231190
231218
|
* committed transition (ACK with no awake evidence, or a timeout).
|
|
231191
231219
|
* `BatteryOnWakeStarted` opens it; normally the `sleeping: false` commit
|
|
@@ -236647,6 +236675,14 @@ function computeHealthCheckBackoffMs(consecutive) {
|
|
|
236647
236675
|
//#endregion
|
|
236648
236676
|
//#region src/reolink-hub.ts
|
|
236649
236677
|
var HUB_DISCOVERY_REFRESH_TIMEOUT_MS = 8e3;
|
|
236678
|
+
/**
|
|
236679
|
+
* How often the hub re-reads its own channels summary to reconcile the
|
|
236680
|
+
* adopted children's sleep slices. 60 s: a naturally-waking camera (PIR,
|
|
236681
|
+
* schedule) is caught within a minute, and the play path has its own
|
|
236682
|
+
* faster confirm + post-dial watch, so this only ever carries background
|
|
236683
|
+
* drift. Never wakes a child — the summary is answered by the hub itself.
|
|
236684
|
+
*/
|
|
236685
|
+
var HUB_CHILD_SLEEP_RECONCILE_MS = 6e4;
|
|
236650
236686
|
var HUB_RECONNECT_BASE_MS = 2e3;
|
|
236651
236687
|
var HUB_RECONNECT_MAX_MS = 3e4;
|
|
236652
236688
|
/**
|
|
@@ -236680,6 +236716,8 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
236680
236716
|
connectInFlight = null;
|
|
236681
236717
|
reconnectAttempts = 0;
|
|
236682
236718
|
reconnectTimer = null;
|
|
236719
|
+
/** Periodic child-sleep reconcile timer (armed in `onActivate`). */
|
|
236720
|
+
sleepReconcileTimer = null;
|
|
236683
236721
|
shutdownRequested = false;
|
|
236684
236722
|
/** Diagnostic Sessions snapshot — same shape as the camera's. */
|
|
236685
236723
|
sessionsSnapshot = null;
|
|
@@ -236764,6 +236802,10 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
236764
236802
|
this.ctx.logger.info("Reolink Hub: child unregistered externally — refreshing discovery", cid !== null ? { tags: { deviceId: cid } } : {});
|
|
236765
236803
|
this.refreshDiscoveryFromCamera().catch(() => {});
|
|
236766
236804
|
}));
|
|
236805
|
+
this.sleepReconcileTimer = setInterval(() => {
|
|
236806
|
+
this.refreshDiscoveryFromCamera().catch(() => {});
|
|
236807
|
+
}, HUB_CHILD_SLEEP_RECONCILE_MS);
|
|
236808
|
+
if (typeof this.sleepReconcileTimer.unref === "function") this.sleepReconcileTimer.unref();
|
|
236767
236809
|
}
|
|
236768
236810
|
eventUnsubscribers = [];
|
|
236769
236811
|
/** Per-channel throttle for the unrouted-event warning (see
|
|
@@ -236775,6 +236817,10 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
236775
236817
|
clearTimeout(this.reconnectTimer);
|
|
236776
236818
|
this.reconnectTimer = null;
|
|
236777
236819
|
}
|
|
236820
|
+
if (this.sleepReconcileTimer) {
|
|
236821
|
+
clearInterval(this.sleepReconcileTimer);
|
|
236822
|
+
this.sleepReconcileTimer = null;
|
|
236823
|
+
}
|
|
236778
236824
|
for (const unsub of this.eventUnsubscribers) try {
|
|
236779
236825
|
unsub();
|
|
236780
236826
|
} catch {}
|
package/dist/addon.mjs
CHANGED
|
@@ -230946,10 +230946,13 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
230946
230946
|
const confirmDeadline = Date.now() + CONFIRM_TIMEOUT_MS;
|
|
230947
230947
|
const parent = await this.getParentHub();
|
|
230948
230948
|
let confirmed = false;
|
|
230949
|
+
let observedAwake = false;
|
|
230949
230950
|
while (Date.now() < confirmDeadline) {
|
|
230950
230951
|
if (parent !== null) try {
|
|
230951
|
-
|
|
230952
|
+
const entry = (await (await parent.getApi()).getNvrChannelsSummary({ channels: [this.getChannel()] })).devices.find((d) => d.channel === this.getChannel());
|
|
230953
|
+
if (entry !== void 0 && entry.online !== false) {
|
|
230952
230954
|
confirmed = true;
|
|
230955
|
+
observedAwake = entry.sleeping === false;
|
|
230953
230956
|
break;
|
|
230954
230957
|
}
|
|
230955
230958
|
} catch {}
|
|
@@ -230962,13 +230965,14 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
230962
230965
|
}
|
|
230963
230966
|
if (state === "awake") {
|
|
230964
230967
|
confirmed = true;
|
|
230968
|
+
observedAwake = true;
|
|
230965
230969
|
break;
|
|
230966
230970
|
}
|
|
230967
230971
|
}
|
|
230968
230972
|
await sleep$1(CONFIRM_POLL_MS);
|
|
230969
230973
|
}
|
|
230970
230974
|
const confirmSource = parent !== null ? "hub-summary" : "sleep-poll";
|
|
230971
|
-
if (
|
|
230975
|
+
if (observedAwake && this.commitSleepState(false, confirmSource)) {
|
|
230972
230976
|
this.ctx.logger.info("battery wakeForStream: wake confirmed — driving wake transition", {
|
|
230973
230977
|
tags: { deviceId: this.id },
|
|
230974
230978
|
meta: {
|
|
@@ -230988,6 +230992,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
230988
230992
|
durationMs: Date.now() - startedAt
|
|
230989
230993
|
};
|
|
230990
230994
|
}
|
|
230995
|
+
if (confirmed && !observedAwake && parent !== null) this.watchHubChildAwake(parent).catch(() => {});
|
|
230991
230996
|
return {
|
|
230992
230997
|
awoke: true,
|
|
230993
230998
|
durationMs: Date.now() - startedAt
|
|
@@ -231166,6 +231171,29 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
231166
231171
|
this.lastProactiveWakeAt = Date.now();
|
|
231167
231172
|
}
|
|
231168
231173
|
/**
|
|
231174
|
+
* Post-confirm watch for a hub child whose wake lands on the consumer's
|
|
231175
|
+
* relay dial: re-read the parent's channel summary a few times over the
|
|
231176
|
+
* dial's wake window and commit `sleeping: false` the moment the firmware
|
|
231177
|
+
* reports it. Ends EARLY once committed; bounded hard so a dead link can't
|
|
231178
|
+
* leak a timer. Costs the camera nothing — the summary is the hub's own
|
|
231179
|
+
* mains-powered read.
|
|
231180
|
+
*/
|
|
231181
|
+
async watchHubChildAwake(parent) {
|
|
231182
|
+
const deadline = Date.now() + 45e3;
|
|
231183
|
+
while (Date.now() < deadline) {
|
|
231184
|
+
await sleep$1(5e3);
|
|
231185
|
+
try {
|
|
231186
|
+
if ((await (await parent.getApi()).getNvrChannelsSummary({ channels: [this.getChannel()] })).devices.find((d) => d.channel === this.getChannel())?.sleeping === false) {
|
|
231187
|
+
if (this.commitSleepState(false, "hub-summary")) {
|
|
231188
|
+
this.ctx.logger.info("battery wakeForStream: hub child observed awake after the dial", { tags: { deviceId: this.id } });
|
|
231189
|
+
this.onWakeTransition("hub-summary").catch(() => {});
|
|
231190
|
+
}
|
|
231191
|
+
return;
|
|
231192
|
+
}
|
|
231193
|
+
} catch {}
|
|
231194
|
+
}
|
|
231195
|
+
}
|
|
231196
|
+
/**
|
|
231169
231197
|
* Close the transient "waking" window on a wake that did NOT produce a
|
|
231170
231198
|
* committed transition (ACK with no awake evidence, or a timeout).
|
|
231171
231199
|
* `BatteryOnWakeStarted` opens it; normally the `sleeping: false` commit
|
|
@@ -236627,6 +236655,14 @@ function computeHealthCheckBackoffMs(consecutive) {
|
|
|
236627
236655
|
//#endregion
|
|
236628
236656
|
//#region src/reolink-hub.ts
|
|
236629
236657
|
var HUB_DISCOVERY_REFRESH_TIMEOUT_MS = 8e3;
|
|
236658
|
+
/**
|
|
236659
|
+
* How often the hub re-reads its own channels summary to reconcile the
|
|
236660
|
+
* adopted children's sleep slices. 60 s: a naturally-waking camera (PIR,
|
|
236661
|
+
* schedule) is caught within a minute, and the play path has its own
|
|
236662
|
+
* faster confirm + post-dial watch, so this only ever carries background
|
|
236663
|
+
* drift. Never wakes a child — the summary is answered by the hub itself.
|
|
236664
|
+
*/
|
|
236665
|
+
var HUB_CHILD_SLEEP_RECONCILE_MS = 6e4;
|
|
236630
236666
|
var HUB_RECONNECT_BASE_MS = 2e3;
|
|
236631
236667
|
var HUB_RECONNECT_MAX_MS = 3e4;
|
|
236632
236668
|
/**
|
|
@@ -236660,6 +236696,8 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
236660
236696
|
connectInFlight = null;
|
|
236661
236697
|
reconnectAttempts = 0;
|
|
236662
236698
|
reconnectTimer = null;
|
|
236699
|
+
/** Periodic child-sleep reconcile timer (armed in `onActivate`). */
|
|
236700
|
+
sleepReconcileTimer = null;
|
|
236663
236701
|
shutdownRequested = false;
|
|
236664
236702
|
/** Diagnostic Sessions snapshot — same shape as the camera's. */
|
|
236665
236703
|
sessionsSnapshot = null;
|
|
@@ -236744,6 +236782,10 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
236744
236782
|
this.ctx.logger.info("Reolink Hub: child unregistered externally — refreshing discovery", cid !== null ? { tags: { deviceId: cid } } : {});
|
|
236745
236783
|
this.refreshDiscoveryFromCamera().catch(() => {});
|
|
236746
236784
|
}));
|
|
236785
|
+
this.sleepReconcileTimer = setInterval(() => {
|
|
236786
|
+
this.refreshDiscoveryFromCamera().catch(() => {});
|
|
236787
|
+
}, HUB_CHILD_SLEEP_RECONCILE_MS);
|
|
236788
|
+
if (typeof this.sleepReconcileTimer.unref === "function") this.sleepReconcileTimer.unref();
|
|
236747
236789
|
}
|
|
236748
236790
|
eventUnsubscribers = [];
|
|
236749
236791
|
/** Per-channel throttle for the unrouted-event warning (see
|
|
@@ -236755,6 +236797,10 @@ var ReolinkHub = class ReolinkHub extends BaseDevice {
|
|
|
236755
236797
|
clearTimeout(this.reconnectTimer);
|
|
236756
236798
|
this.reconnectTimer = null;
|
|
236757
236799
|
}
|
|
236800
|
+
if (this.sleepReconcileTimer) {
|
|
236801
|
+
clearInterval(this.sleepReconcileTimer);
|
|
236802
|
+
this.sleepReconcileTimer = null;
|
|
236803
|
+
}
|
|
236758
236804
|
for (const unsub of this.eventUnsubscribers) try {
|
|
236759
236805
|
unsub();
|
|
236760
236806
|
} catch {}
|