@camstack/addon-provider-dreame 0.2.122 → 0.2.124
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 +325 -93
- package/dist/addon.mjs +325 -93
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -63368,6 +63368,15 @@ var ClipSearchStrictnessSchema = _enum([
|
|
|
63368
63368
|
"balanced",
|
|
63369
63369
|
"strict"
|
|
63370
63370
|
]);
|
|
63371
|
+
/** Steps whose effect a root label can BE. */
|
|
63372
|
+
var LABEL_SUPPLY_STEP_IDS = [
|
|
63373
|
+
"animal-classifier",
|
|
63374
|
+
"vehicle-classifier",
|
|
63375
|
+
"package-detection"
|
|
63376
|
+
];
|
|
63377
|
+
/** Steps whose box a root detection can BE. */
|
|
63378
|
+
var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
|
|
63379
|
+
[...LABEL_SUPPLY_STEP_IDS, ...CROP_SUPPLY_STEP_IDS];
|
|
63371
63380
|
var MODEL_FORMATS = [
|
|
63372
63381
|
"onnx",
|
|
63373
63382
|
"coreml",
|
|
@@ -63437,11 +63446,11 @@ var ModelVariantGroupSchema = object({
|
|
|
63437
63446
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
63438
63447
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
63439
63448
|
/**
|
|
63440
|
-
*
|
|
63441
|
-
*
|
|
63442
|
-
*
|
|
63449
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
63450
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
63451
|
+
* label is "Test".
|
|
63443
63452
|
*/
|
|
63444
|
-
optimization: _enum(["standard", "
|
|
63453
|
+
optimization: _enum(["standard", "test"]).optional(),
|
|
63445
63454
|
/**
|
|
63446
63455
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
63447
63456
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -63464,9 +63473,10 @@ var ModelProviderIdSchema = _enum([
|
|
|
63464
63473
|
* are per upstream. A persisted custom-model row written when this field was a
|
|
63465
63474
|
* string still parses — the string is lifted into `{ weights }`.
|
|
63466
63475
|
*
|
|
63467
|
-
* Every licence surface (the
|
|
63468
|
-
*
|
|
63469
|
-
*
|
|
63476
|
+
* Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
|
|
63477
|
+
* model table) is GENERATED from these records by
|
|
63478
|
+
* `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
|
|
63479
|
+
* `camstack/docs` → `/docs/detection/models`.
|
|
63470
63480
|
*/
|
|
63471
63481
|
var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
|
|
63472
63482
|
/** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
|
|
@@ -63499,6 +63509,35 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
|
|
|
63499
63509
|
/** True when the weights or their data forbid commercial use. */
|
|
63500
63510
|
nonCommercial: boolean().optional()
|
|
63501
63511
|
}));
|
|
63512
|
+
/**
|
|
63513
|
+
* One step a ROOT detector can supply from its own output (D730) — see
|
|
63514
|
+
* `ModelCatalogEntry.suppliesSteps`.
|
|
63515
|
+
*
|
|
63516
|
+
* - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
|
|
63517
|
+
* the root's label to the step's vocabulary; `uncovered` is the vocabulary
|
|
63518
|
+
* the root cannot produce (shown as unavailable, never a blocker).
|
|
63519
|
+
* - `crop`: the root draws the box the step would have found (`license_plate`
|
|
63520
|
+
* for plate-detection, `face` for face-detection). The box becomes a detail
|
|
63521
|
+
* child of the `parentMacro` detection that contains it — never a track.
|
|
63522
|
+
*/
|
|
63523
|
+
var RootStepSupplySchema = discriminatedUnion("kind", [object({
|
|
63524
|
+
kind: literal("label"),
|
|
63525
|
+
stepId: _enum(LABEL_SUPPLY_STEP_IDS),
|
|
63526
|
+
labelToEffect: record(string(), string()),
|
|
63527
|
+
uncovered: array(string()).readonly()
|
|
63528
|
+
}), object({
|
|
63529
|
+
kind: literal("crop"),
|
|
63530
|
+
stepId: _enum(CROP_SUPPLY_STEP_IDS),
|
|
63531
|
+
rootLabels: array(string()).readonly(),
|
|
63532
|
+
parentMacro: _enum(["vehicle", "person"]),
|
|
63533
|
+
childClass: _enum(["plate", "face"]),
|
|
63534
|
+
/**
|
|
63535
|
+
* The root's smaller input side, stamped on read by `rootSuppliesOf` from
|
|
63536
|
+
* the model entry — what a step's `minRootInputPx` gate judges. Never
|
|
63537
|
+
* stored by an import.
|
|
63538
|
+
*/
|
|
63539
|
+
rootInputPx: number().int().positive().optional()
|
|
63540
|
+
})]);
|
|
63502
63541
|
var ModelCatalogEntrySchema = object({
|
|
63503
63542
|
id: string(),
|
|
63504
63543
|
name: string(),
|
|
@@ -63625,6 +63664,16 @@ var ModelCatalogEntrySchema = object({
|
|
|
63625
63664
|
*/
|
|
63626
63665
|
classMap: DetectionCatalogClassMapSchema.optional(),
|
|
63627
63666
|
/**
|
|
63667
|
+
* The pipeline steps this ROOT detector can supply from its own output
|
|
63668
|
+
* (D730): its labels name a step's effect (`deer` for `animal-classifier`)
|
|
63669
|
+
* or draw a step's box (`license_plate` for `plate-detection`). Computed at
|
|
63670
|
+
* import from THIS model's labelmap by `deriveRootSupplies`, never written
|
|
63671
|
+
* by hand and never assumed per family; a row without it is derived on read
|
|
63672
|
+
* (`rootSuppliesOf`). Whether a camera uses it is the step's own
|
|
63673
|
+
* `useRootModel` flag (`resolveRootSupply`).
|
|
63674
|
+
*/
|
|
63675
|
+
suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
|
|
63676
|
+
/**
|
|
63628
63677
|
* The model's CLIP feature-space contract (text encoder, dimension, vector
|
|
63629
63678
|
* index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
|
|
63630
63679
|
* CLIP image encoder; its absence is what "not a CLIP model" means to the
|
|
@@ -67097,7 +67146,7 @@ DeviceType.Camera;
|
|
|
67097
67146
|
* This matters here more than anywhere else in the repo, because every provider
|
|
67098
67147
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
67099
67148
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
67100
|
-
* and `http://admin:hunter2@192.168.
|
|
67149
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
67101
67150
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
67102
67151
|
* filling it is the operator's business, not ours.
|
|
67103
67152
|
*
|
|
@@ -69090,6 +69139,18 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
|
|
|
69090
69139
|
kind: "mutation",
|
|
69091
69140
|
auth: "admin"
|
|
69092
69141
|
});
|
|
69142
|
+
function hostnameOf(baseUrl) {
|
|
69143
|
+
try {
|
|
69144
|
+
const host = new URL(baseUrl).hostname;
|
|
69145
|
+
return host.length > 0 ? host : null;
|
|
69146
|
+
} catch {
|
|
69147
|
+
return null;
|
|
69148
|
+
}
|
|
69149
|
+
}
|
|
69150
|
+
/** The bare hostname of a base URL, or `null` when it does not parse. */
|
|
69151
|
+
function hubAddressHostname(baseUrl) {
|
|
69152
|
+
return baseUrl === null ? null : hostnameOf(baseUrl);
|
|
69153
|
+
}
|
|
69093
69154
|
/**
|
|
69094
69155
|
* Transport bounds for AI capability methods.
|
|
69095
69156
|
*
|
|
@@ -70286,7 +70347,7 @@ method(object({
|
|
|
70286
70347
|
timeoutMs: 6e5
|
|
70287
70348
|
});
|
|
70288
70349
|
method(object({
|
|
70289
|
-
|
|
70350
|
+
targetNodeId: string(),
|
|
70290
70351
|
modelId: string(),
|
|
70291
70352
|
format: _enum(MODEL_FORMATS),
|
|
70292
70353
|
entry: ModelCatalogEntrySchema
|
|
@@ -71692,6 +71753,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
71692
71753
|
"stream-offline",
|
|
71693
71754
|
"node-online",
|
|
71694
71755
|
"node-offline",
|
|
71756
|
+
"node-restarting",
|
|
71757
|
+
"node-updating",
|
|
71695
71758
|
"node-inference-unavailable",
|
|
71696
71759
|
"detection-blind",
|
|
71697
71760
|
"addon-crash-loop",
|
|
@@ -72790,8 +72853,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
72790
72853
|
disabledTargetIds: array(string()).default([])
|
|
72791
72854
|
});
|
|
72792
72855
|
/**
|
|
72793
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
72794
|
-
* still-true state. `
|
|
72856
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
72857
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
72858
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
72795
72859
|
* job is not an open state, and the alarm stays instant.
|
|
72796
72860
|
*/
|
|
72797
72861
|
var NcStateSummarySectionIdSchema = _enum([
|
|
@@ -72803,6 +72867,7 @@ var NcStateSummarySectionIdSchema = _enum([
|
|
|
72803
72867
|
"detection-blind",
|
|
72804
72868
|
"nodes",
|
|
72805
72869
|
"addons",
|
|
72870
|
+
"addon-updates",
|
|
72806
72871
|
"updates"
|
|
72807
72872
|
]);
|
|
72808
72873
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -73283,7 +73348,19 @@ var NcAlarmModeDelaysListSchema = array(object({
|
|
|
73283
73348
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
73284
73349
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
73285
73350
|
*/
|
|
73286
|
-
schedule: NcScheduleSchema.optional()
|
|
73351
|
+
schedule: NcScheduleSchema.optional(),
|
|
73352
|
+
/**
|
|
73353
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
73354
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
73355
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
73356
|
+
*/
|
|
73357
|
+
notifyDuringEntryDelay: boolean().optional(),
|
|
73358
|
+
/**
|
|
73359
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
73360
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
73361
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
73362
|
+
*/
|
|
73363
|
+
notifySensorRewatched: boolean().optional()
|
|
73287
73364
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
73288
73365
|
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
73289
73366
|
mode: AlarmArmModeSchema,
|
|
@@ -73292,7 +73369,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
|
|
|
73292
73369
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
73293
73370
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
73294
73371
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
73295
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
73372
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
73373
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
73374
|
+
notifyDuringEntryDelay: boolean().nullable().optional(),
|
|
73375
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
73376
|
+
notifySensorRewatched: boolean().nullable().optional()
|
|
73296
73377
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
73297
73378
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
73298
73379
|
var NcAlarmNonBlockingEditSchema = object({
|
|
@@ -74253,39 +74334,19 @@ Object.freeze(Object.fromEntries([{
|
|
|
74253
74334
|
label: "Face recognition model",
|
|
74254
74335
|
defaultModelId: "auraface-r100",
|
|
74255
74336
|
indexName: "the enrolled face gallery",
|
|
74256
|
-
options: [
|
|
74257
|
-
|
|
74258
|
-
|
|
74259
|
-
|
|
74260
|
-
},
|
|
74261
|
-
{
|
|
74262
|
-
id: "arcface-r100",
|
|
74263
|
-
label: "ArcFace (ResNet34)"
|
|
74264
|
-
},
|
|
74265
|
-
{
|
|
74266
|
-
id: "inception-resnet-v1",
|
|
74267
|
-
label: "Inception ResNet V1"
|
|
74268
|
-
}
|
|
74269
|
-
]
|
|
74337
|
+
options: [{
|
|
74338
|
+
id: "auraface-r100",
|
|
74339
|
+
label: "AuraFace R100"
|
|
74340
|
+
}]
|
|
74270
74341
|
}, {
|
|
74271
74342
|
stepId: "clip-embedding",
|
|
74272
74343
|
label: "Semantic search model",
|
|
74273
|
-
defaultModelId: "
|
|
74344
|
+
defaultModelId: "siglip2-b16-224",
|
|
74274
74345
|
indexName: "the object semantic-search index",
|
|
74275
|
-
options: [
|
|
74276
|
-
|
|
74277
|
-
|
|
74278
|
-
|
|
74279
|
-
},
|
|
74280
|
-
{
|
|
74281
|
-
id: "mobileclip-s2",
|
|
74282
|
-
label: "MobileCLIP S2"
|
|
74283
|
-
},
|
|
74284
|
-
{
|
|
74285
|
-
id: "siglip2-b16-224",
|
|
74286
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
74287
|
-
}
|
|
74288
|
-
]
|
|
74346
|
+
options: [{
|
|
74347
|
+
id: "siglip2-b16-224",
|
|
74348
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
74349
|
+
}]
|
|
74289
74350
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
74290
74351
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
74291
74352
|
stepId: "face-embedding",
|
|
@@ -76211,6 +76272,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
76211
76272
|
timestamp: number()
|
|
76212
76273
|
});
|
|
76213
76274
|
/**
|
|
76275
|
+
* A root model's boxes standing in for one crop-kind step's own inference
|
|
76276
|
+
* (D730) — see `runPipeline.suppliedRoot`.
|
|
76277
|
+
*/
|
|
76278
|
+
var SuppliedRootOutputSchema = object({
|
|
76279
|
+
stepId: string(),
|
|
76280
|
+
/** The root model that drew the boxes — stamped on the result. */
|
|
76281
|
+
modelId: string(),
|
|
76282
|
+
detections: array(object({
|
|
76283
|
+
/** `[x1, y1, x2, y2]` in the pixels of the call's image. */
|
|
76284
|
+
bbox: tuple([
|
|
76285
|
+
number(),
|
|
76286
|
+
number(),
|
|
76287
|
+
number(),
|
|
76288
|
+
number()
|
|
76289
|
+
]),
|
|
76290
|
+
score: number(),
|
|
76291
|
+
/**
|
|
76292
|
+
* Five facial landmarks in the same pixels — a face the step's own
|
|
76293
|
+
* detector already re-found inside a root face box (D730), so its
|
|
76294
|
+
* embedder child aligns it exactly as it aligns any detected face.
|
|
76295
|
+
*/
|
|
76296
|
+
landmarks: array(object({
|
|
76297
|
+
x: number(),
|
|
76298
|
+
y: number()
|
|
76299
|
+
})).optional()
|
|
76300
|
+
})).min(1)
|
|
76301
|
+
});
|
|
76302
|
+
/**
|
|
76214
76303
|
* Reference to the frame's retained NATIVE surface + the parent crop's placement
|
|
76215
76304
|
* within the frame, so the executor can re-cut a leaf child ROI at native
|
|
76216
76305
|
* resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
|
|
@@ -76340,7 +76429,8 @@ var PipelineModelOptionSchema = object({
|
|
|
76340
76429
|
group: ModelVariantGroupSchema.optional(),
|
|
76341
76430
|
legacy: boolean().optional(),
|
|
76342
76431
|
provider: ModelProviderIdSchema.optional(),
|
|
76343
|
-
defaultConfidence: number().optional()
|
|
76432
|
+
defaultConfidence: number().optional(),
|
|
76433
|
+
suppliesSteps: array(RootStepSupplySchema).readonly().optional()
|
|
76344
76434
|
});
|
|
76345
76435
|
var ConfigFieldBridge = custom();
|
|
76346
76436
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -76608,7 +76698,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
76608
76698
|
* `device-not-servable`), and nothing reaches the camera's live
|
|
76609
76699
|
* trace stream. Absent ⇒ unchanged behaviour.
|
|
76610
76700
|
*/
|
|
76611
|
-
replay: literal(true).optional()
|
|
76701
|
+
replay: literal(true).optional(),
|
|
76702
|
+
/**
|
|
76703
|
+
* Root-supplied detections for the tree's ROOT step (D730). Set by
|
|
76704
|
+
* `runDetailSubtree` when the camera's root model supplies a crop-kind
|
|
76705
|
+
* step (a Frigate+ `license_plate` for `plate-detection`): the step is
|
|
76706
|
+
* NOT inferred, these boxes are its output, and its children (the plate
|
|
76707
|
+
* reader) run on them through their own crop policy. Boxes are in the
|
|
76708
|
+
* PIXELS of the image this call carries. Absent ⇒ the root step runs.
|
|
76709
|
+
*/
|
|
76710
|
+
suppliedRoot: SuppliedRootOutputSchema.optional()
|
|
76612
76711
|
}), PipelineRunResultBridge, { kind: "mutation" }), method(object({
|
|
76613
76712
|
steps: array(PipelineStepInputSchema).min(1),
|
|
76614
76713
|
frames: array(FrameInputSchema).min(1).max(255),
|
|
@@ -77173,6 +77272,22 @@ var MotionSourceEnum = _enum([
|
|
|
77173
77272
|
"device-activity"
|
|
77174
77273
|
]);
|
|
77175
77274
|
/**
|
|
77275
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
77276
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
77277
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
77278
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
77279
|
+
* absent when unknown or when the camera itself triggered.
|
|
77280
|
+
*
|
|
77281
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
77282
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
77283
|
+
* runner never decides anything on it.
|
|
77284
|
+
*/
|
|
77285
|
+
var SessionTriggerSchema = object({
|
|
77286
|
+
source: MotionSourceEnum,
|
|
77287
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
77288
|
+
sensorName: string().optional()
|
|
77289
|
+
});
|
|
77290
|
+
/**
|
|
77176
77291
|
* List of motion sources active on a camera. Empty array is valid:
|
|
77177
77292
|
* "no source" — happens for battery cams without firmware motion when
|
|
77178
77293
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -77424,6 +77539,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
77424
77539
|
*/
|
|
77425
77540
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
77426
77541
|
/**
|
|
77542
|
+
* What opened this attach, on a SESSION attach only (see
|
|
77543
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
77544
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
77545
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
77546
|
+
* runner then names no source on the phase event.
|
|
77547
|
+
*/
|
|
77548
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
77549
|
+
/**
|
|
77427
77550
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
77428
77551
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
77429
77552
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -77726,7 +77849,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
|
|
|
77726
77849
|
*/
|
|
77727
77850
|
cropJpeg: string().optional(),
|
|
77728
77851
|
parent: DetailParentSchema,
|
|
77729
|
-
steps: array(string()).optional()
|
|
77852
|
+
steps: array(string()).optional(),
|
|
77853
|
+
/**
|
|
77854
|
+
* The camera's root model already drew this step's boxes (D730): a
|
|
77855
|
+
* `license_plate` inside the parent vehicle. The named step is NOT
|
|
77856
|
+
* inferred — these FRAME-space boxes are its output — and its
|
|
77857
|
+
* requested children (the plate reader) run on them. Absent ⇒ every
|
|
77858
|
+
* requested step infers as before.
|
|
77859
|
+
*/
|
|
77860
|
+
supplied: object({
|
|
77861
|
+
stepId: string(),
|
|
77862
|
+
modelId: string(),
|
|
77863
|
+
boxes: array(object({
|
|
77864
|
+
bbox: NativeCropBboxSchema,
|
|
77865
|
+
score: number()
|
|
77866
|
+
})).min(1)
|
|
77867
|
+
}).optional()
|
|
77730
77868
|
}), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
|
|
77731
77869
|
/** Catalog step id, e.g. `clip-embedding`. */
|
|
77732
77870
|
stepId: string(),
|
|
@@ -84837,7 +84975,7 @@ var LocalInterfaceSchema = object({
|
|
|
84837
84975
|
name: string(),
|
|
84838
84976
|
family: _enum(["IPv4", "IPv6"]),
|
|
84839
84977
|
address: string(),
|
|
84840
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
84978
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
84841
84979
|
cidr: string(),
|
|
84842
84980
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
84843
84981
|
netmask: string(),
|
|
@@ -84891,7 +85029,8 @@ var ConnectionEndpointSchema = object({
|
|
|
84891
85029
|
"lan-ipv4",
|
|
84892
85030
|
"lan-ipv6",
|
|
84893
85031
|
"public",
|
|
84894
|
-
"loopback"
|
|
85032
|
+
"loopback",
|
|
85033
|
+
"app-link"
|
|
84895
85034
|
]),
|
|
84896
85035
|
/**
|
|
84897
85036
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -84960,15 +85099,27 @@ var GetConnectionEndpointsResultSchema = object({
|
|
|
84960
85099
|
localPort: AdvertisedLocalPortSchema
|
|
84961
85100
|
});
|
|
84962
85101
|
/**
|
|
84963
|
-
* The
|
|
84964
|
-
*
|
|
84965
|
-
*
|
|
85102
|
+
* The address flagged for notification links. `baseUrl: null` = AUTO, which
|
|
85103
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
85104
|
+
* so the UI can show it either way.
|
|
84966
85105
|
*/
|
|
84967
85106
|
var NotificationEndpointSchema = object({
|
|
84968
85107
|
/** The operator's explicit choice, or null for AUTO. */
|
|
84969
85108
|
baseUrl: string().nullable(),
|
|
84970
|
-
/**
|
|
84971
|
-
|
|
85109
|
+
/**
|
|
85110
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
85111
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
85112
|
+
* answered the public tunnel / mesh here, or null.
|
|
85113
|
+
*/
|
|
85114
|
+
resolved: string().nullable(),
|
|
85115
|
+
/**
|
|
85116
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
85117
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
85118
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
85119
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
85120
|
+
* Absent on a pre-D709 hub.
|
|
85121
|
+
*/
|
|
85122
|
+
appLinkHub: string().nullable()
|
|
84972
85123
|
});
|
|
84973
85124
|
/**
|
|
84974
85125
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -84981,6 +85132,27 @@ var ViewerEndpointsSchema = object({
|
|
|
84981
85132
|
/** What the ranking currently resolves to (may be empty if nothing is up). */
|
|
84982
85133
|
resolved: array(string()).readonly()
|
|
84983
85134
|
});
|
|
85135
|
+
/**
|
|
85136
|
+
* One audience's hub address (see `hub-address.ts`): the operator's stored
|
|
85137
|
+
* override, the address in use, and where it came from.
|
|
85138
|
+
*/
|
|
85139
|
+
var HubAddressSnapshotSchema = object({
|
|
85140
|
+
/** The operator's override, or null for automatic. */
|
|
85141
|
+
override: string().nullable(),
|
|
85142
|
+
/** The address in use, or null when nothing qualifies (never loopback). */
|
|
85143
|
+
resolved: string().nullable(),
|
|
85144
|
+
source: _enum([
|
|
85145
|
+
"override",
|
|
85146
|
+
"auto",
|
|
85147
|
+
"none"
|
|
85148
|
+
])
|
|
85149
|
+
});
|
|
85150
|
+
var HubAddressesSchema = object({
|
|
85151
|
+
/** "Hub address for agents" — agents' bundle/model pulls, LAN devices. */
|
|
85152
|
+
cluster: HubAddressSnapshotSchema,
|
|
85153
|
+
/** "Public address for sign-in links" — e-mail links, OIDC, WebAuthn, OAuth2. */
|
|
85154
|
+
browser: HubAddressSnapshotSchema
|
|
85155
|
+
});
|
|
84984
85156
|
var AllowedAddressesSchema = object({
|
|
84985
85157
|
/**
|
|
84986
85158
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -85022,8 +85194,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
85022
85194
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
85023
85195
|
* to avoid mixed-content blocks in the browser. The public
|
|
85024
85196
|
* tunnel always emits `https://` regardless. */
|
|
85025
|
-
scheme: _enum(["http", "https"]).optional()
|
|
85026
|
-
|
|
85197
|
+
scheme: _enum(["http", "https"]).optional(),
|
|
85198
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
85199
|
+
* an address notification links can be flagged with, not a hub
|
|
85200
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
85201
|
+
includeAppLink: boolean().optional()
|
|
85202
|
+
}), GetConnectionEndpointsResultSchema), method(_void(), NotificationEndpointSchema), method(object({ baseUrl: string().nullable() }), NotificationEndpointSchema, { kind: "mutation" }), method(_void(), ViewerEndpointsSchema), method(object({ baseUrls: array(string()).readonly() }), ViewerEndpointsSchema, { kind: "mutation" }), method(_void(), HubAddressesSchema), method(object({
|
|
85203
|
+
audience: _enum(["cluster", "browser"]),
|
|
85204
|
+
baseUrl: string().nullable()
|
|
85205
|
+
}), HubAddressesSchema, {
|
|
85206
|
+
kind: "mutation",
|
|
85207
|
+
auth: "admin"
|
|
85208
|
+
}), method(_void(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
|
|
85027
85209
|
kind: "mutation",
|
|
85028
85210
|
auth: "admin"
|
|
85029
85211
|
}), method(object({
|
|
@@ -85351,7 +85533,7 @@ var MeshPeerSchema = object({
|
|
|
85351
85533
|
tags: array(string()).readonly(),
|
|
85352
85534
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
85353
85535
|
exitNodeOption: boolean(),
|
|
85354
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
85536
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
85355
85537
|
advertisedRoutes: array(string()).readonly(),
|
|
85356
85538
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
85357
85539
|
userLogin: string().nullable(),
|
|
@@ -85481,7 +85663,8 @@ var MotionStatusSchema = object({
|
|
|
85481
85663
|
* writes this slice (not even a boot seed), and neither does the runner's
|
|
85482
85664
|
* phase machine: its phase is "a session is attached" for every on-motion
|
|
85483
85665
|
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
85484
|
-
* A provider's `isDetected`
|
|
85666
|
+
* A provider's `isDetected` and `getStatus` answer from the hub's slice
|
|
85667
|
+
* (`hubMotionNativeProvider`).
|
|
85485
85668
|
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
85486
85669
|
* imports) — the provider pushes both edges itself, from the upstream
|
|
85487
85670
|
* system's own state change. That is the sensor's own fact.
|
|
@@ -86827,7 +87010,13 @@ var OsdStatusSchema = object({ overlays: array(object({
|
|
|
86827
87010
|
*/
|
|
86828
87011
|
availablePositions: array(OsdPositionEnum).readonly(),
|
|
86829
87012
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
86830
|
-
readOnly: boolean().optional()
|
|
87013
|
+
readOnly: boolean().optional(),
|
|
87014
|
+
/**
|
|
87015
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
87016
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
87017
|
+
* copy on the binding.
|
|
87018
|
+
*/
|
|
87019
|
+
maxCharacters: number().int().positive().optional()
|
|
86831
87020
|
})).readonly() });
|
|
86832
87021
|
var OsdOverlayPatchSchema = object({
|
|
86833
87022
|
enabled: boolean().optional(),
|
|
@@ -86878,7 +87067,9 @@ var OsdTemplateBindingSchema = object({
|
|
|
86878
87067
|
valuePath: string().min(1).max(64),
|
|
86879
87068
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
86880
87069
|
displayUnit: string().max(16).optional(),
|
|
86881
|
-
maxDecimals: number().int().min(0).max(4).default(1)
|
|
87070
|
+
maxDecimals: number().int().min(0).max(4).default(1),
|
|
87071
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
87072
|
+
valueMap: record(string(), string()).optional()
|
|
86882
87073
|
});
|
|
86883
87074
|
/**
|
|
86884
87075
|
* A named template: bindings (alias → leaf field) + a parser that
|
|
@@ -86928,18 +87119,11 @@ var OsdSlotBindingSchema = object({
|
|
|
86928
87119
|
source: OsdSourceSchema,
|
|
86929
87120
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
86930
87121
|
template: string().max(96).default("${value}"),
|
|
86931
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
86932
|
-
maxCharacters: number().int().min(4).max(64).optional(),
|
|
86933
87122
|
/**
|
|
86934
87123
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
86935
87124
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
86936
87125
|
*/
|
|
86937
87126
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
86938
|
-
/**
|
|
86939
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
86940
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
86941
|
-
*/
|
|
86942
|
-
unitLabel: string().max(8).optional(),
|
|
86943
87127
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
86944
87128
|
valueMap: record(string(), string()).optional(),
|
|
86945
87129
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -86948,9 +87132,7 @@ var OsdSlotBindingSchema = object({
|
|
|
86948
87132
|
* Display gate, in the notification centre's condition vocabulary.
|
|
86949
87133
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
86950
87134
|
*/
|
|
86951
|
-
conditions: NcConditionsSchema.optional()
|
|
86952
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
86953
|
-
fallbackText: string().max(64).default("")
|
|
87135
|
+
conditions: NcConditionsSchema.optional()
|
|
86954
87136
|
});
|
|
86955
87137
|
/** One camera slot, as the operator sees it: firmware truth + our binding. */
|
|
86956
87138
|
var OsdSlotViewSchema = object({
|
|
@@ -96647,6 +96829,12 @@ Object.freeze({
|
|
|
96647
96829
|
addonId: null,
|
|
96648
96830
|
access: "view"
|
|
96649
96831
|
},
|
|
96832
|
+
"localNetwork.getHubAddresses": {
|
|
96833
|
+
capName: "local-network",
|
|
96834
|
+
capScope: "system",
|
|
96835
|
+
addonId: null,
|
|
96836
|
+
access: "view"
|
|
96837
|
+
},
|
|
96650
96838
|
"localNetwork.getNotificationEndpoint": {
|
|
96651
96839
|
capName: "local-network",
|
|
96652
96840
|
capScope: "system",
|
|
@@ -96701,6 +96889,12 @@ Object.freeze({
|
|
|
96701
96889
|
addonId: null,
|
|
96702
96890
|
access: "create"
|
|
96703
96891
|
},
|
|
96892
|
+
"localNetwork.setHubAddress": {
|
|
96893
|
+
capName: "local-network",
|
|
96894
|
+
capScope: "system",
|
|
96895
|
+
addonId: null,
|
|
96896
|
+
access: "create"
|
|
96897
|
+
},
|
|
96704
96898
|
"localNetwork.setNotificationEndpoint": {
|
|
96705
96899
|
capName: "local-network",
|
|
96706
96900
|
capScope: "system",
|
|
@@ -105100,6 +105294,8 @@ new Map(Object.entries({
|
|
|
105100
105294
|
"detection-blind": "device-events",
|
|
105101
105295
|
"node-online": "system",
|
|
105102
105296
|
"node-offline": "system",
|
|
105297
|
+
"node-restarting": "system",
|
|
105298
|
+
"node-updating": "system",
|
|
105103
105299
|
"node-inference-unavailable": "system",
|
|
105104
105300
|
"addon-crash-loop": "system",
|
|
105105
105301
|
"addon-update-available": "system",
|
|
@@ -105177,18 +105373,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
105177
105373
|
kinds: [
|
|
105178
105374
|
"node-offline",
|
|
105179
105375
|
"node-online",
|
|
105376
|
+
"node-restarting",
|
|
105180
105377
|
"node-inference-unavailable"
|
|
105181
105378
|
]
|
|
105182
105379
|
},
|
|
105183
105380
|
{
|
|
105184
105381
|
id: "addons",
|
|
105185
105382
|
family: "system",
|
|
105186
|
-
label: "Addons",
|
|
105187
|
-
kinds: [
|
|
105188
|
-
|
|
105189
|
-
|
|
105190
|
-
|
|
105191
|
-
|
|
105383
|
+
label: "Addons stopped",
|
|
105384
|
+
kinds: ["addon-crash-loop"]
|
|
105385
|
+
},
|
|
105386
|
+
{
|
|
105387
|
+
id: "addon-updates",
|
|
105388
|
+
family: "system",
|
|
105389
|
+
label: "Addon updates",
|
|
105390
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
105192
105391
|
},
|
|
105193
105392
|
{
|
|
105194
105393
|
id: "updates",
|
|
@@ -105196,6 +105395,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
105196
105395
|
label: "Server & container updates",
|
|
105197
105396
|
kinds: [
|
|
105198
105397
|
"server-update-available",
|
|
105398
|
+
"node-updating",
|
|
105199
105399
|
"server-updated",
|
|
105200
105400
|
"wrapper-update-available"
|
|
105201
105401
|
]
|
|
@@ -105343,18 +105543,21 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
105343
105543
|
kinds: [
|
|
105344
105544
|
"node-offline",
|
|
105345
105545
|
"node-online",
|
|
105546
|
+
"node-restarting",
|
|
105346
105547
|
"node-inference-unavailable"
|
|
105347
105548
|
]
|
|
105348
105549
|
},
|
|
105349
105550
|
{
|
|
105350
105551
|
name: "summaryAddons",
|
|
105351
|
-
label: "Summary: addons",
|
|
105352
|
-
example: "
|
|
105353
|
-
kinds: [
|
|
105354
|
-
|
|
105355
|
-
|
|
105356
|
-
|
|
105357
|
-
|
|
105552
|
+
label: "Summary: addons stopped",
|
|
105553
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
105554
|
+
kinds: ["addon-crash-loop"]
|
|
105555
|
+
},
|
|
105556
|
+
{
|
|
105557
|
+
name: "summaryAddonUpdates",
|
|
105558
|
+
label: "Summary: addon updates",
|
|
105559
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
105560
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
105358
105561
|
},
|
|
105359
105562
|
{
|
|
105360
105563
|
name: "summaryUpdates",
|
|
@@ -105362,6 +105565,7 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
105362
105565
|
example: "server 1.2.377 → 1.2.378",
|
|
105363
105566
|
kinds: [
|
|
105364
105567
|
"server-update-available",
|
|
105568
|
+
"node-updating",
|
|
105365
105569
|
"server-updated",
|
|
105366
105570
|
"wrapper-update-available"
|
|
105367
105571
|
]
|
|
@@ -105394,7 +105598,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
105394
105598
|
{
|
|
105395
105599
|
name: "summarySection",
|
|
105396
105600
|
label: "Summary: this section",
|
|
105397
|
-
description: "The section a per-section summary row is about
|
|
105601
|
+
description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
|
|
105398
105602
|
example: "Batterie scariche",
|
|
105399
105603
|
group: "system",
|
|
105400
105604
|
families: ["rule"],
|
|
@@ -105438,6 +105642,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
105438
105642
|
[...RULE_BODY_ONLY],
|
|
105439
105643
|
[...RULE_TEXT],
|
|
105440
105644
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
105645
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
105441
105646
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
105442
105647
|
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
105443
105648
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
@@ -105478,6 +105683,8 @@ var STATE_SUMMARY_VARS = [
|
|
|
105478
105683
|
[...RULE_TEXT],
|
|
105479
105684
|
[...RULE_TEXT],
|
|
105480
105685
|
[...RULE_TEXT],
|
|
105686
|
+
[...RULE_TEXT],
|
|
105687
|
+
[...RULE_TEXT],
|
|
105481
105688
|
...STATE_SUMMARY_VARS
|
|
105482
105689
|
];
|
|
105483
105690
|
new Set([
|
|
@@ -108392,6 +108599,18 @@ function nextVacuumControlSlice(prev, next) {
|
|
|
108392
108599
|
}
|
|
108393
108600
|
//#endregion
|
|
108394
108601
|
//#region src/devices/dreame-camera-stream.ts
|
|
108602
|
+
/**
|
|
108603
|
+
* The robot camera as a stream the broker can pull — the pure facts.
|
|
108604
|
+
*
|
|
108605
|
+
* A Dreame relay carries video only between `open()` and `close()`, and the
|
|
108606
|
+
* robot runs on a battery, so the camera cannot sit in the catalog with a
|
|
108607
|
+
* URL the way a mains RTSP camera does. The seam is the broker's own battery
|
|
108608
|
+
* path: `battery.wakeForStream` opens the monitor, and the catalog then
|
|
108609
|
+
* names the local RFC 4571 server (`dreame-rfc4571-server.ts`) the broker
|
|
108610
|
+
* pulls. While the monitor is CLOSED the
|
|
108611
|
+
* catalog carries the broker's lazy sentinel (Reolink's shape): the stream is
|
|
108612
|
+
* listed, and the first dial asks the publisher to materialize it.
|
|
108613
|
+
*/
|
|
108395
108614
|
/** The one stream the robot camera offers. Half of the broker id (`<deviceId>/live`). */
|
|
108396
108615
|
var CAMERA_STREAM_ID = "live";
|
|
108397
108616
|
/** The plugin's cap: a monitor never outlives this, whoever is watching. */
|
|
@@ -108471,17 +108690,13 @@ function cameraStreamCatalog(session) {
|
|
|
108471
108690
|
/**
|
|
108472
108691
|
* The host the broker is told to dial. The provider and the ingest owner
|
|
108473
108692
|
* share the hub today, but a broker on another node reaches the hub only
|
|
108474
|
-
* through
|
|
108475
|
-
*
|
|
108693
|
+
* through the hub's address for agents — `local-network.getHubAddresses()
|
|
108694
|
+
* .cluster` (the Network page's override, else the detected LAN address).
|
|
108695
|
+
* Loopback when that names nothing: then the only broker that can dial at
|
|
108696
|
+
* all is this node's own.
|
|
108476
108697
|
*/
|
|
108477
|
-
function advertisedRfcHost(
|
|
108478
|
-
|
|
108479
|
-
try {
|
|
108480
|
-
const host = new URL(hubPublicUrl).hostname;
|
|
108481
|
-
return host.length > 0 ? host : "127.0.0.1";
|
|
108482
|
-
} catch {
|
|
108483
|
-
return "127.0.0.1";
|
|
108484
|
-
}
|
|
108698
|
+
function advertisedRfcHost(clusterBaseUrl) {
|
|
108699
|
+
return hubAddressHostname(clusterBaseUrl) ?? "127.0.0.1";
|
|
108485
108700
|
}
|
|
108486
108701
|
function rfcUrl(host, port) {
|
|
108487
108702
|
return `tcp://${host}:${String(port)}`;
|
|
@@ -154871,6 +155086,23 @@ var DreameCameraDevice = class extends DreameChildDevice {
|
|
|
154871
155086
|
}
|
|
154872
155087
|
unsubscribeRefresh = null;
|
|
154873
155088
|
/** Register the stream on the broker — the server, or the lazy sentinel (push semantics; the catalog is the durable copy). */
|
|
155089
|
+
/**
|
|
155090
|
+
* The hub's address for agents (`local-network.getHubAddresses().cluster`:
|
|
155091
|
+
* the Network page's override, else the detected LAN address). A failed
|
|
155092
|
+
* read is `null` — `advertisedRfcHost` then answers loopback, which this
|
|
155093
|
+
* node's own broker can still dial.
|
|
155094
|
+
*/
|
|
155095
|
+
async hubClusterAddress() {
|
|
155096
|
+
try {
|
|
155097
|
+
return (await this.ctx.api.localNetwork.getHubAddresses.query()).cluster.resolved;
|
|
155098
|
+
} catch (err) {
|
|
155099
|
+
this.ctx.logger.warn("robot camera: hub address unavailable — advertising loopback", {
|
|
155100
|
+
tags: { deviceId: this.id },
|
|
155101
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
155102
|
+
});
|
|
155103
|
+
return null;
|
|
155104
|
+
}
|
|
155105
|
+
}
|
|
154874
155106
|
async publishRelay(session) {
|
|
154875
155107
|
const [descriptor] = cameraStreamCatalog(session);
|
|
154876
155108
|
if (descriptor === void 0) return;
|
|
@@ -154956,7 +155188,7 @@ var DreameCameraDevice = class extends DreameChildDevice {
|
|
|
154956
155188
|
rfc
|
|
154957
155189
|
};
|
|
154958
155190
|
this.session = {
|
|
154959
|
-
url: rfcUrl(advertisedRfcHost(
|
|
155191
|
+
url: rfcUrl(advertisedRfcHost(await this.hubClusterAddress()), rfc.port),
|
|
154960
155192
|
sdp: rfc.sdp
|
|
154961
155193
|
};
|
|
154962
155194
|
this.sessionOpenedAt = Date.now();
|