@camstack/addon-provider-reolink 1.2.126 → 1.2.128
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 +84 -32
- package/dist/addon.mjs +84 -32
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -22078,6 +22078,14 @@ var MotionSourceEnum = _enum([
|
|
|
22078
22078
|
*/
|
|
22079
22079
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
22080
22080
|
/**
|
|
22081
|
+
* Which root detectors a camera runs. Deliberately the SAME vocabulary
|
|
22082
|
+
* post-analysis already tags every detection with (`DetectionSource`) rather
|
|
22083
|
+
* than a second spelling of the same two ideas — the value an operator picks
|
|
22084
|
+
* here is the value that comes back on the track, the overlay and the debug
|
|
22085
|
+
* row.
|
|
22086
|
+
*/
|
|
22087
|
+
var DetectionSourcesSchema = array(DetectionSourceSchema);
|
|
22088
|
+
/**
|
|
22081
22089
|
* Input shape for `pipeline-runner.reportMotion` cap method. Exported
|
|
22082
22090
|
* so cap-side consumers (the orchestrator forward, the runner addon's
|
|
22083
22091
|
* cap implementation, tests) can reuse the type instead of redeclaring
|
|
@@ -22228,6 +22236,35 @@ var RunnerCameraConfigSchema = object({
|
|
|
22228
22236
|
* events; the orchestrator forwards to `reportMotion`.
|
|
22229
22237
|
*/
|
|
22230
22238
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
22239
|
+
/**
|
|
22240
|
+
* WHICH root detector runs for this camera. The detection counterpart of
|
|
22241
|
+
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
22242
|
+
* of sources the system understands, vendor-agnostic, owned here.
|
|
22243
|
+
*
|
|
22244
|
+
* - `pipeline` — this runner's own root step on decoded pixels (`steps`).
|
|
22245
|
+
* - `onboard` — the CAMERA's own detector, admitted only when it is named
|
|
22246
|
+
* here. Its boxes reach post-analysis on the same
|
|
22247
|
+
* `PipelineInferenceResult` payload as the pipeline's, so an onboard-born
|
|
22248
|
+
* track gets the same tracker, the same overlay and the same detail
|
|
22249
|
+
* subtree (face / plate / embedding).
|
|
22250
|
+
*
|
|
22251
|
+
* `['onboard']` alone is the REPLACEMENT: this runner's root step does not
|
|
22252
|
+
* run, and that is where a camera with a usable onboard detector buys back
|
|
22253
|
+
* its share of the accelerator. It saves the root inference, not the decode
|
|
22254
|
+
* — the detail subtree still needs pixels to cut crops from.
|
|
22255
|
+
*
|
|
22256
|
+
* A camera whose onboard detections carry no geometry cannot serve as a root
|
|
22257
|
+
* step at all (there is nothing to track), and the cap that knows this says
|
|
22258
|
+
* so on `native-object-detection.getOptions().geometry`. On Reolink that is
|
|
22259
|
+
* every battery camera: the boxes ride a sub-stream a battery camera never
|
|
22260
|
+
* attaches, so such a camera stays on `['pipeline']` and its onboard AI is
|
|
22261
|
+
* worth exactly what it already is — a wake signal with a class.
|
|
22262
|
+
*
|
|
22263
|
+
* Defaults to `['pipeline']`, which is byte-for-byte today's behaviour: a
|
|
22264
|
+
* vendor never turns a detector on for the operator, and neither does a
|
|
22265
|
+
* default.
|
|
22266
|
+
*/
|
|
22267
|
+
detectionSources: DetectionSourcesSchema.default(["pipeline"]),
|
|
22231
22268
|
pipelineEnabled: boolean().default(true),
|
|
22232
22269
|
/** Ordered tree of video steps. Absent → runner skips video detection. */
|
|
22233
22270
|
steps: array(PipelineStepInputSchema).readonly().optional(),
|
|
@@ -29344,31 +29381,38 @@ var NativeObjectDetectionStatusSchema = object({
|
|
|
29344
29381
|
/**
|
|
29345
29382
|
* Whether forwarding of onboard AI detections is enabled for this device.
|
|
29346
29383
|
*
|
|
29347
|
-
*
|
|
29348
|
-
*
|
|
29349
|
-
*
|
|
29350
|
-
*
|
|
29351
|
-
*
|
|
29352
|
-
* costs. {@link NativeObjectDetectionOptionsSchema.geometry} is how the UI
|
|
29353
|
-
* says which of the two a camera is.
|
|
29384
|
+
* Cold-start OFF on every camera. A vendor does not decide which detector a
|
|
29385
|
+
* camera runs — that is the operator's choice, and it is made where every
|
|
29386
|
+
* other detection choice is made. `geometry` on
|
|
29387
|
+
* {@link NativeObjectDetectionOptionsSchema} is how the form says what the
|
|
29388
|
+
* choice would buy this particular camera.
|
|
29354
29389
|
*/
|
|
29355
29390
|
enabled: boolean()
|
|
29356
29391
|
});
|
|
29357
29392
|
/**
|
|
29358
|
-
*
|
|
29393
|
+
* WHEN a camera's onboard detections carry geometry.
|
|
29359
29394
|
*
|
|
29360
|
-
* `boxed` —
|
|
29361
|
-
* a subject the
|
|
29362
|
-
* `
|
|
29363
|
-
*
|
|
29364
|
-
*
|
|
29365
|
-
*
|
|
29395
|
+
* - `boxed` — always. The provider holds a standing channel for the boxes, so
|
|
29396
|
+
* a detection is a trackable subject whenever the camera sees one.
|
|
29397
|
+
* - `while-streaming` — only while some stream of this camera is already open.
|
|
29398
|
+
* The boxes ride the video's own side-channel rather than a feed of their
|
|
29399
|
+
* own, so they cost nothing and they exist only when something is pulling.
|
|
29400
|
+
* On Reolink this is every BATTERY camera: a persistent second feed is real
|
|
29401
|
+
* radio drain, but a camera that is awake is awake precisely because
|
|
29402
|
+
* something is in front of it, and its stream is already being pulled.
|
|
29403
|
+
* - `flag-only` — never. The firmware ships the class and nothing else; the
|
|
29404
|
+
* pipeline needs geometry to make a subject, so such a push reaches the
|
|
29405
|
+
* tracker as motion and no further.
|
|
29366
29406
|
*
|
|
29367
29407
|
* Reported and not inferred, because the operator's question in front of the
|
|
29368
|
-
*
|
|
29369
|
-
*
|
|
29408
|
+
* picker is "what do I get", and these are three different answers (D14: the
|
|
29409
|
+
* derived form is only as honest as `getOptions`).
|
|
29370
29410
|
*/
|
|
29371
|
-
var NativeObjectGeometryEnum = _enum([
|
|
29411
|
+
var NativeObjectGeometryEnum = _enum([
|
|
29412
|
+
"boxed",
|
|
29413
|
+
"while-streaming",
|
|
29414
|
+
"flag-only"
|
|
29415
|
+
]);
|
|
29372
29416
|
var NativeObjectDetectionOptionsSchema = object({
|
|
29373
29417
|
/** Classes this firmware can detect — the same list the status reports. */
|
|
29374
29418
|
supportedClasses: array(NativeObjectClassEnum).readonly(),
|
|
@@ -29385,11 +29429,6 @@ var nativeObjectDetectionCapability = {
|
|
|
29385
29429
|
deviceNative: true,
|
|
29386
29430
|
mode: "singleton",
|
|
29387
29431
|
deviceTypes: [DeviceType.Camera],
|
|
29388
|
-
deviceConfig: { ui: {
|
|
29389
|
-
kind: "derived-form",
|
|
29390
|
-
builderId: "native-object-detection",
|
|
29391
|
-
tab: "motion"
|
|
29392
|
-
} },
|
|
29393
29432
|
methods: {
|
|
29394
29433
|
getOptions: method(object({ deviceId: number() }), NativeObjectDetectionOptionsSchema),
|
|
29395
29434
|
setSettings: method(object({
|
|
@@ -152481,10 +152520,8 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
152481
152520
|
* yet (e.g. fresh device, no config cached).
|
|
152482
152521
|
* - `lastByClass`: updated in `handleSimpleEvent` every time an AI-class
|
|
152483
152522
|
* event fires, regardless of the `enabled` flag.
|
|
152484
|
-
* - `enabled`: operator toggle
|
|
152485
|
-
*
|
|
152486
|
-
* subjects), OFF for a battery one (no boxed side-channel, so the toggle
|
|
152487
|
-
* would buy it nothing). See `buildEmptyState`.
|
|
152523
|
+
* - `enabled`: operator toggle, cold-start OFF on every camera. A vendor
|
|
152524
|
+
* never turns a detector on for the operator; see `buildEmptyState`.
|
|
152488
152525
|
*
|
|
152489
152526
|
* Follows the trampoline pattern from `registerStreamParamsCap` — no
|
|
152490
152527
|
* parallel private fields; all state lives in the kernel runtimeState
|
|
@@ -152512,7 +152549,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
152512
152549
|
const CAP_NAME = "native-object-detection";
|
|
152513
152550
|
const buildSupportedClasses = () => buildSupportedNativeClasses(this.config.get("deviceCache")?.aiDetectTypes, isNativeObjectClass).filter(isNativeObjectClass);
|
|
152514
152551
|
const buildEmptyState = () => ({
|
|
152515
|
-
enabled:
|
|
152552
|
+
enabled: false,
|
|
152516
152553
|
lastByClass: {},
|
|
152517
152554
|
supportedClasses: buildSupportedClasses(),
|
|
152518
152555
|
lastFetchedAt: 0
|
|
@@ -152544,7 +152581,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
152544
152581
|
};
|
|
152545
152582
|
return {
|
|
152546
152583
|
supportedClasses: buildSupportedClasses(),
|
|
152547
|
-
geometry: this.isBattery ? "
|
|
152584
|
+
geometry: this.isBattery ? "while-streaming" : "boxed"
|
|
152548
152585
|
};
|
|
152549
152586
|
},
|
|
152550
152587
|
setSettings: async ({ deviceId, settings }) => {
|
|
@@ -152563,6 +152600,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
152563
152600
|
...buildEmptyState(),
|
|
152564
152601
|
lastFetchedAt: Date.now()
|
|
152565
152602
|
});
|
|
152603
|
+
else this.runtimeState.patchCapState(CAP_NAME, { supportedClasses: buildSupportedClasses() });
|
|
152566
152604
|
this.ctx.logger.info("Reolink native-object-detection cap registered", { tags: { deviceId: this.id } });
|
|
152567
152605
|
}
|
|
152568
152606
|
/**
|
|
@@ -154185,14 +154223,22 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
154185
154223
|
});
|
|
154186
154224
|
} catch {}
|
|
154187
154225
|
this.objectDetectionsSubscribed = false;
|
|
154188
|
-
if (this.isBattery) {
|
|
154189
|
-
this.ctx.logger.debug("Reolink objectDetections subscribe skipped — battery cam", { meta: { reason } });
|
|
154190
|
-
return;
|
|
154191
|
-
}
|
|
154192
154226
|
if (!isNativeObjectForwardingEnabled(this.runtimeState.getCapState("native-object-detection"))) {
|
|
154193
154227
|
this.ctx.logger.debug("Reolink objectDetections subscribe skipped — cap disabled", { meta: { reason } });
|
|
154194
154228
|
return;
|
|
154195
154229
|
}
|
|
154230
|
+
if (this.isBattery) {
|
|
154231
|
+
api.onDetection(this.handleObjectDetectionsBound);
|
|
154232
|
+
this.objectDetectionsSubscribed = true;
|
|
154233
|
+
this.ctx.logger.info("Reolink onboard boxes ride the open stream (battery cam)", {
|
|
154234
|
+
tags: { deviceId: this.id },
|
|
154235
|
+
meta: {
|
|
154236
|
+
reason,
|
|
154237
|
+
channel
|
|
154238
|
+
}
|
|
154239
|
+
});
|
|
154240
|
+
return;
|
|
154241
|
+
}
|
|
154196
154242
|
if (!api.client.isSocketConnected() || !api.client.loggedIn) {
|
|
154197
154243
|
this.ctx.logger.debug("Reolink objectDetections subscribe skipped — socket not ready", { meta: {
|
|
154198
154244
|
reason,
|
|
@@ -154218,6 +154264,11 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
154218
154264
|
*/
|
|
154219
154265
|
async unsubscribeObjectDetections(api) {
|
|
154220
154266
|
if (!this.objectDetectionsSubscribed) return;
|
|
154267
|
+
if (this.isBattery) {
|
|
154268
|
+
api.offDetection(this.handleObjectDetectionsBound);
|
|
154269
|
+
this.objectDetectionsSubscribed = false;
|
|
154270
|
+
return;
|
|
154271
|
+
}
|
|
154221
154272
|
try {
|
|
154222
154273
|
await api.offObjectDetections(this.handleObjectDetectionsBound, {
|
|
154223
154274
|
channel: this.getChannel(),
|
|
@@ -154247,6 +154298,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
154247
154298
|
*/
|
|
154248
154299
|
handleObjectDetections(event) {
|
|
154249
154300
|
if (!isNativeObjectForwardingEnabled(this.runtimeState.getCapState("native-object-detection"))) return;
|
|
154301
|
+
if (event.channel !== this.getChannel()) return;
|
|
154250
154302
|
if (event.boxes.length === 0) return;
|
|
154251
154303
|
const now = Date.now();
|
|
154252
154304
|
const payload = mapDetectionEvent(event, this.id, now);
|
package/dist/addon.mjs
CHANGED
|
@@ -22073,6 +22073,14 @@ var MotionSourceEnum = _enum([
|
|
|
22073
22073
|
*/
|
|
22074
22074
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
22075
22075
|
/**
|
|
22076
|
+
* Which root detectors a camera runs. Deliberately the SAME vocabulary
|
|
22077
|
+
* post-analysis already tags every detection with (`DetectionSource`) rather
|
|
22078
|
+
* than a second spelling of the same two ideas — the value an operator picks
|
|
22079
|
+
* here is the value that comes back on the track, the overlay and the debug
|
|
22080
|
+
* row.
|
|
22081
|
+
*/
|
|
22082
|
+
var DetectionSourcesSchema = array(DetectionSourceSchema);
|
|
22083
|
+
/**
|
|
22076
22084
|
* Input shape for `pipeline-runner.reportMotion` cap method. Exported
|
|
22077
22085
|
* so cap-side consumers (the orchestrator forward, the runner addon's
|
|
22078
22086
|
* cap implementation, tests) can reuse the type instead of redeclaring
|
|
@@ -22223,6 +22231,35 @@ var RunnerCameraConfigSchema = object({
|
|
|
22223
22231
|
* events; the orchestrator forwards to `reportMotion`.
|
|
22224
22232
|
*/
|
|
22225
22233
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
22234
|
+
/**
|
|
22235
|
+
* WHICH root detector runs for this camera. The detection counterpart of
|
|
22236
|
+
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
22237
|
+
* of sources the system understands, vendor-agnostic, owned here.
|
|
22238
|
+
*
|
|
22239
|
+
* - `pipeline` — this runner's own root step on decoded pixels (`steps`).
|
|
22240
|
+
* - `onboard` — the CAMERA's own detector, admitted only when it is named
|
|
22241
|
+
* here. Its boxes reach post-analysis on the same
|
|
22242
|
+
* `PipelineInferenceResult` payload as the pipeline's, so an onboard-born
|
|
22243
|
+
* track gets the same tracker, the same overlay and the same detail
|
|
22244
|
+
* subtree (face / plate / embedding).
|
|
22245
|
+
*
|
|
22246
|
+
* `['onboard']` alone is the REPLACEMENT: this runner's root step does not
|
|
22247
|
+
* run, and that is where a camera with a usable onboard detector buys back
|
|
22248
|
+
* its share of the accelerator. It saves the root inference, not the decode
|
|
22249
|
+
* — the detail subtree still needs pixels to cut crops from.
|
|
22250
|
+
*
|
|
22251
|
+
* A camera whose onboard detections carry no geometry cannot serve as a root
|
|
22252
|
+
* step at all (there is nothing to track), and the cap that knows this says
|
|
22253
|
+
* so on `native-object-detection.getOptions().geometry`. On Reolink that is
|
|
22254
|
+
* every battery camera: the boxes ride a sub-stream a battery camera never
|
|
22255
|
+
* attaches, so such a camera stays on `['pipeline']` and its onboard AI is
|
|
22256
|
+
* worth exactly what it already is — a wake signal with a class.
|
|
22257
|
+
*
|
|
22258
|
+
* Defaults to `['pipeline']`, which is byte-for-byte today's behaviour: a
|
|
22259
|
+
* vendor never turns a detector on for the operator, and neither does a
|
|
22260
|
+
* default.
|
|
22261
|
+
*/
|
|
22262
|
+
detectionSources: DetectionSourcesSchema.default(["pipeline"]),
|
|
22226
22263
|
pipelineEnabled: boolean().default(true),
|
|
22227
22264
|
/** Ordered tree of video steps. Absent → runner skips video detection. */
|
|
22228
22265
|
steps: array(PipelineStepInputSchema).readonly().optional(),
|
|
@@ -29339,31 +29376,38 @@ var NativeObjectDetectionStatusSchema = object({
|
|
|
29339
29376
|
/**
|
|
29340
29377
|
* Whether forwarding of onboard AI detections is enabled for this device.
|
|
29341
29378
|
*
|
|
29342
|
-
*
|
|
29343
|
-
*
|
|
29344
|
-
*
|
|
29345
|
-
*
|
|
29346
|
-
*
|
|
29347
|
-
* costs. {@link NativeObjectDetectionOptionsSchema.geometry} is how the UI
|
|
29348
|
-
* says which of the two a camera is.
|
|
29379
|
+
* Cold-start OFF on every camera. A vendor does not decide which detector a
|
|
29380
|
+
* camera runs — that is the operator's choice, and it is made where every
|
|
29381
|
+
* other detection choice is made. `geometry` on
|
|
29382
|
+
* {@link NativeObjectDetectionOptionsSchema} is how the form says what the
|
|
29383
|
+
* choice would buy this particular camera.
|
|
29349
29384
|
*/
|
|
29350
29385
|
enabled: boolean()
|
|
29351
29386
|
});
|
|
29352
29387
|
/**
|
|
29353
|
-
*
|
|
29388
|
+
* WHEN a camera's onboard detections carry geometry.
|
|
29354
29389
|
*
|
|
29355
|
-
* `boxed` —
|
|
29356
|
-
* a subject the
|
|
29357
|
-
* `
|
|
29358
|
-
*
|
|
29359
|
-
*
|
|
29360
|
-
*
|
|
29390
|
+
* - `boxed` — always. The provider holds a standing channel for the boxes, so
|
|
29391
|
+
* a detection is a trackable subject whenever the camera sees one.
|
|
29392
|
+
* - `while-streaming` — only while some stream of this camera is already open.
|
|
29393
|
+
* The boxes ride the video's own side-channel rather than a feed of their
|
|
29394
|
+
* own, so they cost nothing and they exist only when something is pulling.
|
|
29395
|
+
* On Reolink this is every BATTERY camera: a persistent second feed is real
|
|
29396
|
+
* radio drain, but a camera that is awake is awake precisely because
|
|
29397
|
+
* something is in front of it, and its stream is already being pulled.
|
|
29398
|
+
* - `flag-only` — never. The firmware ships the class and nothing else; the
|
|
29399
|
+
* pipeline needs geometry to make a subject, so such a push reaches the
|
|
29400
|
+
* tracker as motion and no further.
|
|
29361
29401
|
*
|
|
29362
29402
|
* Reported and not inferred, because the operator's question in front of the
|
|
29363
|
-
*
|
|
29364
|
-
*
|
|
29403
|
+
* picker is "what do I get", and these are three different answers (D14: the
|
|
29404
|
+
* derived form is only as honest as `getOptions`).
|
|
29365
29405
|
*/
|
|
29366
|
-
var NativeObjectGeometryEnum = _enum([
|
|
29406
|
+
var NativeObjectGeometryEnum = _enum([
|
|
29407
|
+
"boxed",
|
|
29408
|
+
"while-streaming",
|
|
29409
|
+
"flag-only"
|
|
29410
|
+
]);
|
|
29367
29411
|
var NativeObjectDetectionOptionsSchema = object({
|
|
29368
29412
|
/** Classes this firmware can detect — the same list the status reports. */
|
|
29369
29413
|
supportedClasses: array(NativeObjectClassEnum).readonly(),
|
|
@@ -29380,11 +29424,6 @@ var nativeObjectDetectionCapability = {
|
|
|
29380
29424
|
deviceNative: true,
|
|
29381
29425
|
mode: "singleton",
|
|
29382
29426
|
deviceTypes: [DeviceType.Camera],
|
|
29383
|
-
deviceConfig: { ui: {
|
|
29384
|
-
kind: "derived-form",
|
|
29385
|
-
builderId: "native-object-detection",
|
|
29386
|
-
tab: "motion"
|
|
29387
|
-
} },
|
|
29388
29427
|
methods: {
|
|
29389
29428
|
getOptions: method(object({ deviceId: number() }), NativeObjectDetectionOptionsSchema),
|
|
29390
29429
|
setSettings: method(object({
|
|
@@ -152476,10 +152515,8 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
152476
152515
|
* yet (e.g. fresh device, no config cached).
|
|
152477
152516
|
* - `lastByClass`: updated in `handleSimpleEvent` every time an AI-class
|
|
152478
152517
|
* event fires, regardless of the `enabled` flag.
|
|
152479
|
-
* - `enabled`: operator toggle
|
|
152480
|
-
*
|
|
152481
|
-
* subjects), OFF for a battery one (no boxed side-channel, so the toggle
|
|
152482
|
-
* would buy it nothing). See `buildEmptyState`.
|
|
152518
|
+
* - `enabled`: operator toggle, cold-start OFF on every camera. A vendor
|
|
152519
|
+
* never turns a detector on for the operator; see `buildEmptyState`.
|
|
152483
152520
|
*
|
|
152484
152521
|
* Follows the trampoline pattern from `registerStreamParamsCap` — no
|
|
152485
152522
|
* parallel private fields; all state lives in the kernel runtimeState
|
|
@@ -152507,7 +152544,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
152507
152544
|
const CAP_NAME = "native-object-detection";
|
|
152508
152545
|
const buildSupportedClasses = () => buildSupportedNativeClasses(this.config.get("deviceCache")?.aiDetectTypes, isNativeObjectClass).filter(isNativeObjectClass);
|
|
152509
152546
|
const buildEmptyState = () => ({
|
|
152510
|
-
enabled:
|
|
152547
|
+
enabled: false,
|
|
152511
152548
|
lastByClass: {},
|
|
152512
152549
|
supportedClasses: buildSupportedClasses(),
|
|
152513
152550
|
lastFetchedAt: 0
|
|
@@ -152539,7 +152576,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
152539
152576
|
};
|
|
152540
152577
|
return {
|
|
152541
152578
|
supportedClasses: buildSupportedClasses(),
|
|
152542
|
-
geometry: this.isBattery ? "
|
|
152579
|
+
geometry: this.isBattery ? "while-streaming" : "boxed"
|
|
152543
152580
|
};
|
|
152544
152581
|
},
|
|
152545
152582
|
setSettings: async ({ deviceId, settings }) => {
|
|
@@ -152558,6 +152595,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
152558
152595
|
...buildEmptyState(),
|
|
152559
152596
|
lastFetchedAt: Date.now()
|
|
152560
152597
|
});
|
|
152598
|
+
else this.runtimeState.patchCapState(CAP_NAME, { supportedClasses: buildSupportedClasses() });
|
|
152561
152599
|
this.ctx.logger.info("Reolink native-object-detection cap registered", { tags: { deviceId: this.id } });
|
|
152562
152600
|
}
|
|
152563
152601
|
/**
|
|
@@ -154180,14 +154218,22 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
154180
154218
|
});
|
|
154181
154219
|
} catch {}
|
|
154182
154220
|
this.objectDetectionsSubscribed = false;
|
|
154183
|
-
if (this.isBattery) {
|
|
154184
|
-
this.ctx.logger.debug("Reolink objectDetections subscribe skipped — battery cam", { meta: { reason } });
|
|
154185
|
-
return;
|
|
154186
|
-
}
|
|
154187
154221
|
if (!isNativeObjectForwardingEnabled(this.runtimeState.getCapState("native-object-detection"))) {
|
|
154188
154222
|
this.ctx.logger.debug("Reolink objectDetections subscribe skipped — cap disabled", { meta: { reason } });
|
|
154189
154223
|
return;
|
|
154190
154224
|
}
|
|
154225
|
+
if (this.isBattery) {
|
|
154226
|
+
api.onDetection(this.handleObjectDetectionsBound);
|
|
154227
|
+
this.objectDetectionsSubscribed = true;
|
|
154228
|
+
this.ctx.logger.info("Reolink onboard boxes ride the open stream (battery cam)", {
|
|
154229
|
+
tags: { deviceId: this.id },
|
|
154230
|
+
meta: {
|
|
154231
|
+
reason,
|
|
154232
|
+
channel
|
|
154233
|
+
}
|
|
154234
|
+
});
|
|
154235
|
+
return;
|
|
154236
|
+
}
|
|
154191
154237
|
if (!api.client.isSocketConnected() || !api.client.loggedIn) {
|
|
154192
154238
|
this.ctx.logger.debug("Reolink objectDetections subscribe skipped — socket not ready", { meta: {
|
|
154193
154239
|
reason,
|
|
@@ -154213,6 +154259,11 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
154213
154259
|
*/
|
|
154214
154260
|
async unsubscribeObjectDetections(api) {
|
|
154215
154261
|
if (!this.objectDetectionsSubscribed) return;
|
|
154262
|
+
if (this.isBattery) {
|
|
154263
|
+
api.offDetection(this.handleObjectDetectionsBound);
|
|
154264
|
+
this.objectDetectionsSubscribed = false;
|
|
154265
|
+
return;
|
|
154266
|
+
}
|
|
154216
154267
|
try {
|
|
154217
154268
|
await api.offObjectDetections(this.handleObjectDetectionsBound, {
|
|
154218
154269
|
channel: this.getChannel(),
|
|
@@ -154242,6 +154293,7 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
154242
154293
|
*/
|
|
154243
154294
|
handleObjectDetections(event) {
|
|
154244
154295
|
if (!isNativeObjectForwardingEnabled(this.runtimeState.getCapState("native-object-detection"))) return;
|
|
154296
|
+
if (event.channel !== this.getChannel()) return;
|
|
154245
154297
|
if (event.boxes.length === 0) return;
|
|
154246
154298
|
const now = Date.now();
|
|
154247
154299
|
const payload = mapDetectionEvent(event, this.id, now);
|