@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.mjs
CHANGED
|
@@ -63365,6 +63365,15 @@ var ClipSearchStrictnessSchema = _enum([
|
|
|
63365
63365
|
"balanced",
|
|
63366
63366
|
"strict"
|
|
63367
63367
|
]);
|
|
63368
|
+
/** Steps whose effect a root label can BE. */
|
|
63369
|
+
var LABEL_SUPPLY_STEP_IDS = [
|
|
63370
|
+
"animal-classifier",
|
|
63371
|
+
"vehicle-classifier",
|
|
63372
|
+
"package-detection"
|
|
63373
|
+
];
|
|
63374
|
+
/** Steps whose box a root detection can BE. */
|
|
63375
|
+
var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
|
|
63376
|
+
[...LABEL_SUPPLY_STEP_IDS, ...CROP_SUPPLY_STEP_IDS];
|
|
63368
63377
|
var MODEL_FORMATS = [
|
|
63369
63378
|
"onnx",
|
|
63370
63379
|
"coreml",
|
|
@@ -63434,11 +63443,11 @@ var ModelVariantGroupSchema = object({
|
|
|
63434
63443
|
/** Quantization axis. Omit ⇒ the fp32 base build. */
|
|
63435
63444
|
precision: _enum(["fp32", "int8"]).optional(),
|
|
63436
63445
|
/**
|
|
63437
|
-
*
|
|
63438
|
-
*
|
|
63439
|
-
*
|
|
63446
|
+
* Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
|
|
63447
|
+
* an alternate training of the same family (Scrypted `relu_test`); chip
|
|
63448
|
+
* label is "Test".
|
|
63440
63449
|
*/
|
|
63441
|
-
optimization: _enum(["standard", "
|
|
63450
|
+
optimization: _enum(["standard", "test"]).optional(),
|
|
63442
63451
|
/**
|
|
63443
63452
|
* Input-resolution axis (square input side, px). Omit ⇒ the family's native
|
|
63444
63453
|
* resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
|
|
@@ -63461,9 +63470,10 @@ var ModelProviderIdSchema = _enum([
|
|
|
63461
63470
|
* are per upstream. A persisted custom-model row written when this field was a
|
|
63462
63471
|
* string still parses — the string is lifted into `{ weights }`.
|
|
63463
63472
|
*
|
|
63464
|
-
* Every licence surface (the
|
|
63465
|
-
*
|
|
63466
|
-
*
|
|
63473
|
+
* Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
|
|
63474
|
+
* model table) is GENERATED from these records by
|
|
63475
|
+
* `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
|
|
63476
|
+
* `camstack/docs` → `/docs/detection/models`.
|
|
63467
63477
|
*/
|
|
63468
63478
|
var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
|
|
63469
63479
|
/** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
|
|
@@ -63496,6 +63506,35 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
|
|
|
63496
63506
|
/** True when the weights or their data forbid commercial use. */
|
|
63497
63507
|
nonCommercial: boolean().optional()
|
|
63498
63508
|
}));
|
|
63509
|
+
/**
|
|
63510
|
+
* One step a ROOT detector can supply from its own output (D730) — see
|
|
63511
|
+
* `ModelCatalogEntry.suppliesSteps`.
|
|
63512
|
+
*
|
|
63513
|
+
* - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
|
|
63514
|
+
* the root's label to the step's vocabulary; `uncovered` is the vocabulary
|
|
63515
|
+
* the root cannot produce (shown as unavailable, never a blocker).
|
|
63516
|
+
* - `crop`: the root draws the box the step would have found (`license_plate`
|
|
63517
|
+
* for plate-detection, `face` for face-detection). The box becomes a detail
|
|
63518
|
+
* child of the `parentMacro` detection that contains it — never a track.
|
|
63519
|
+
*/
|
|
63520
|
+
var RootStepSupplySchema = discriminatedUnion("kind", [object({
|
|
63521
|
+
kind: literal("label"),
|
|
63522
|
+
stepId: _enum(LABEL_SUPPLY_STEP_IDS),
|
|
63523
|
+
labelToEffect: record(string(), string()),
|
|
63524
|
+
uncovered: array(string()).readonly()
|
|
63525
|
+
}), object({
|
|
63526
|
+
kind: literal("crop"),
|
|
63527
|
+
stepId: _enum(CROP_SUPPLY_STEP_IDS),
|
|
63528
|
+
rootLabels: array(string()).readonly(),
|
|
63529
|
+
parentMacro: _enum(["vehicle", "person"]),
|
|
63530
|
+
childClass: _enum(["plate", "face"]),
|
|
63531
|
+
/**
|
|
63532
|
+
* The root's smaller input side, stamped on read by `rootSuppliesOf` from
|
|
63533
|
+
* the model entry — what a step's `minRootInputPx` gate judges. Never
|
|
63534
|
+
* stored by an import.
|
|
63535
|
+
*/
|
|
63536
|
+
rootInputPx: number().int().positive().optional()
|
|
63537
|
+
})]);
|
|
63499
63538
|
var ModelCatalogEntrySchema = object({
|
|
63500
63539
|
id: string(),
|
|
63501
63540
|
name: string(),
|
|
@@ -63622,6 +63661,16 @@ var ModelCatalogEntrySchema = object({
|
|
|
63622
63661
|
*/
|
|
63623
63662
|
classMap: DetectionCatalogClassMapSchema.optional(),
|
|
63624
63663
|
/**
|
|
63664
|
+
* The pipeline steps this ROOT detector can supply from its own output
|
|
63665
|
+
* (D730): its labels name a step's effect (`deer` for `animal-classifier`)
|
|
63666
|
+
* or draw a step's box (`license_plate` for `plate-detection`). Computed at
|
|
63667
|
+
* import from THIS model's labelmap by `deriveRootSupplies`, never written
|
|
63668
|
+
* by hand and never assumed per family; a row without it is derived on read
|
|
63669
|
+
* (`rootSuppliesOf`). Whether a camera uses it is the step's own
|
|
63670
|
+
* `useRootModel` flag (`resolveRootSupply`).
|
|
63671
|
+
*/
|
|
63672
|
+
suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
|
|
63673
|
+
/**
|
|
63625
63674
|
* The model's CLIP feature-space contract (text encoder, dimension, vector
|
|
63626
63675
|
* index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
|
|
63627
63676
|
* CLIP image encoder; its absence is what "not a CLIP model" means to the
|
|
@@ -67094,7 +67143,7 @@ DeviceType.Camera;
|
|
|
67094
67143
|
* This matters here more than anywhere else in the repo, because every provider
|
|
67095
67144
|
* that knows a device's host knows its PASSWORD too: `{ host, port, username,
|
|
67096
67145
|
* password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
|
|
67097
|
-
* and `http://admin:hunter2@192.168.
|
|
67146
|
+
* and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
|
|
67098
67147
|
* camera's own page will ask for its own login. That is correct, and pre-
|
|
67099
67148
|
* filling it is the operator's business, not ours.
|
|
67100
67149
|
*
|
|
@@ -69087,6 +69136,18 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
|
|
|
69087
69136
|
kind: "mutation",
|
|
69088
69137
|
auth: "admin"
|
|
69089
69138
|
});
|
|
69139
|
+
function hostnameOf(baseUrl) {
|
|
69140
|
+
try {
|
|
69141
|
+
const host = new URL(baseUrl).hostname;
|
|
69142
|
+
return host.length > 0 ? host : null;
|
|
69143
|
+
} catch {
|
|
69144
|
+
return null;
|
|
69145
|
+
}
|
|
69146
|
+
}
|
|
69147
|
+
/** The bare hostname of a base URL, or `null` when it does not parse. */
|
|
69148
|
+
function hubAddressHostname(baseUrl) {
|
|
69149
|
+
return baseUrl === null ? null : hostnameOf(baseUrl);
|
|
69150
|
+
}
|
|
69090
69151
|
/**
|
|
69091
69152
|
* Transport bounds for AI capability methods.
|
|
69092
69153
|
*
|
|
@@ -70283,7 +70344,7 @@ method(object({
|
|
|
70283
70344
|
timeoutMs: 6e5
|
|
70284
70345
|
});
|
|
70285
70346
|
method(object({
|
|
70286
|
-
|
|
70347
|
+
targetNodeId: string(),
|
|
70287
70348
|
modelId: string(),
|
|
70288
70349
|
format: _enum(MODEL_FORMATS),
|
|
70289
70350
|
entry: ModelCatalogEntrySchema
|
|
@@ -71689,6 +71750,8 @@ var NcSystemEventKindSchema = _enum([
|
|
|
71689
71750
|
"stream-offline",
|
|
71690
71751
|
"node-online",
|
|
71691
71752
|
"node-offline",
|
|
71753
|
+
"node-restarting",
|
|
71754
|
+
"node-updating",
|
|
71692
71755
|
"node-inference-unavailable",
|
|
71693
71756
|
"detection-blind",
|
|
71694
71757
|
"addon-crash-loop",
|
|
@@ -72787,8 +72850,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
|
|
|
72787
72850
|
disabledTargetIds: array(string()).default([])
|
|
72788
72851
|
});
|
|
72789
72852
|
/**
|
|
72790
|
-
* The state-summary SECTIONS (D647 / D698): the D637 kind groups that
|
|
72791
|
-
* still-true state. `
|
|
72853
|
+
* The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
|
|
72854
|
+
* report a still-true state. `addons` is the crash-looped addons only and
|
|
72855
|
+
* `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
|
|
72792
72856
|
* job is not an open state, and the alarm stays instant.
|
|
72793
72857
|
*/
|
|
72794
72858
|
var NcStateSummarySectionIdSchema = _enum([
|
|
@@ -72800,6 +72864,7 @@ var NcStateSummarySectionIdSchema = _enum([
|
|
|
72800
72864
|
"detection-blind",
|
|
72801
72865
|
"nodes",
|
|
72802
72866
|
"addons",
|
|
72867
|
+
"addon-updates",
|
|
72803
72868
|
"updates"
|
|
72804
72869
|
]);
|
|
72805
72870
|
/** One section of a previewed state summary. `unavailable` = its state could not be read. */
|
|
@@ -73280,7 +73345,19 @@ var NcAlarmModeDelaysListSchema = array(object({
|
|
|
73280
73345
|
* When this mode may be armed. Absent / null = always allowed (same as a
|
|
73281
73346
|
* rule with no `schedule`). Evaluated with {@link isScheduleActive}.
|
|
73282
73347
|
*/
|
|
73283
|
-
schedule: NcScheduleSchema.optional()
|
|
73348
|
+
schedule: NcScheduleSchema.optional(),
|
|
73349
|
+
/**
|
|
73350
|
+
* D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
|
|
73351
|
+
* intrusion naming the locations)? Absent = false — the entry-delay notification is the
|
|
73352
|
+
* only one, and the matches ride the triggered notification's mosaic (D705).
|
|
73353
|
+
*/
|
|
73354
|
+
notifyDuringEntryDelay: boolean().optional(),
|
|
73355
|
+
/**
|
|
73356
|
+
* D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
|
|
73357
|
+
* Absent = false (logged, not sent). Even when true it is not sent when that same sensor
|
|
73358
|
+
* is the one that starts the entry delay — the entry-delay notification already names it.
|
|
73359
|
+
*/
|
|
73360
|
+
notifySensorRewatched: boolean().optional()
|
|
73284
73361
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
|
|
73285
73362
|
var NcAlarmModeDelaysEditListSchema = array(object({
|
|
73286
73363
|
mode: AlarmArmModeSchema,
|
|
@@ -73289,7 +73366,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
|
|
|
73289
73366
|
triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
|
|
73290
73367
|
postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
|
|
73291
73368
|
/** Set a schedule, or `null` to clear (mode always allowed again). */
|
|
73292
|
-
schedule: NcScheduleSchema.nullable().optional()
|
|
73369
|
+
schedule: NcScheduleSchema.nullable().optional(),
|
|
73370
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
73371
|
+
notifyDuringEntryDelay: boolean().nullable().optional(),
|
|
73372
|
+
/** D706: set the switch, or `null` to clear it (back to the default, false). */
|
|
73373
|
+
notifySensorRewatched: boolean().nullable().optional()
|
|
73293
73374
|
})).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
|
|
73294
73375
|
/** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
|
|
73295
73376
|
var NcAlarmNonBlockingEditSchema = object({
|
|
@@ -74250,39 +74331,19 @@ Object.freeze(Object.fromEntries([{
|
|
|
74250
74331
|
label: "Face recognition model",
|
|
74251
74332
|
defaultModelId: "auraface-r100",
|
|
74252
74333
|
indexName: "the enrolled face gallery",
|
|
74253
|
-
options: [
|
|
74254
|
-
|
|
74255
|
-
|
|
74256
|
-
|
|
74257
|
-
},
|
|
74258
|
-
{
|
|
74259
|
-
id: "arcface-r100",
|
|
74260
|
-
label: "ArcFace (ResNet34)"
|
|
74261
|
-
},
|
|
74262
|
-
{
|
|
74263
|
-
id: "inception-resnet-v1",
|
|
74264
|
-
label: "Inception ResNet V1"
|
|
74265
|
-
}
|
|
74266
|
-
]
|
|
74334
|
+
options: [{
|
|
74335
|
+
id: "auraface-r100",
|
|
74336
|
+
label: "AuraFace R100"
|
|
74337
|
+
}]
|
|
74267
74338
|
}, {
|
|
74268
74339
|
stepId: "clip-embedding",
|
|
74269
74340
|
label: "Semantic search model",
|
|
74270
|
-
defaultModelId: "
|
|
74341
|
+
defaultModelId: "siglip2-b16-224",
|
|
74271
74342
|
indexName: "the object semantic-search index",
|
|
74272
|
-
options: [
|
|
74273
|
-
|
|
74274
|
-
|
|
74275
|
-
|
|
74276
|
-
},
|
|
74277
|
-
{
|
|
74278
|
-
id: "mobileclip-s2",
|
|
74279
|
-
label: "MobileCLIP S2"
|
|
74280
|
-
},
|
|
74281
|
-
{
|
|
74282
|
-
id: "siglip2-b16-224",
|
|
74283
|
-
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
74284
|
-
}
|
|
74285
|
-
]
|
|
74343
|
+
options: [{
|
|
74344
|
+
id: "siglip2-b16-224",
|
|
74345
|
+
label: "SigLIP2 B/16 (Apache-2.0)"
|
|
74346
|
+
}]
|
|
74286
74347
|
}].map((s) => [s.stepId, s.defaultModelId])));
|
|
74287
74348
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
74288
74349
|
stepId: "face-embedding",
|
|
@@ -76208,6 +76269,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
76208
76269
|
timestamp: number()
|
|
76209
76270
|
});
|
|
76210
76271
|
/**
|
|
76272
|
+
* A root model's boxes standing in for one crop-kind step's own inference
|
|
76273
|
+
* (D730) — see `runPipeline.suppliedRoot`.
|
|
76274
|
+
*/
|
|
76275
|
+
var SuppliedRootOutputSchema = object({
|
|
76276
|
+
stepId: string(),
|
|
76277
|
+
/** The root model that drew the boxes — stamped on the result. */
|
|
76278
|
+
modelId: string(),
|
|
76279
|
+
detections: array(object({
|
|
76280
|
+
/** `[x1, y1, x2, y2]` in the pixels of the call's image. */
|
|
76281
|
+
bbox: tuple([
|
|
76282
|
+
number(),
|
|
76283
|
+
number(),
|
|
76284
|
+
number(),
|
|
76285
|
+
number()
|
|
76286
|
+
]),
|
|
76287
|
+
score: number(),
|
|
76288
|
+
/**
|
|
76289
|
+
* Five facial landmarks in the same pixels — a face the step's own
|
|
76290
|
+
* detector already re-found inside a root face box (D730), so its
|
|
76291
|
+
* embedder child aligns it exactly as it aligns any detected face.
|
|
76292
|
+
*/
|
|
76293
|
+
landmarks: array(object({
|
|
76294
|
+
x: number(),
|
|
76295
|
+
y: number()
|
|
76296
|
+
})).optional()
|
|
76297
|
+
})).min(1)
|
|
76298
|
+
});
|
|
76299
|
+
/**
|
|
76211
76300
|
* Reference to the frame's retained NATIVE surface + the parent crop's placement
|
|
76212
76301
|
* within the frame, so the executor can re-cut a leaf child ROI at native
|
|
76213
76302
|
* resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
|
|
@@ -76337,7 +76426,8 @@ var PipelineModelOptionSchema = object({
|
|
|
76337
76426
|
group: ModelVariantGroupSchema.optional(),
|
|
76338
76427
|
legacy: boolean().optional(),
|
|
76339
76428
|
provider: ModelProviderIdSchema.optional(),
|
|
76340
|
-
defaultConfidence: number().optional()
|
|
76429
|
+
defaultConfidence: number().optional(),
|
|
76430
|
+
suppliesSteps: array(RootStepSupplySchema).readonly().optional()
|
|
76341
76431
|
});
|
|
76342
76432
|
var ConfigFieldBridge = custom();
|
|
76343
76433
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -76605,7 +76695,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
76605
76695
|
* `device-not-servable`), and nothing reaches the camera's live
|
|
76606
76696
|
* trace stream. Absent ⇒ unchanged behaviour.
|
|
76607
76697
|
*/
|
|
76608
|
-
replay: literal(true).optional()
|
|
76698
|
+
replay: literal(true).optional(),
|
|
76699
|
+
/**
|
|
76700
|
+
* Root-supplied detections for the tree's ROOT step (D730). Set by
|
|
76701
|
+
* `runDetailSubtree` when the camera's root model supplies a crop-kind
|
|
76702
|
+
* step (a Frigate+ `license_plate` for `plate-detection`): the step is
|
|
76703
|
+
* NOT inferred, these boxes are its output, and its children (the plate
|
|
76704
|
+
* reader) run on them through their own crop policy. Boxes are in the
|
|
76705
|
+
* PIXELS of the image this call carries. Absent ⇒ the root step runs.
|
|
76706
|
+
*/
|
|
76707
|
+
suppliedRoot: SuppliedRootOutputSchema.optional()
|
|
76609
76708
|
}), PipelineRunResultBridge, { kind: "mutation" }), method(object({
|
|
76610
76709
|
steps: array(PipelineStepInputSchema).min(1),
|
|
76611
76710
|
frames: array(FrameInputSchema).min(1).max(255),
|
|
@@ -77170,6 +77269,22 @@ var MotionSourceEnum = _enum([
|
|
|
77170
77269
|
"device-activity"
|
|
77171
77270
|
]);
|
|
77172
77271
|
/**
|
|
77272
|
+
* What opened an on-motion detection SESSION: the motion source that passed the
|
|
77273
|
+
* camera's `motionSources` gate, and what raised it (the camera itself, or a
|
|
77274
|
+
* sensor the operator attached — D672). `sensorName` is the attached sensor's
|
|
77275
|
+
* device name as the orchestrator's camera-sensors resolution last read it;
|
|
77276
|
+
* absent when unknown or when the camera itself triggered.
|
|
77277
|
+
*
|
|
77278
|
+
* Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
|
|
77279
|
+
* can say what started the session (D672 rule 11, amended 2026-10-06). The
|
|
77280
|
+
* runner never decides anything on it.
|
|
77281
|
+
*/
|
|
77282
|
+
var SessionTriggerSchema = object({
|
|
77283
|
+
source: MotionSourceEnum,
|
|
77284
|
+
triggeredBy: MotionTriggeredBySchema,
|
|
77285
|
+
sensorName: string().optional()
|
|
77286
|
+
});
|
|
77287
|
+
/**
|
|
77173
77288
|
* List of motion sources active on a camera. Empty array is valid:
|
|
77174
77289
|
* "no source" — happens for battery cams without firmware motion when
|
|
77175
77290
|
* the operator hasn't opted into the SW analyzer (would hold the
|
|
@@ -77421,6 +77536,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
77421
77536
|
*/
|
|
77422
77537
|
motionSources: MotionSourcesSchema.default(["analyzer"]),
|
|
77423
77538
|
/**
|
|
77539
|
+
* What opened this attach, on a SESSION attach only (see
|
|
77540
|
+
* {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
|
|
77541
|
+
* standing attach, an occupancy burst, a re-dispatch with no motion event
|
|
77542
|
+
* behind it, and every attach from an orchestrator older than the field — the
|
|
77543
|
+
* runner then names no source on the phase event.
|
|
77544
|
+
*/
|
|
77545
|
+
sessionTrigger: SessionTriggerSchema.optional(),
|
|
77546
|
+
/**
|
|
77424
77547
|
* WHICH root detector runs for this camera. The detection counterpart of
|
|
77425
77548
|
* {@link motionSources}, same shape and same discipline: a per-camera list
|
|
77426
77549
|
* of sources the system understands, vendor-agnostic, owned here.
|
|
@@ -77723,7 +77846,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
|
|
|
77723
77846
|
*/
|
|
77724
77847
|
cropJpeg: string().optional(),
|
|
77725
77848
|
parent: DetailParentSchema,
|
|
77726
|
-
steps: array(string()).optional()
|
|
77849
|
+
steps: array(string()).optional(),
|
|
77850
|
+
/**
|
|
77851
|
+
* The camera's root model already drew this step's boxes (D730): a
|
|
77852
|
+
* `license_plate` inside the parent vehicle. The named step is NOT
|
|
77853
|
+
* inferred — these FRAME-space boxes are its output — and its
|
|
77854
|
+
* requested children (the plate reader) run on them. Absent ⇒ every
|
|
77855
|
+
* requested step infers as before.
|
|
77856
|
+
*/
|
|
77857
|
+
supplied: object({
|
|
77858
|
+
stepId: string(),
|
|
77859
|
+
modelId: string(),
|
|
77860
|
+
boxes: array(object({
|
|
77861
|
+
bbox: NativeCropBboxSchema,
|
|
77862
|
+
score: number()
|
|
77863
|
+
})).min(1)
|
|
77864
|
+
}).optional()
|
|
77727
77865
|
}), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
|
|
77728
77866
|
/** Catalog step id, e.g. `clip-embedding`. */
|
|
77729
77867
|
stepId: string(),
|
|
@@ -84834,7 +84972,7 @@ var LocalInterfaceSchema = object({
|
|
|
84834
84972
|
name: string(),
|
|
84835
84973
|
family: _enum(["IPv4", "IPv6"]),
|
|
84836
84974
|
address: string(),
|
|
84837
|
-
/** CIDR shorthand (e.g. `192.168.
|
|
84975
|
+
/** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
|
|
84838
84976
|
cidr: string(),
|
|
84839
84977
|
/** OS netmask. Stable across calls so the SDK can hash on it. */
|
|
84840
84978
|
netmask: string(),
|
|
@@ -84888,7 +85026,8 @@ var ConnectionEndpointSchema = object({
|
|
|
84888
85026
|
"lan-ipv4",
|
|
84889
85027
|
"lan-ipv6",
|
|
84890
85028
|
"public",
|
|
84891
|
-
"loopback"
|
|
85029
|
+
"loopback",
|
|
85030
|
+
"app-link"
|
|
84892
85031
|
]),
|
|
84893
85032
|
/**
|
|
84894
85033
|
* Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
|
|
@@ -84957,15 +85096,27 @@ var GetConnectionEndpointsResultSchema = object({
|
|
|
84957
85096
|
localPort: AdvertisedLocalPortSchema
|
|
84958
85097
|
});
|
|
84959
85098
|
/**
|
|
84960
|
-
* The
|
|
84961
|
-
*
|
|
84962
|
-
*
|
|
85099
|
+
* The address flagged for notification links. `baseUrl: null` = AUTO, which
|
|
85100
|
+
* since D709 is the CamStack app link; `resolved` reports the effective value,
|
|
85101
|
+
* so the UI can show it either way.
|
|
84963
85102
|
*/
|
|
84964
85103
|
var NotificationEndpointSchema = object({
|
|
84965
85104
|
/** The operator's explicit choice, or null for AUTO. */
|
|
84966
85105
|
baseUrl: string().nullable(),
|
|
84967
|
-
/**
|
|
84968
|
-
|
|
85106
|
+
/**
|
|
85107
|
+
* The effective flagged address: the explicit choice, else (AUTO) the
|
|
85108
|
+
* CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
|
|
85109
|
+
* answered the public tunnel / mesh here, or null.
|
|
85110
|
+
*/
|
|
85111
|
+
resolved: string().nullable(),
|
|
85112
|
+
/**
|
|
85113
|
+
* The hub origin an app link carries as `hub=` (D709): the hub's best
|
|
85114
|
+
* public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
|
|
85115
|
+
* picked from this cap's own palette by `pickAppLinkHub`. `null` when the
|
|
85116
|
+
* hub advertises neither; the app link is then minted without `hub=`.
|
|
85117
|
+
* Absent on a pre-D709 hub.
|
|
85118
|
+
*/
|
|
85119
|
+
appLinkHub: string().nullable()
|
|
84969
85120
|
});
|
|
84970
85121
|
/**
|
|
84971
85122
|
* The URLs the SDK / viewer should race for API access. `baseUrls` empty =
|
|
@@ -84978,6 +85129,27 @@ var ViewerEndpointsSchema = object({
|
|
|
84978
85129
|
/** What the ranking currently resolves to (may be empty if nothing is up). */
|
|
84979
85130
|
resolved: array(string()).readonly()
|
|
84980
85131
|
});
|
|
85132
|
+
/**
|
|
85133
|
+
* One audience's hub address (see `hub-address.ts`): the operator's stored
|
|
85134
|
+
* override, the address in use, and where it came from.
|
|
85135
|
+
*/
|
|
85136
|
+
var HubAddressSnapshotSchema = object({
|
|
85137
|
+
/** The operator's override, or null for automatic. */
|
|
85138
|
+
override: string().nullable(),
|
|
85139
|
+
/** The address in use, or null when nothing qualifies (never loopback). */
|
|
85140
|
+
resolved: string().nullable(),
|
|
85141
|
+
source: _enum([
|
|
85142
|
+
"override",
|
|
85143
|
+
"auto",
|
|
85144
|
+
"none"
|
|
85145
|
+
])
|
|
85146
|
+
});
|
|
85147
|
+
var HubAddressesSchema = object({
|
|
85148
|
+
/** "Hub address for agents" — agents' bundle/model pulls, LAN devices. */
|
|
85149
|
+
cluster: HubAddressSnapshotSchema,
|
|
85150
|
+
/** "Public address for sign-in links" — e-mail links, OIDC, WebAuthn, OAuth2. */
|
|
85151
|
+
browser: HubAddressSnapshotSchema
|
|
85152
|
+
});
|
|
84981
85153
|
var AllowedAddressesSchema = object({
|
|
84982
85154
|
/**
|
|
84983
85155
|
* Allowlist of interface addresses operators have explicitly opted
|
|
@@ -85019,8 +85191,18 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
|
|
|
85019
85191
|
* Pass `'https'` when the caller is itself loaded over HTTPS
|
|
85020
85192
|
* to avoid mixed-content blocks in the browser. The public
|
|
85021
85193
|
* tunnel always emits `https://` regardless. */
|
|
85022
|
-
scheme: _enum(["http", "https"]).optional()
|
|
85023
|
-
|
|
85194
|
+
scheme: _enum(["http", "https"]).optional(),
|
|
85195
|
+
/** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
|
|
85196
|
+
* an address notification links can be flagged with, not a hub
|
|
85197
|
+
* route. Default `false`: racers and rankers never see it. */
|
|
85198
|
+
includeAppLink: boolean().optional()
|
|
85199
|
+
}), 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({
|
|
85200
|
+
audience: _enum(["cluster", "browser"]),
|
|
85201
|
+
baseUrl: string().nullable()
|
|
85202
|
+
}), HubAddressesSchema, {
|
|
85203
|
+
kind: "mutation",
|
|
85204
|
+
auth: "admin"
|
|
85205
|
+
}), 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, {
|
|
85024
85206
|
kind: "mutation",
|
|
85025
85207
|
auth: "admin"
|
|
85026
85208
|
}), method(object({
|
|
@@ -85348,7 +85530,7 @@ var MeshPeerSchema = object({
|
|
|
85348
85530
|
tags: array(string()).readonly(),
|
|
85349
85531
|
/** True when the peer advertises itself as an exit-node candidate. */
|
|
85350
85532
|
exitNodeOption: boolean(),
|
|
85351
|
-
/** Subnet routes the peer advertises (e.g. `["192.168.
|
|
85533
|
+
/** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
|
|
85352
85534
|
advertisedRoutes: array(string()).readonly(),
|
|
85353
85535
|
/** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
|
|
85354
85536
|
userLogin: string().nullable(),
|
|
@@ -85478,7 +85660,8 @@ var MotionStatusSchema = object({
|
|
|
85478
85660
|
* writes this slice (not even a boot seed), and neither does the runner's
|
|
85479
85661
|
* phase machine: its phase is "a session is attached" for every on-motion
|
|
85480
85662
|
* session, not motion, and it now has its own `DetectionPhaseTransition`.
|
|
85481
|
-
* A provider's `isDetected`
|
|
85663
|
+
* A provider's `isDetected` and `getStatus` answer from the hub's slice
|
|
85664
|
+
* (`hubMotionNativeProvider`).
|
|
85482
85665
|
* - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
|
|
85483
85666
|
* imports) — the provider pushes both edges itself, from the upstream
|
|
85484
85667
|
* system's own state change. That is the sensor's own fact.
|
|
@@ -86824,7 +87007,13 @@ var OsdStatusSchema = object({ overlays: array(object({
|
|
|
86824
87007
|
*/
|
|
86825
87008
|
availablePositions: array(OsdPositionEnum).readonly(),
|
|
86826
87009
|
/** Firmware does not allow editing the `text` field (e.g. timestamp). */
|
|
86827
|
-
readOnly: boolean().optional()
|
|
87010
|
+
readOnly: boolean().optional(),
|
|
87011
|
+
/**
|
|
87012
|
+
* Firmware text ceiling for this overlay. Absent = no known limit.
|
|
87013
|
+
* The OSD manager truncates here on every write — never stores its own
|
|
87014
|
+
* copy on the binding.
|
|
87015
|
+
*/
|
|
87016
|
+
maxCharacters: number().int().positive().optional()
|
|
86828
87017
|
})).readonly() });
|
|
86829
87018
|
var OsdOverlayPatchSchema = object({
|
|
86830
87019
|
enabled: boolean().optional(),
|
|
@@ -86875,7 +87064,9 @@ var OsdTemplateBindingSchema = object({
|
|
|
86875
87064
|
valuePath: string().min(1).max(64),
|
|
86876
87065
|
/** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
|
|
86877
87066
|
displayUnit: string().max(16).optional(),
|
|
86878
|
-
maxDecimals: number().int().min(0).max(4).default(1)
|
|
87067
|
+
maxDecimals: number().int().min(0).max(4).default(1),
|
|
87068
|
+
/** Raw value → display text (same shape as slot binding). Empty string hides. */
|
|
87069
|
+
valueMap: record(string(), string()).optional()
|
|
86879
87070
|
});
|
|
86880
87071
|
/**
|
|
86881
87072
|
* A named template: bindings (alias → leaf field) + a parser that
|
|
@@ -86925,18 +87116,11 @@ var OsdSlotBindingSchema = object({
|
|
|
86925
87116
|
source: OsdSourceSchema,
|
|
86926
87117
|
/** `${value}` and `${unit}` are substituted; every occurrence. */
|
|
86927
87118
|
template: string().max(96).default("${value}"),
|
|
86928
|
-
/** Truncate with an ellipsis past this length. Absent = no limit. */
|
|
86929
|
-
maxCharacters: number().int().min(4).max(64).optional(),
|
|
86930
87119
|
/**
|
|
86931
87120
|
* Decimal places for a numeric value. `0` yields an integer — the
|
|
86932
87121
|
* documented workaround for firmwares that reject `.` in overlay text.
|
|
86933
87122
|
*/
|
|
86934
87123
|
maxDecimals: number().int().min(0).max(4).default(1),
|
|
86935
|
-
/**
|
|
86936
|
-
* Appended via `${unit}` when no unit conversion produces a label.
|
|
86937
|
-
* Prefer `source.displayUnit` for converted device-state values.
|
|
86938
|
-
*/
|
|
86939
|
-
unitLabel: string().max(8).optional(),
|
|
86940
87124
|
/** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
|
|
86941
87125
|
valueMap: record(string(), string()).optional(),
|
|
86942
87126
|
/** Time windows in which the slot is shown. Absent = always. */
|
|
@@ -86945,9 +87129,7 @@ var OsdSlotBindingSchema = object({
|
|
|
86945
87129
|
* Display gate, in the notification centre's condition vocabulary.
|
|
86946
87130
|
* Only the keys reported by `getConditionSupport` are accepted.
|
|
86947
87131
|
*/
|
|
86948
|
-
conditions: NcConditionsSchema.optional()
|
|
86949
|
-
/** Rendered when the gate is closed or the value unreadable. Empty = hide. */
|
|
86950
|
-
fallbackText: string().max(64).default("")
|
|
87132
|
+
conditions: NcConditionsSchema.optional()
|
|
86951
87133
|
});
|
|
86952
87134
|
/** One camera slot, as the operator sees it: firmware truth + our binding. */
|
|
86953
87135
|
var OsdSlotViewSchema = object({
|
|
@@ -96644,6 +96826,12 @@ Object.freeze({
|
|
|
96644
96826
|
addonId: null,
|
|
96645
96827
|
access: "view"
|
|
96646
96828
|
},
|
|
96829
|
+
"localNetwork.getHubAddresses": {
|
|
96830
|
+
capName: "local-network",
|
|
96831
|
+
capScope: "system",
|
|
96832
|
+
addonId: null,
|
|
96833
|
+
access: "view"
|
|
96834
|
+
},
|
|
96647
96835
|
"localNetwork.getNotificationEndpoint": {
|
|
96648
96836
|
capName: "local-network",
|
|
96649
96837
|
capScope: "system",
|
|
@@ -96698,6 +96886,12 @@ Object.freeze({
|
|
|
96698
96886
|
addonId: null,
|
|
96699
96887
|
access: "create"
|
|
96700
96888
|
},
|
|
96889
|
+
"localNetwork.setHubAddress": {
|
|
96890
|
+
capName: "local-network",
|
|
96891
|
+
capScope: "system",
|
|
96892
|
+
addonId: null,
|
|
96893
|
+
access: "create"
|
|
96894
|
+
},
|
|
96701
96895
|
"localNetwork.setNotificationEndpoint": {
|
|
96702
96896
|
capName: "local-network",
|
|
96703
96897
|
capScope: "system",
|
|
@@ -105097,6 +105291,8 @@ new Map(Object.entries({
|
|
|
105097
105291
|
"detection-blind": "device-events",
|
|
105098
105292
|
"node-online": "system",
|
|
105099
105293
|
"node-offline": "system",
|
|
105294
|
+
"node-restarting": "system",
|
|
105295
|
+
"node-updating": "system",
|
|
105100
105296
|
"node-inference-unavailable": "system",
|
|
105101
105297
|
"addon-crash-loop": "system",
|
|
105102
105298
|
"addon-update-available": "system",
|
|
@@ -105174,18 +105370,21 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
105174
105370
|
kinds: [
|
|
105175
105371
|
"node-offline",
|
|
105176
105372
|
"node-online",
|
|
105373
|
+
"node-restarting",
|
|
105177
105374
|
"node-inference-unavailable"
|
|
105178
105375
|
]
|
|
105179
105376
|
},
|
|
105180
105377
|
{
|
|
105181
105378
|
id: "addons",
|
|
105182
105379
|
family: "system",
|
|
105183
|
-
label: "Addons",
|
|
105184
|
-
kinds: [
|
|
105185
|
-
|
|
105186
|
-
|
|
105187
|
-
|
|
105188
|
-
|
|
105380
|
+
label: "Addons stopped",
|
|
105381
|
+
kinds: ["addon-crash-loop"]
|
|
105382
|
+
},
|
|
105383
|
+
{
|
|
105384
|
+
id: "addon-updates",
|
|
105385
|
+
family: "system",
|
|
105386
|
+
label: "Addon updates",
|
|
105387
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
105189
105388
|
},
|
|
105190
105389
|
{
|
|
105191
105390
|
id: "updates",
|
|
@@ -105193,6 +105392,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
|
|
|
105193
105392
|
label: "Server & container updates",
|
|
105194
105393
|
kinds: [
|
|
105195
105394
|
"server-update-available",
|
|
105395
|
+
"node-updating",
|
|
105196
105396
|
"server-updated",
|
|
105197
105397
|
"wrapper-update-available"
|
|
105198
105398
|
]
|
|
@@ -105340,18 +105540,21 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
105340
105540
|
kinds: [
|
|
105341
105541
|
"node-offline",
|
|
105342
105542
|
"node-online",
|
|
105543
|
+
"node-restarting",
|
|
105343
105544
|
"node-inference-unavailable"
|
|
105344
105545
|
]
|
|
105345
105546
|
},
|
|
105346
105547
|
{
|
|
105347
105548
|
name: "summaryAddons",
|
|
105348
|
-
label: "Summary: addons",
|
|
105349
|
-
example: "
|
|
105350
|
-
kinds: [
|
|
105351
|
-
|
|
105352
|
-
|
|
105353
|
-
|
|
105354
|
-
|
|
105549
|
+
label: "Summary: addons stopped",
|
|
105550
|
+
example: "hub — recorder stopped after repeated crashes",
|
|
105551
|
+
kinds: ["addon-crash-loop"]
|
|
105552
|
+
},
|
|
105553
|
+
{
|
|
105554
|
+
name: "summaryAddonUpdates",
|
|
105555
|
+
label: "Summary: addon updates",
|
|
105556
|
+
example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
|
|
105557
|
+
kinds: ["addon-update-available", "addon-updated"]
|
|
105355
105558
|
},
|
|
105356
105559
|
{
|
|
105357
105560
|
name: "summaryUpdates",
|
|
@@ -105359,6 +105562,7 @@ var STATE_SUMMARY_SECTION_VARS = [
|
|
|
105359
105562
|
example: "server 1.2.377 → 1.2.378",
|
|
105360
105563
|
kinds: [
|
|
105361
105564
|
"server-update-available",
|
|
105565
|
+
"node-updating",
|
|
105362
105566
|
"server-updated",
|
|
105363
105567
|
"wrapper-update-available"
|
|
105364
105568
|
]
|
|
@@ -105391,7 +105595,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
105391
105595
|
{
|
|
105392
105596
|
name: "summarySection",
|
|
105393
105597
|
label: "Summary: this section",
|
|
105394
|
-
description: "The section a per-section summary row is about
|
|
105598
|
+
description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
|
|
105395
105599
|
example: "Batterie scariche",
|
|
105396
105600
|
group: "system",
|
|
105397
105601
|
families: ["rule"],
|
|
@@ -105435,6 +105639,7 @@ var STATE_SUMMARY_VARS = [
|
|
|
105435
105639
|
[...RULE_BODY_ONLY],
|
|
105436
105640
|
[...RULE_TEXT],
|
|
105437
105641
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
105642
|
+
([...RULE_TEXT], [...COMBINED_ALARM]),
|
|
105438
105643
|
([...RULE_TEXT], [...DEVICE_EVENTS]),
|
|
105439
105644
|
([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
|
|
105440
105645
|
([...RULE_TEXT], [...CONSUMABLE]),
|
|
@@ -105475,6 +105680,8 @@ var STATE_SUMMARY_VARS = [
|
|
|
105475
105680
|
[...RULE_TEXT],
|
|
105476
105681
|
[...RULE_TEXT],
|
|
105477
105682
|
[...RULE_TEXT],
|
|
105683
|
+
[...RULE_TEXT],
|
|
105684
|
+
[...RULE_TEXT],
|
|
105478
105685
|
...STATE_SUMMARY_VARS
|
|
105479
105686
|
];
|
|
105480
105687
|
new Set([
|
|
@@ -108389,6 +108596,18 @@ function nextVacuumControlSlice(prev, next) {
|
|
|
108389
108596
|
}
|
|
108390
108597
|
//#endregion
|
|
108391
108598
|
//#region src/devices/dreame-camera-stream.ts
|
|
108599
|
+
/**
|
|
108600
|
+
* The robot camera as a stream the broker can pull — the pure facts.
|
|
108601
|
+
*
|
|
108602
|
+
* A Dreame relay carries video only between `open()` and `close()`, and the
|
|
108603
|
+
* robot runs on a battery, so the camera cannot sit in the catalog with a
|
|
108604
|
+
* URL the way a mains RTSP camera does. The seam is the broker's own battery
|
|
108605
|
+
* path: `battery.wakeForStream` opens the monitor, and the catalog then
|
|
108606
|
+
* names the local RFC 4571 server (`dreame-rfc4571-server.ts`) the broker
|
|
108607
|
+
* pulls. While the monitor is CLOSED the
|
|
108608
|
+
* catalog carries the broker's lazy sentinel (Reolink's shape): the stream is
|
|
108609
|
+
* listed, and the first dial asks the publisher to materialize it.
|
|
108610
|
+
*/
|
|
108392
108611
|
/** The one stream the robot camera offers. Half of the broker id (`<deviceId>/live`). */
|
|
108393
108612
|
var CAMERA_STREAM_ID = "live";
|
|
108394
108613
|
/** The plugin's cap: a monitor never outlives this, whoever is watching. */
|
|
@@ -108468,17 +108687,13 @@ function cameraStreamCatalog(session) {
|
|
|
108468
108687
|
/**
|
|
108469
108688
|
* The host the broker is told to dial. The provider and the ingest owner
|
|
108470
108689
|
* share the hub today, but a broker on another node reaches the hub only
|
|
108471
|
-
* through
|
|
108472
|
-
*
|
|
108690
|
+
* through the hub's address for agents — `local-network.getHubAddresses()
|
|
108691
|
+
* .cluster` (the Network page's override, else the detected LAN address).
|
|
108692
|
+
* Loopback when that names nothing: then the only broker that can dial at
|
|
108693
|
+
* all is this node's own.
|
|
108473
108694
|
*/
|
|
108474
|
-
function advertisedRfcHost(
|
|
108475
|
-
|
|
108476
|
-
try {
|
|
108477
|
-
const host = new URL(hubPublicUrl).hostname;
|
|
108478
|
-
return host.length > 0 ? host : "127.0.0.1";
|
|
108479
|
-
} catch {
|
|
108480
|
-
return "127.0.0.1";
|
|
108481
|
-
}
|
|
108695
|
+
function advertisedRfcHost(clusterBaseUrl) {
|
|
108696
|
+
return hubAddressHostname(clusterBaseUrl) ?? "127.0.0.1";
|
|
108482
108697
|
}
|
|
108483
108698
|
function rfcUrl(host, port) {
|
|
108484
108699
|
return `tcp://${host}:${String(port)}`;
|
|
@@ -154868,6 +155083,23 @@ var DreameCameraDevice = class extends DreameChildDevice {
|
|
|
154868
155083
|
}
|
|
154869
155084
|
unsubscribeRefresh = null;
|
|
154870
155085
|
/** Register the stream on the broker — the server, or the lazy sentinel (push semantics; the catalog is the durable copy). */
|
|
155086
|
+
/**
|
|
155087
|
+
* The hub's address for agents (`local-network.getHubAddresses().cluster`:
|
|
155088
|
+
* the Network page's override, else the detected LAN address). A failed
|
|
155089
|
+
* read is `null` — `advertisedRfcHost` then answers loopback, which this
|
|
155090
|
+
* node's own broker can still dial.
|
|
155091
|
+
*/
|
|
155092
|
+
async hubClusterAddress() {
|
|
155093
|
+
try {
|
|
155094
|
+
return (await this.ctx.api.localNetwork.getHubAddresses.query()).cluster.resolved;
|
|
155095
|
+
} catch (err) {
|
|
155096
|
+
this.ctx.logger.warn("robot camera: hub address unavailable — advertising loopback", {
|
|
155097
|
+
tags: { deviceId: this.id },
|
|
155098
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
155099
|
+
});
|
|
155100
|
+
return null;
|
|
155101
|
+
}
|
|
155102
|
+
}
|
|
154871
155103
|
async publishRelay(session) {
|
|
154872
155104
|
const [descriptor] = cameraStreamCatalog(session);
|
|
154873
155105
|
if (descriptor === void 0) return;
|
|
@@ -154953,7 +155185,7 @@ var DreameCameraDevice = class extends DreameChildDevice {
|
|
|
154953
155185
|
rfc
|
|
154954
155186
|
};
|
|
154955
155187
|
this.session = {
|
|
154956
|
-
url: rfcUrl(advertisedRfcHost(
|
|
155188
|
+
url: rfcUrl(advertisedRfcHost(await this.hubClusterAddress()), rfc.port),
|
|
154957
155189
|
sdp: rfc.sdp
|
|
154958
155190
|
};
|
|
154959
155191
|
this.sessionOpenedAt = Date.now();
|