@camstack/addon-provider-onvif 1.1.20 → 1.1.21
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 +117 -3
- package/dist/addon.mjs +117 -3
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -6937,10 +6937,18 @@ var ModelVariantGroupSchema = object({
|
|
|
6937
6937
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
6938
6938
|
/**
|
|
6939
6939
|
* Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
|
|
6940
|
-
* latency-optimized export (e.g. ReLU-activation
|
|
6941
|
-
*
|
|
6940
|
+
* latency-optimized export (e.g. ReLU-activation variant) — the slot the
|
|
6941
|
+
* future performance variants plug into.
|
|
6942
6942
|
*/
|
|
6943
|
-
optimization: _enum(["standard", "fast"]).optional()
|
|
6943
|
+
optimization: _enum(["standard", "fast"]).optional(),
|
|
6944
|
+
/**
|
|
6945
|
+
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
6946
|
+
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
6947
|
+
* cheap latency lever — especially on Apple ANE and the Intel N100 — at a
|
|
6948
|
+
* small-object accuracy cost. Mirrors the model's `inputSize` but lifted onto
|
|
6949
|
+
* the group so the selector can offer it as a variant axis.
|
|
6950
|
+
*/
|
|
6951
|
+
resolution: number().int().positive().optional()
|
|
6944
6952
|
});
|
|
6945
6953
|
var ModelCatalogEntrySchema = object({
|
|
6946
6954
|
id: string(),
|
|
@@ -8430,6 +8438,72 @@ var DeviceConfig = class DeviceConfig {
|
|
|
8430
8438
|
}));
|
|
8431
8439
|
}
|
|
8432
8440
|
};
|
|
8441
|
+
/** Reject after `ms`; always clears its own timer. */
|
|
8442
|
+
async function withTimeout(promise, ms, label) {
|
|
8443
|
+
let timer;
|
|
8444
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
8445
|
+
timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`${label} timed out after ${String(ms)}ms`)), ms);
|
|
8446
|
+
});
|
|
8447
|
+
try {
|
|
8448
|
+
return await Promise.race([promise, timeout]);
|
|
8449
|
+
} finally {
|
|
8450
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
8451
|
+
}
|
|
8452
|
+
}
|
|
8453
|
+
/**
|
|
8454
|
+
* Start the reachability poll loop. Returns a handle whose `stop()` clears the
|
|
8455
|
+
* timer and prevents any further ticks. Start on device activation, stop on
|
|
8456
|
+
* device teardown (`removeDevice`) so no timer leaks.
|
|
8457
|
+
*/
|
|
8458
|
+
function startReachabilityPoll(options) {
|
|
8459
|
+
const intervalMs = options.intervalMs ?? 3e4;
|
|
8460
|
+
const failuresToOffline = options.failuresToOffline ?? 3;
|
|
8461
|
+
const probeTimeoutMs = options.probeTimeoutMs ?? 1e4;
|
|
8462
|
+
const runImmediately = options.runImmediately ?? true;
|
|
8463
|
+
let stopped = false;
|
|
8464
|
+
let running = false;
|
|
8465
|
+
let consecutiveFailures = 0;
|
|
8466
|
+
let timer;
|
|
8467
|
+
const tick = async () => {
|
|
8468
|
+
if (stopped) return;
|
|
8469
|
+
if (running) return;
|
|
8470
|
+
if (options.isEnabled && !options.isEnabled()) return;
|
|
8471
|
+
running = true;
|
|
8472
|
+
try {
|
|
8473
|
+
const reachable = await withTimeout(Promise.resolve().then(options.probe), probeTimeoutMs, "reachability probe");
|
|
8474
|
+
if (stopped) return;
|
|
8475
|
+
if (reachable) {
|
|
8476
|
+
consecutiveFailures = 0;
|
|
8477
|
+
options.setOnline(true);
|
|
8478
|
+
} else registerFailure("probe resolved unreachable");
|
|
8479
|
+
} catch (error) {
|
|
8480
|
+
if (stopped) return;
|
|
8481
|
+
registerFailure(error instanceof Error ? error.message : "probe threw");
|
|
8482
|
+
} finally {
|
|
8483
|
+
running = false;
|
|
8484
|
+
}
|
|
8485
|
+
};
|
|
8486
|
+
const registerFailure = (reason) => {
|
|
8487
|
+
consecutiveFailures += 1;
|
|
8488
|
+
options.logger?.debug("reachability probe failed", {
|
|
8489
|
+
reason,
|
|
8490
|
+
consecutiveFailures,
|
|
8491
|
+
failuresToOffline
|
|
8492
|
+
});
|
|
8493
|
+
if (consecutiveFailures >= failuresToOffline) options.setOnline(false);
|
|
8494
|
+
};
|
|
8495
|
+
timer = setInterval(() => {
|
|
8496
|
+
tick();
|
|
8497
|
+
}, intervalMs);
|
|
8498
|
+
if (typeof timer === "object" && timer !== null && "unref" in timer) timer.unref();
|
|
8499
|
+
if (runImmediately) tick();
|
|
8500
|
+
return { stop: () => {
|
|
8501
|
+
if (stopped) return;
|
|
8502
|
+
stopped = true;
|
|
8503
|
+
if (timer !== void 0) clearInterval(timer);
|
|
8504
|
+
timer = void 0;
|
|
8505
|
+
} };
|
|
8506
|
+
}
|
|
8433
8507
|
/**
|
|
8434
8508
|
* Generic device-level status snapshot. Auto-registered by `BaseDevice`
|
|
8435
8509
|
* for every device, regardless of provider — the kernel needs a uniform
|
|
@@ -10725,6 +10799,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
10725
10799
|
})) }), object({ success: literal(true) }), {
|
|
10726
10800
|
kind: "mutation",
|
|
10727
10801
|
auth: "admin"
|
|
10802
|
+
}), method(object({ nodeId: string() }), object({
|
|
10803
|
+
success: literal(true),
|
|
10804
|
+
regeneratedModelId: string().nullable()
|
|
10805
|
+
}), {
|
|
10806
|
+
kind: "mutation",
|
|
10807
|
+
auth: "admin"
|
|
10728
10808
|
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({ steps: array(PipelineStepInputSchema) }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
|
|
10729
10809
|
name: string(),
|
|
10730
10810
|
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
@@ -21696,6 +21776,12 @@ Object.freeze({
|
|
|
21696
21776
|
addonId: null,
|
|
21697
21777
|
access: "create"
|
|
21698
21778
|
},
|
|
21779
|
+
"pipelineExecutor.resetToDefault": {
|
|
21780
|
+
capName: "pipeline-executor",
|
|
21781
|
+
capScope: "system",
|
|
21782
|
+
addonId: null,
|
|
21783
|
+
access: "delete"
|
|
21784
|
+
},
|
|
21699
21785
|
"pipelineExecutor.runAudioTest": {
|
|
21700
21786
|
capName: "pipeline-executor",
|
|
21701
21787
|
capScope: "system",
|
|
@@ -23378,6 +23464,10 @@ var OnvifCamera = class {
|
|
|
23378
23464
|
* `null` when the camera is being restored from DB without a live connection.
|
|
23379
23465
|
*/
|
|
23380
23466
|
client;
|
|
23467
|
+
/** Control-plane reachability poll — drives `online` from ONVIF
|
|
23468
|
+
* `getDeviceInformation` liveness, decoupled from stream-broker video
|
|
23469
|
+
* health. Started on `attachClient`, stopped on `removeDevice`. */
|
|
23470
|
+
reachabilityPoll = null;
|
|
23381
23471
|
constructor(ctx, initialData, client = null) {
|
|
23382
23472
|
this.ctx = ctx;
|
|
23383
23473
|
this.id = ctx.id;
|
|
@@ -23562,8 +23652,32 @@ var OnvifCamera = class {
|
|
|
23562
23652
|
attachClient(client) {
|
|
23563
23653
|
this.client = client;
|
|
23564
23654
|
this.online = true;
|
|
23655
|
+
this.startReachabilityPolling();
|
|
23656
|
+
}
|
|
23657
|
+
/** Start the control-plane reachability poll: an ONVIF
|
|
23658
|
+
* `getDeviceInformation` round-trip every 30s drives `online`, with
|
|
23659
|
+
* hysteresis. Replaces the old stream-health→online coupling so a
|
|
23660
|
+
* reachable on-demand camera still reports ONLINE. Re-armed on each
|
|
23661
|
+
* `attachClient` (reconnect) — the prior poll is stopped first. */
|
|
23662
|
+
startReachabilityPolling() {
|
|
23663
|
+
this.reachabilityPoll?.stop();
|
|
23664
|
+
this.reachabilityPoll = startReachabilityPoll({
|
|
23665
|
+
probe: async () => {
|
|
23666
|
+
const client = this.client;
|
|
23667
|
+
if (!client) return false;
|
|
23668
|
+
await client.getDeviceInfo();
|
|
23669
|
+
return true;
|
|
23670
|
+
},
|
|
23671
|
+
setOnline: (online) => {
|
|
23672
|
+
this.markOnline(online);
|
|
23673
|
+
},
|
|
23674
|
+
isEnabled: () => !this.disabled && this.client !== null,
|
|
23675
|
+
logger: this.ctx.logger
|
|
23676
|
+
});
|
|
23565
23677
|
}
|
|
23566
23678
|
async removeDevice() {
|
|
23679
|
+
this.reachabilityPoll?.stop();
|
|
23680
|
+
this.reachabilityPoll = null;
|
|
23567
23681
|
this.client?.disconnect();
|
|
23568
23682
|
this.client = null;
|
|
23569
23683
|
this.online = false;
|
package/dist/addon.mjs
CHANGED
|
@@ -6938,10 +6938,18 @@ var ModelVariantGroupSchema = object({
|
|
|
6938
6938
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
6939
6939
|
/**
|
|
6940
6940
|
* Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
|
|
6941
|
-
* latency-optimized export (e.g. ReLU-activation
|
|
6942
|
-
*
|
|
6941
|
+
* latency-optimized export (e.g. ReLU-activation variant) — the slot the
|
|
6942
|
+
* future performance variants plug into.
|
|
6943
6943
|
*/
|
|
6944
|
-
optimization: _enum(["standard", "fast"]).optional()
|
|
6944
|
+
optimization: _enum(["standard", "fast"]).optional(),
|
|
6945
|
+
/**
|
|
6946
|
+
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
6947
|
+
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
6948
|
+
* cheap latency lever — especially on Apple ANE and the Intel N100 — at a
|
|
6949
|
+
* small-object accuracy cost. Mirrors the model's `inputSize` but lifted onto
|
|
6950
|
+
* the group so the selector can offer it as a variant axis.
|
|
6951
|
+
*/
|
|
6952
|
+
resolution: number().int().positive().optional()
|
|
6945
6953
|
});
|
|
6946
6954
|
var ModelCatalogEntrySchema = object({
|
|
6947
6955
|
id: string(),
|
|
@@ -8431,6 +8439,72 @@ var DeviceConfig = class DeviceConfig {
|
|
|
8431
8439
|
}));
|
|
8432
8440
|
}
|
|
8433
8441
|
};
|
|
8442
|
+
/** Reject after `ms`; always clears its own timer. */
|
|
8443
|
+
async function withTimeout(promise, ms, label) {
|
|
8444
|
+
let timer;
|
|
8445
|
+
const timeout = new Promise((_resolve, reject) => {
|
|
8446
|
+
timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`${label} timed out after ${String(ms)}ms`)), ms);
|
|
8447
|
+
});
|
|
8448
|
+
try {
|
|
8449
|
+
return await Promise.race([promise, timeout]);
|
|
8450
|
+
} finally {
|
|
8451
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
8452
|
+
}
|
|
8453
|
+
}
|
|
8454
|
+
/**
|
|
8455
|
+
* Start the reachability poll loop. Returns a handle whose `stop()` clears the
|
|
8456
|
+
* timer and prevents any further ticks. Start on device activation, stop on
|
|
8457
|
+
* device teardown (`removeDevice`) so no timer leaks.
|
|
8458
|
+
*/
|
|
8459
|
+
function startReachabilityPoll(options) {
|
|
8460
|
+
const intervalMs = options.intervalMs ?? 3e4;
|
|
8461
|
+
const failuresToOffline = options.failuresToOffline ?? 3;
|
|
8462
|
+
const probeTimeoutMs = options.probeTimeoutMs ?? 1e4;
|
|
8463
|
+
const runImmediately = options.runImmediately ?? true;
|
|
8464
|
+
let stopped = false;
|
|
8465
|
+
let running = false;
|
|
8466
|
+
let consecutiveFailures = 0;
|
|
8467
|
+
let timer;
|
|
8468
|
+
const tick = async () => {
|
|
8469
|
+
if (stopped) return;
|
|
8470
|
+
if (running) return;
|
|
8471
|
+
if (options.isEnabled && !options.isEnabled()) return;
|
|
8472
|
+
running = true;
|
|
8473
|
+
try {
|
|
8474
|
+
const reachable = await withTimeout(Promise.resolve().then(options.probe), probeTimeoutMs, "reachability probe");
|
|
8475
|
+
if (stopped) return;
|
|
8476
|
+
if (reachable) {
|
|
8477
|
+
consecutiveFailures = 0;
|
|
8478
|
+
options.setOnline(true);
|
|
8479
|
+
} else registerFailure("probe resolved unreachable");
|
|
8480
|
+
} catch (error) {
|
|
8481
|
+
if (stopped) return;
|
|
8482
|
+
registerFailure(error instanceof Error ? error.message : "probe threw");
|
|
8483
|
+
} finally {
|
|
8484
|
+
running = false;
|
|
8485
|
+
}
|
|
8486
|
+
};
|
|
8487
|
+
const registerFailure = (reason) => {
|
|
8488
|
+
consecutiveFailures += 1;
|
|
8489
|
+
options.logger?.debug("reachability probe failed", {
|
|
8490
|
+
reason,
|
|
8491
|
+
consecutiveFailures,
|
|
8492
|
+
failuresToOffline
|
|
8493
|
+
});
|
|
8494
|
+
if (consecutiveFailures >= failuresToOffline) options.setOnline(false);
|
|
8495
|
+
};
|
|
8496
|
+
timer = setInterval(() => {
|
|
8497
|
+
tick();
|
|
8498
|
+
}, intervalMs);
|
|
8499
|
+
if (typeof timer === "object" && timer !== null && "unref" in timer) timer.unref();
|
|
8500
|
+
if (runImmediately) tick();
|
|
8501
|
+
return { stop: () => {
|
|
8502
|
+
if (stopped) return;
|
|
8503
|
+
stopped = true;
|
|
8504
|
+
if (timer !== void 0) clearInterval(timer);
|
|
8505
|
+
timer = void 0;
|
|
8506
|
+
} };
|
|
8507
|
+
}
|
|
8434
8508
|
/**
|
|
8435
8509
|
* Generic device-level status snapshot. Auto-registered by `BaseDevice`
|
|
8436
8510
|
* for every device, regardless of provider — the kernel needs a uniform
|
|
@@ -10726,6 +10800,12 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
10726
10800
|
})) }), object({ success: literal(true) }), {
|
|
10727
10801
|
kind: "mutation",
|
|
10728
10802
|
auth: "admin"
|
|
10803
|
+
}), method(object({ nodeId: string() }), object({
|
|
10804
|
+
success: literal(true),
|
|
10805
|
+
regeneratedModelId: string().nullable()
|
|
10806
|
+
}), {
|
|
10807
|
+
kind: "mutation",
|
|
10808
|
+
auth: "admin"
|
|
10729
10809
|
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({ steps: array(PipelineStepInputSchema) }), PipelineValidationResultSchema), method(_void(), array(PipelineTemplateSchema$1).readonly()), method(object({
|
|
10730
10810
|
name: string(),
|
|
10731
10811
|
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
@@ -21697,6 +21777,12 @@ Object.freeze({
|
|
|
21697
21777
|
addonId: null,
|
|
21698
21778
|
access: "create"
|
|
21699
21779
|
},
|
|
21780
|
+
"pipelineExecutor.resetToDefault": {
|
|
21781
|
+
capName: "pipeline-executor",
|
|
21782
|
+
capScope: "system",
|
|
21783
|
+
addonId: null,
|
|
21784
|
+
access: "delete"
|
|
21785
|
+
},
|
|
21700
21786
|
"pipelineExecutor.runAudioTest": {
|
|
21701
21787
|
capName: "pipeline-executor",
|
|
21702
21788
|
capScope: "system",
|
|
@@ -23379,6 +23465,10 @@ var OnvifCamera = class {
|
|
|
23379
23465
|
* `null` when the camera is being restored from DB without a live connection.
|
|
23380
23466
|
*/
|
|
23381
23467
|
client;
|
|
23468
|
+
/** Control-plane reachability poll — drives `online` from ONVIF
|
|
23469
|
+
* `getDeviceInformation` liveness, decoupled from stream-broker video
|
|
23470
|
+
* health. Started on `attachClient`, stopped on `removeDevice`. */
|
|
23471
|
+
reachabilityPoll = null;
|
|
23382
23472
|
constructor(ctx, initialData, client = null) {
|
|
23383
23473
|
this.ctx = ctx;
|
|
23384
23474
|
this.id = ctx.id;
|
|
@@ -23563,8 +23653,32 @@ var OnvifCamera = class {
|
|
|
23563
23653
|
attachClient(client) {
|
|
23564
23654
|
this.client = client;
|
|
23565
23655
|
this.online = true;
|
|
23656
|
+
this.startReachabilityPolling();
|
|
23657
|
+
}
|
|
23658
|
+
/** Start the control-plane reachability poll: an ONVIF
|
|
23659
|
+
* `getDeviceInformation` round-trip every 30s drives `online`, with
|
|
23660
|
+
* hysteresis. Replaces the old stream-health→online coupling so a
|
|
23661
|
+
* reachable on-demand camera still reports ONLINE. Re-armed on each
|
|
23662
|
+
* `attachClient` (reconnect) — the prior poll is stopped first. */
|
|
23663
|
+
startReachabilityPolling() {
|
|
23664
|
+
this.reachabilityPoll?.stop();
|
|
23665
|
+
this.reachabilityPoll = startReachabilityPoll({
|
|
23666
|
+
probe: async () => {
|
|
23667
|
+
const client = this.client;
|
|
23668
|
+
if (!client) return false;
|
|
23669
|
+
await client.getDeviceInfo();
|
|
23670
|
+
return true;
|
|
23671
|
+
},
|
|
23672
|
+
setOnline: (online) => {
|
|
23673
|
+
this.markOnline(online);
|
|
23674
|
+
},
|
|
23675
|
+
isEnabled: () => !this.disabled && this.client !== null,
|
|
23676
|
+
logger: this.ctx.logger
|
|
23677
|
+
});
|
|
23566
23678
|
}
|
|
23567
23679
|
async removeDevice() {
|
|
23680
|
+
this.reachabilityPoll?.stop();
|
|
23681
|
+
this.reachabilityPoll = null;
|
|
23568
23682
|
this.client?.disconnect();
|
|
23569
23683
|
this.client = null;
|
|
23570
23684
|
this.online = false;
|