@camstack/addon-provider-hikvision 1.2.143 → 1.2.145

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.
Files changed (3) hide show
  1. package/dist/addon.js +349 -83
  2. package/dist/addon.mjs +349 -83
  3. package/package.json +1 -1
package/dist/addon.mjs CHANGED
@@ -5392,7 +5392,7 @@ var ZodIssueCode = {
5392
5392
  var ZodFirstPartyTypeKind;
5393
5393
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5394
5394
  //#endregion
5395
- //#region ../types/dist/sleep-DXKLNFvA.mjs
5395
+ //#region ../types/dist/sleep-C16NCZR2.mjs
5396
5396
  /**
5397
5397
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5398
5398
  * window to float samples (D455).
@@ -10781,57 +10781,15 @@ var ClipSearchStrictnessSchema = _enum([
10781
10781
  "balanced",
10782
10782
  "strict"
10783
10783
  ]);
10784
- new Set([
10785
- {
10786
- id: "person",
10787
- name: "Person"
10788
- },
10789
- {
10790
- id: "vehicle",
10791
- name: "Vehicle"
10792
- },
10793
- {
10794
- id: "animal",
10795
- name: "Animal"
10796
- },
10797
- {
10798
- id: "package",
10799
- name: "Package"
10800
- }
10801
- ].map((l) => l.id));
10802
- var COCO_TO_MACRO = {
10803
- mapping: {
10804
- person: "person",
10805
- bicycle: "vehicle",
10806
- car: "vehicle",
10807
- motorcycle: "vehicle",
10808
- airplane: "vehicle",
10809
- bus: "vehicle",
10810
- train: "vehicle",
10811
- truck: "vehicle",
10812
- boat: "vehicle",
10813
- bird: "animal",
10814
- cat: "animal",
10815
- dog: "animal",
10816
- horse: "animal",
10817
- sheep: "animal",
10818
- cow: "animal",
10819
- elephant: "animal",
10820
- bear: "animal",
10821
- zebra: "animal",
10822
- giraffe: "animal",
10823
- suitcase: "package",
10824
- backpack: "package",
10825
- handbag: "package"
10826
- },
10827
- preserveOriginal: false
10828
- };
10829
- /** Steps a root detector may declare it fills. */
10830
- var FILLABLE_STEP_IDS = [
10784
+ /** Steps whose effect a root label can BE. */
10785
+ var LABEL_SUPPLY_STEP_IDS = [
10831
10786
  "animal-classifier",
10832
10787
  "vehicle-classifier",
10833
10788
  "package-detection"
10834
10789
  ];
10790
+ /** Steps whose box a root detection can BE. */
10791
+ var CROP_SUPPLY_STEP_IDS = ["plate-detection", "face-detection"];
10792
+ [...LABEL_SUPPLY_STEP_IDS, ...CROP_SUPPLY_STEP_IDS];
10835
10793
  var MODEL_FORMATS = [
10836
10794
  "onnx",
10837
10795
  "coreml",
@@ -10964,12 +10922,35 @@ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { wei
10964
10922
  /** True when the weights or their data forbid commercial use. */
10965
10923
  nonCommercial: boolean().optional()
10966
10924
  }));
10967
- /** One `fillsClassifierEffects` entry — see `ModelCatalogEntry.fillsClassifierEffects`. */
10968
- var FillsClassifierEffectSchema = object({
10969
- stepId: _enum(FILLABLE_STEP_IDS),
10925
+ /**
10926
+ * One step a ROOT detector can supply from its own output (D730) — see
10927
+ * `ModelCatalogEntry.suppliesSteps`.
10928
+ *
10929
+ * - `label`: the root's raw class IS the step's answer. `labelToEffect` maps
10930
+ * the root's label to the step's vocabulary; `uncovered` is the vocabulary
10931
+ * the root cannot produce (shown as unavailable, never a blocker).
10932
+ * - `crop`: the root draws the box the step would have found (`license_plate`
10933
+ * for plate-detection, `face` for face-detection). The box becomes a detail
10934
+ * child of the `parentMacro` detection that contains it — never a track.
10935
+ */
10936
+ var RootStepSupplySchema = discriminatedUnion("kind", [object({
10937
+ kind: literal("label"),
10938
+ stepId: _enum(LABEL_SUPPLY_STEP_IDS),
10970
10939
  labelToEffect: record(string(), string()),
10971
10940
  uncovered: array(string()).readonly()
10972
- });
10941
+ }), object({
10942
+ kind: literal("crop"),
10943
+ stepId: _enum(CROP_SUPPLY_STEP_IDS),
10944
+ rootLabels: array(string()).readonly(),
10945
+ parentMacro: _enum(["vehicle", "person"]),
10946
+ childClass: _enum(["plate", "face"]),
10947
+ /**
10948
+ * The root's smaller input side, stamped on read by `rootSuppliesOf` from
10949
+ * the model entry — what a step's `minRootInputPx` gate judges. Never
10950
+ * stored by an import.
10951
+ */
10952
+ rootInputPx: number().int().positive().optional()
10953
+ })]);
10973
10954
  var ModelCatalogEntrySchema = object({
10974
10955
  id: string(),
10975
10956
  name: string(),
@@ -11096,15 +11077,15 @@ var ModelCatalogEntrySchema = object({
11096
11077
  */
11097
11078
  classMap: DetectionCatalogClassMapSchema.optional(),
11098
11079
  /**
11099
- * The pipeline steps this ROOT detector already does the work of (D715):
11100
- * its labels name the effect the step exists to produce (`deer` for
11101
- * `animal-classifier`, `package` for `package-detection`). Derived from the
11102
- * labelmap by `deriveClassifierFills`, never hand-written; a COCO model
11103
- * declares none. Whether a declaration is honoured is the step's own
11104
- * `labelLink` policy (`resolveLabelLink`). `labelToEffect` values are in
11105
- * `FILLABLE_STEP_VOCABULARIES` (guard `check-label-link-vocabulary`).
11080
+ * The pipeline steps this ROOT detector can supply from its own output
11081
+ * (D730): its labels name a step's effect (`deer` for `animal-classifier`)
11082
+ * or draw a step's box (`license_plate` for `plate-detection`). Computed at
11083
+ * import from THIS model's labelmap by `deriveRootSupplies`, never written
11084
+ * by hand and never assumed per family; a row without it is derived on read
11085
+ * (`rootSuppliesOf`). Whether a camera uses it is the step's own
11086
+ * `useRootModel` flag (`resolveRootSupply`).
11106
11087
  */
11107
- fillsClassifierEffects: array(FillsClassifierEffectSchema).readonly().optional(),
11088
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional(),
11108
11089
  /**
11109
11090
  * The model's CLIP feature-space contract (text encoder, dimension, vector
11110
11091
  * index, token window, search floor) — see `clip-model.ts`. Present ONLY on a
@@ -16686,6 +16667,12 @@ method(_void(), array(string()).readonly(), { auth: "admin" }), method(object({
16686
16667
  kind: "mutation",
16687
16668
  auth: "admin"
16688
16669
  });
16670
+ var HUB_ADDRESS_ROLES = [
16671
+ "appConnections",
16672
+ "notificationTaps",
16673
+ "internal",
16674
+ "publicEndpoint"
16675
+ ];
16689
16676
  /**
16690
16677
  * Transport bounds for AI capability methods.
16691
16678
  *
@@ -18448,6 +18435,51 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
18448
18435
  kind: "mutation",
18449
18436
  auth: "admin"
18450
18437
  });
18438
+ new Set([
18439
+ {
18440
+ id: "person",
18441
+ name: "Person"
18442
+ },
18443
+ {
18444
+ id: "vehicle",
18445
+ name: "Vehicle"
18446
+ },
18447
+ {
18448
+ id: "animal",
18449
+ name: "Animal"
18450
+ },
18451
+ {
18452
+ id: "package",
18453
+ name: "Package"
18454
+ }
18455
+ ].map((l) => l.id));
18456
+ var COCO_TO_MACRO = {
18457
+ mapping: {
18458
+ person: "person",
18459
+ bicycle: "vehicle",
18460
+ car: "vehicle",
18461
+ motorcycle: "vehicle",
18462
+ airplane: "vehicle",
18463
+ bus: "vehicle",
18464
+ train: "vehicle",
18465
+ truck: "vehicle",
18466
+ boat: "vehicle",
18467
+ bird: "animal",
18468
+ cat: "animal",
18469
+ dog: "animal",
18470
+ horse: "animal",
18471
+ sheep: "animal",
18472
+ cow: "animal",
18473
+ elephant: "animal",
18474
+ bear: "animal",
18475
+ zebra: "animal",
18476
+ giraffe: "animal",
18477
+ suitcase: "package",
18478
+ backpack: "package",
18479
+ handbag: "package"
18480
+ },
18481
+ preserveOriginal: false
18482
+ };
18451
18483
  var AUDIO_MACRO_LABELS = [
18452
18484
  {
18453
18485
  id: "speech",
@@ -19243,6 +19275,8 @@ var NcSystemEventKindSchema = _enum([
19243
19275
  "stream-offline",
19244
19276
  "node-online",
19245
19277
  "node-offline",
19278
+ "node-restarting",
19279
+ "node-updating",
19246
19280
  "node-inference-unavailable",
19247
19281
  "detection-blind",
19248
19282
  "addon-crash-loop",
@@ -20848,7 +20882,13 @@ var NcAlarmModeDelaysListSchema = array(object({
20848
20882
  * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20849
20883
  * is the one that starts the entry delay — the entry-delay notification already names it.
20850
20884
  */
20851
- notifySensorRewatched: boolean().optional()
20885
+ notifySensorRewatched: boolean().optional(),
20886
+ /**
20887
+ * D735: notify "ignored" when a sensor this arm bypassed really MOVED while armed (its own
20888
+ * change time is after the arm) and set nothing off. Absent = false (logged, not sent). A
20889
+ * re-sync, a recovery from `unavailable` or a duplicate is never announced, switch or not.
20890
+ */
20891
+ notifySensorIgnored: boolean().optional()
20852
20892
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20853
20893
  var NcAlarmModeDelaysEditListSchema = array(object({
20854
20894
  mode: AlarmArmModeSchema,
@@ -20861,7 +20901,9 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20861
20901
  /** D706: set the switch, or `null` to clear it (back to the default, false). */
20862
20902
  notifyDuringEntryDelay: boolean().nullable().optional(),
20863
20903
  /** D706: set the switch, or `null` to clear it (back to the default, false). */
20864
- notifySensorRewatched: boolean().nullable().optional()
20904
+ notifySensorRewatched: boolean().nullable().optional(),
20905
+ /** D735: set the switch, or `null` to clear it (back to the default, false). */
20906
+ notifySensorIgnored: boolean().nullable().optional()
20865
20907
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20866
20908
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20867
20909
  var NcAlarmNonBlockingEditSchema = object({
@@ -23760,6 +23802,34 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
23760
23802
  timestamp: number()
23761
23803
  });
23762
23804
  /**
23805
+ * A root model's boxes standing in for one crop-kind step's own inference
23806
+ * (D730) — see `runPipeline.suppliedRoot`.
23807
+ */
23808
+ var SuppliedRootOutputSchema = object({
23809
+ stepId: string(),
23810
+ /** The root model that drew the boxes — stamped on the result. */
23811
+ modelId: string(),
23812
+ detections: array(object({
23813
+ /** `[x1, y1, x2, y2]` in the pixels of the call's image. */
23814
+ bbox: tuple([
23815
+ number(),
23816
+ number(),
23817
+ number(),
23818
+ number()
23819
+ ]),
23820
+ score: number(),
23821
+ /**
23822
+ * Five facial landmarks in the same pixels — a face the step's own
23823
+ * detector already re-found inside a root face box (D730), so its
23824
+ * embedder child aligns it exactly as it aligns any detected face.
23825
+ */
23826
+ landmarks: array(object({
23827
+ x: number(),
23828
+ y: number()
23829
+ })).optional()
23830
+ })).min(1)
23831
+ });
23832
+ /**
23763
23833
  * Reference to the frame's retained NATIVE surface + the parent crop's placement
23764
23834
  * within the frame, so the executor can re-cut a leaf child ROI at native
23765
23835
  * resolution on the detail plane. See the `runPipeline` `nativeCropRef` field.
@@ -23890,7 +23960,7 @@ var PipelineModelOptionSchema = object({
23890
23960
  legacy: boolean().optional(),
23891
23961
  provider: ModelProviderIdSchema.optional(),
23892
23962
  defaultConfidence: number().optional(),
23893
- fillsClassifierEffects: array(FillsClassifierEffectSchema).readonly().optional()
23963
+ suppliesSteps: array(RootStepSupplySchema).readonly().optional()
23894
23964
  });
23895
23965
  var ConfigFieldBridge = custom();
23896
23966
  var PipelineAddonSchemaSchema = object({
@@ -24158,7 +24228,16 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
24158
24228
  * `device-not-servable`), and nothing reaches the camera's live
24159
24229
  * trace stream. Absent ⇒ unchanged behaviour.
24160
24230
  */
24161
- replay: literal(true).optional()
24231
+ replay: literal(true).optional(),
24232
+ /**
24233
+ * Root-supplied detections for the tree's ROOT step (D730). Set by
24234
+ * `runDetailSubtree` when the camera's root model supplies a crop-kind
24235
+ * step (a Frigate+ `license_plate` for `plate-detection`): the step is
24236
+ * NOT inferred, these boxes are its output, and its children (the plate
24237
+ * reader) run on them through their own crop policy. Boxes are in the
24238
+ * PIXELS of the image this call carries. Absent ⇒ the root step runs.
24239
+ */
24240
+ suppliedRoot: SuppliedRootOutputSchema.optional()
24162
24241
  }), PipelineRunResultBridge, { kind: "mutation" }), method(object({
24163
24242
  steps: array(PipelineStepInputSchema).min(1),
24164
24243
  frames: array(FrameInputSchema).min(1).max(255),
@@ -25300,7 +25379,22 @@ method(RunnerCameraConfigSchema, object({ success: literal(true) }), { kind: "mu
25300
25379
  */
25301
25380
  cropJpeg: string().optional(),
25302
25381
  parent: DetailParentSchema,
25303
- steps: array(string()).optional()
25382
+ steps: array(string()).optional(),
25383
+ /**
25384
+ * The camera's root model already drew this step's boxes (D730): a
25385
+ * `license_plate` inside the parent vehicle. The named step is NOT
25386
+ * inferred — these FRAME-space boxes are its output — and its
25387
+ * requested children (the plate reader) run on them. Absent ⇒ every
25388
+ * requested step infers as before.
25389
+ */
25390
+ supplied: object({
25391
+ stepId: string(),
25392
+ modelId: string(),
25393
+ boxes: array(object({
25394
+ bbox: NativeCropBboxSchema,
25395
+ score: number()
25396
+ })).min(1)
25397
+ }).optional()
25304
25398
  }), object({ details: array(DetailResultSchema) }).nullable(), { kind: "mutation" }), method(object({
25305
25399
  /** Catalog step id, e.g. `clip-embedding`. */
25306
25400
  stepId: string(),
@@ -29152,6 +29246,14 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
29152
29246
  */
29153
29247
  alive: boolean()
29154
29248
  })), method(object({
29249
+ deviceId: number().int().nonnegative(),
29250
+ sessionId: string(),
29251
+ downlinkMbps: number().nonnegative()
29252
+ }), object({
29253
+ outcome: _enum(["switching", "held"]),
29254
+ tier: CamProfileSchema.nullable(),
29255
+ reason: string()
29256
+ }), { kind: "mutation" }), method(object({
29155
29257
  deviceId: number().int().nonnegative(),
29156
29258
  sessionId: string()
29157
29259
  }), WebrtcSessionDebugSchema, { kind: "query" });
@@ -32963,7 +33065,8 @@ var ConnectionEndpointSchema = object({
32963
33065
  "lan-ipv6",
32964
33066
  "public",
32965
33067
  "loopback",
32966
- "app-link"
33068
+ "app-link",
33069
+ "custom"
32967
33070
  ]),
32968
33071
  /**
32969
33072
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -33032,7 +33135,7 @@ var GetConnectionEndpointsResultSchema = object({
33032
33135
  localPort: AdvertisedLocalPortSchema
33033
33136
  });
33034
33137
  /**
33035
- * The address flagged for notification links. `baseUrl: null` = AUTO, which
33138
+ * The address flagged for notification taps (`notificationTaps`). `baseUrl: null` = AUTO, which
33036
33139
  * since D709 is the CamStack app link; `resolved` reports the effective value,
33037
33140
  * so the UI can show it either way.
33038
33141
  */
@@ -33065,6 +33168,72 @@ var ViewerEndpointsSchema = object({
33065
33168
  /** What the ranking currently resolves to (may be empty if nothing is up). */
33066
33169
  resolved: array(string()).readonly()
33067
33170
  });
33171
+ /**
33172
+ * DEPRECATED compatibility shape of `getHubAddresses` (D729 amendment, kept
33173
+ * for addons built against it): `cluster` is the `internal` role, `browser`
33174
+ * the `publicEndpoint` role; `override` is the flagged address.
33175
+ */
33176
+ var HubAddressSnapshotSchema = object({
33177
+ override: string().nullable(),
33178
+ resolved: string().nullable(),
33179
+ source: _enum([
33180
+ "override",
33181
+ "auto",
33182
+ "none"
33183
+ ])
33184
+ });
33185
+ var HubAddressesSchema = object({
33186
+ cluster: HubAddressSnapshotSchema,
33187
+ browser: HubAddressSnapshotSchema
33188
+ });
33189
+ /**
33190
+ * What an address is used for (`hub-address.ts`, D734). `appConnections` is
33191
+ * many-valued; `notificationTaps`, `publicEndpoint` and `internal` are carried
33192
+ * by at most one address.
33193
+ */
33194
+ var HubAddressRoleSchema = _enum(HUB_ADDRESS_ROLES);
33195
+ var RoleSourceSchema = _enum([
33196
+ "flagged",
33197
+ "auto",
33198
+ "none"
33199
+ ]);
33200
+ /** One single-valued role: the flagged address, the one in use, and why. */
33201
+ var HubAddressRoleResolutionSchema = object({
33202
+ /** The address carrying the flag, or null = automatic. */
33203
+ flagged: string().nullable(),
33204
+ /** The address in use, or null when nothing qualifies (never loopback). */
33205
+ resolved: string().nullable(),
33206
+ source: RoleSourceSchema
33207
+ });
33208
+ var HubAppConnectionsResolutionSchema = object({
33209
+ /** The addresses flagged `appConnections`, or empty = automatic. */
33210
+ flagged: array(string()).readonly(),
33211
+ /** What the apps race right now. */
33212
+ resolved: array(string()).readonly(),
33213
+ source: RoleSourceSchema
33214
+ });
33215
+ var HubAddressBookSchema = object({
33216
+ rows: array(ConnectionEndpointSchema.extend({
33217
+ /** In the hub's detected palette right now. */
33218
+ detected: boolean(),
33219
+ /** Entered by the operator (removable). */
33220
+ custom: boolean(),
33221
+ /** The roles explicitly flagged on this address. */
33222
+ flags: array(HubAddressRoleSchema).readonly(),
33223
+ /** The roles this address serves right now — flagged or automatic. */
33224
+ inUse: array(HubAddressRoleSchema).readonly(),
33225
+ /** The roles this address may be flagged with. */
33226
+ eligible: array(HubAddressRoleSchema).readonly()
33227
+ })).readonly(),
33228
+ roles: object({
33229
+ appConnections: HubAppConnectionsResolutionSchema,
33230
+ notificationTaps: HubAddressRoleResolutionSchema,
33231
+ internal: HubAddressRoleResolutionSchema,
33232
+ publicEndpoint: HubAddressRoleResolutionSchema
33233
+ }),
33234
+ /** The `hub=` an app link carries (D709), or null. */
33235
+ appLinkHub: string().nullable()
33236
+ });
33068
33237
  var AllowedAddressesSchema = object({
33069
33238
  /**
33070
33239
  * Allowlist of interface addresses operators have explicitly opted
@@ -33108,10 +33277,27 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
33108
33277
  * tunnel always emits `https://` regardless. */
33109
33278
  scheme: _enum(["http", "https"]).optional(),
33110
33279
  /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
33111
- * an address notification links can be flagged with, not a hub
33280
+ * an address notification taps can be flagged with, not a hub
33112
33281
  * route. Default `false`: racers and rankers never see it. */
33113
33282
  includeAppLink: boolean().optional()
33114
- }), 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(), AllowedAddressesSchema), method(AllowedAddressesSchema, object({ success: literal(true) }), { kind: "mutation" }), method(_void(), AllowedAddressesSchema, { kind: "mutation" }), method(_void(), TlsStatusSchema), method(object({ reason: string().optional() }), TlsStatusSchema, {
33283
+ }), 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(object({ scheme: _enum(["http", "https"]).optional() }).optional(), HubAddressBookSchema), method(object({
33284
+ baseUrl: string(),
33285
+ label: string().max(80)
33286
+ }), HubAddressBookSchema, {
33287
+ kind: "mutation",
33288
+ auth: "admin"
33289
+ }), method(object({ baseUrl: string() }), HubAddressBookSchema, {
33290
+ kind: "mutation",
33291
+ auth: "admin"
33292
+ }), method(object({
33293
+ role: HubAddressRoleSchema,
33294
+ baseUrl: string().nullable(),
33295
+ enabled: boolean(),
33296
+ acceptInsecureHttp: boolean().optional()
33297
+ }), HubAddressBookSchema, {
33298
+ kind: "mutation",
33299
+ auth: "admin"
33300
+ }), method(_void(), HubAddressesSchema), 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, {
33115
33301
  kind: "mutation",
33116
33302
  auth: "admin"
33117
33303
  }), method(object({
@@ -33569,7 +33755,8 @@ var MotionStatusSchema = object({
33569
33755
  * writes this slice (not even a boot seed), and neither does the runner's
33570
33756
  * phase machine: its phase is "a session is attached" for every on-motion
33571
33757
  * session, not motion, and it now has its own `DetectionPhaseTransition`.
33572
- * A provider's `isDetected` answers from the hub's slice.
33758
+ * A provider's `isDetected` and `getStatus` answer from the hub's slice
33759
+ * (`hubMotionNativeProvider`).
33573
33760
  * - **Sensors** (Home Assistant binary sensors, Homematic, Matter, Alexa
33574
33761
  * imports) — the provider pushes both edges itself, from the upstream
33575
33762
  * system's own state change. That is the sensor's own fact.
@@ -45144,12 +45331,24 @@ Object.freeze({
45144
45331
  addonId: null,
45145
45332
  access: "view"
45146
45333
  },
45334
+ "localNetwork.addCustomAddress": {
45335
+ capName: "local-network",
45336
+ capScope: "system",
45337
+ addonId: null,
45338
+ access: "create"
45339
+ },
45147
45340
  "localNetwork.downloadCa": {
45148
45341
  capName: "local-network",
45149
45342
  capScope: "system",
45150
45343
  addonId: null,
45151
45344
  access: "view"
45152
45345
  },
45346
+ "localNetwork.getAddresses": {
45347
+ capName: "local-network",
45348
+ capScope: "system",
45349
+ addonId: null,
45350
+ access: "view"
45351
+ },
45153
45352
  "localNetwork.getAllowedAddresses": {
45154
45353
  capName: "local-network",
45155
45354
  capScope: "system",
@@ -45162,6 +45361,12 @@ Object.freeze({
45162
45361
  addonId: null,
45163
45362
  access: "view"
45164
45363
  },
45364
+ "localNetwork.getHubAddresses": {
45365
+ capName: "local-network",
45366
+ capScope: "system",
45367
+ addonId: null,
45368
+ access: "view"
45369
+ },
45165
45370
  "localNetwork.getNotificationEndpoint": {
45166
45371
  capName: "local-network",
45167
45372
  capScope: "system",
@@ -45198,6 +45403,12 @@ Object.freeze({
45198
45403
  addonId: null,
45199
45404
  access: "create"
45200
45405
  },
45406
+ "localNetwork.removeCustomAddress": {
45407
+ capName: "local-network",
45408
+ capScope: "system",
45409
+ addonId: null,
45410
+ access: "delete"
45411
+ },
45201
45412
  "localNetwork.resetAllowlistToBestMatch": {
45202
45413
  capName: "local-network",
45203
45414
  capScope: "system",
@@ -45210,6 +45421,12 @@ Object.freeze({
45210
45421
  addonId: null,
45211
45422
  access: "create"
45212
45423
  },
45424
+ "localNetwork.setAddressRole": {
45425
+ capName: "local-network",
45426
+ capScope: "system",
45427
+ addonId: null,
45428
+ access: "create"
45429
+ },
45213
45430
  "localNetwork.setAllowedAddresses": {
45214
45431
  capName: "local-network",
45215
45432
  capScope: "system",
@@ -49464,6 +49681,12 @@ Object.freeze({
49464
49681
  addonId: null,
49465
49682
  access: "create"
49466
49683
  },
49684
+ "webrtcSession.applyDownlinkProbe": {
49685
+ capName: "webrtc-session",
49686
+ capScope: "device",
49687
+ addonId: null,
49688
+ access: "create"
49689
+ },
49467
49690
  "webrtcSession.closeSession": {
49468
49691
  capName: "webrtc-session",
49469
49692
  capScope: "device",
@@ -53604,6 +53827,11 @@ Object.freeze({
53604
53827
  form: "single",
53605
53828
  optional: false
53606
53829
  }],
53830
+ "webrtcSession.applyDownlinkProbe": [{
53831
+ name: "deviceId",
53832
+ form: "single",
53833
+ optional: false
53834
+ }],
53607
53835
  "webrtcSession.closeSession": [{
53608
53836
  name: "deviceId",
53609
53837
  form: "single",
@@ -53833,6 +54061,8 @@ new Map(Object.entries({
53833
54061
  "detection-blind": "device-events",
53834
54062
  "node-online": "system",
53835
54063
  "node-offline": "system",
54064
+ "node-restarting": "system",
54065
+ "node-updating": "system",
53836
54066
  "node-inference-unavailable": "system",
53837
54067
  "addon-crash-loop": "system",
53838
54068
  "addon-update-available": "system",
@@ -53910,6 +54140,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
53910
54140
  kinds: [
53911
54141
  "node-offline",
53912
54142
  "node-online",
54143
+ "node-restarting",
53913
54144
  "node-inference-unavailable"
53914
54145
  ]
53915
54146
  },
@@ -53931,6 +54162,7 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
53931
54162
  label: "Server & container updates",
53932
54163
  kinds: [
53933
54164
  "server-update-available",
54165
+ "node-updating",
53934
54166
  "server-updated",
53935
54167
  "wrapper-update-available"
53936
54168
  ]
@@ -54078,6 +54310,7 @@ var STATE_SUMMARY_SECTION_VARS = [
54078
54310
  kinds: [
54079
54311
  "node-offline",
54080
54312
  "node-online",
54313
+ "node-restarting",
54081
54314
  "node-inference-unavailable"
54082
54315
  ]
54083
54316
  },
@@ -54099,6 +54332,7 @@ var STATE_SUMMARY_SECTION_VARS = [
54099
54332
  example: "server 1.2.377 → 1.2.378",
54100
54333
  kinds: [
54101
54334
  "server-update-available",
54335
+ "node-updating",
54102
54336
  "server-updated",
54103
54337
  "wrapper-update-available"
54104
54338
  ]
@@ -54131,7 +54365,7 @@ var STATE_SUMMARY_VARS = [
54131
54365
  {
54132
54366
  name: "summarySection",
54133
54367
  label: "Summary: this section",
54134
- description: "The section a per-section summary row is about (D698); on a summary sent as one message, every section it reports, comma-separated.",
54368
+ description: "The section a per-section summary row is about; on a summary sent as one message, every section it reports, comma-separated.",
54135
54369
  example: "Batterie scariche",
54136
54370
  group: "system",
54137
54371
  families: ["rule"],
@@ -54554,10 +54788,9 @@ TimelapseRuleInputSchema.extend({
54554
54788
  createdAt: number(),
54555
54789
  updatedAt: number()
54556
54790
  });
54557
- async function readHubMotionDetected(deviceState, deviceId) {
54558
- let slice;
54791
+ async function readSlice(deviceState, deviceId) {
54559
54792
  try {
54560
- slice = await deviceState.getCapSlice.query({
54793
+ return await deviceState.getCapSlice.query({
54561
54794
  deviceId,
54562
54795
  capName: "motion"
54563
54796
  });
@@ -54565,10 +54798,44 @@ async function readHubMotionDetected(deviceState, deviceId) {
54565
54798
  const reason = err instanceof Error ? err.message : String(err);
54566
54799
  throw new Error(`motion state of device ${deviceId} is unreadable: ${reason}`, { cause: err });
54567
54800
  }
54568
- const detected = slice?.["detected"];
54801
+ }
54802
+ /**
54803
+ * The hub's `motion` slice as a `MotionStatus`, or `null` when nobody has
54804
+ * published it since the hub started. Throws when the hub does not answer or
54805
+ * the slice is malformed — never a made-up "no motion".
54806
+ */
54807
+ async function readHubMotionStatus(deviceState, deviceId) {
54808
+ const slice = await readSlice(deviceState, deviceId);
54809
+ if (slice === null) return null;
54810
+ const parsed = MotionStatusSchema.safeParse(slice);
54811
+ if (!parsed.success) throw new Error(`motion state of device ${deviceId} is malformed on the hub: ${parsed.error.message}`);
54812
+ return parsed.data;
54813
+ }
54814
+ async function readHubMotionDetected(deviceState, deviceId) {
54815
+ const detected = (await readSlice(deviceState, deviceId))?.["detected"];
54569
54816
  if (typeof detected !== "boolean") throw new Error(`motion state of device ${deviceId} is not published yet (unknown)`);
54570
54817
  return detected;
54571
54818
  }
54819
+ /**
54820
+ * The native `motion` provider of a camera whose slice the orchestrator writes
54821
+ * (D696): `isDetected` AND `getStatus`, both from the hub. `owner` names the
54822
+ * provider class in the deviceId-mismatch error.
54823
+ */
54824
+ function hubMotionNativeProvider(deviceState, deviceId, owner) {
54825
+ const ownDevice = (asked) => {
54826
+ if (asked !== deviceId) throw new Error(`${owner}: motion deviceId mismatch, expected ${deviceId}, got ${asked}`);
54827
+ };
54828
+ return {
54829
+ isDetected: async ({ deviceId: asked }) => {
54830
+ ownDevice(asked);
54831
+ return readHubMotionDetected(deviceState, deviceId);
54832
+ },
54833
+ getStatus: async ({ deviceId: asked }) => {
54834
+ ownDevice(asked);
54835
+ return readHubMotionStatus(deviceState, deviceId);
54836
+ }
54837
+ };
54838
+ }
54572
54839
  MotionOnMotionChangedDataSchema.omit({ triggeredBy: true });
54573
54840
  function providerMotionEvent(source, data) {
54574
54841
  return createEvent(EventCategory.ProviderMotion, source, data);
@@ -55614,7 +55881,7 @@ function createClipStreamHandler(deps) {
55614
55881
  * Node-only (`node:child_process`), so it lives under `@camstack/types/node`.
55615
55882
  */
55616
55883
  /** The detail a site refusing for want of a binary puts in its refusal. */
55617
- var NO_PINNED_FFMPEG_DETAIL = "no pinned ffmpeg on this node (D540)";
55884
+ var NO_PINNED_FFMPEG_DETAIL = "no pinned ffmpeg on this node";
55618
55885
  /**
55619
55886
  * {@link pinnedFfmpegSpawner}, asked at the point of use through the node's
55620
55887
  * resolver (`memoizePinnedFfmpeg`). A site that keeps the RESOLVER rather than
@@ -66944,15 +67211,14 @@ var HikvisionCamera = class HikvisionCamera extends BaseDevice {
66944
67211
  * The native `motion` cap. Its presence is what defaults the camera to
66945
67212
  * `motionSources: ['onboard']`. This provider writes NO `motion` slice (D696):
66946
67213
  * the orchestrator is its only writer, with the EFFECTIVE motion, on the hub.
66947
- * `isDetected` therefore answers from the hub's slice; an unreadable hub, or
66948
- * a slice nobody has published since the hub started, makes the call fail.
66949
- * It never answers `false` for "unknown" (D49, D393).
67214
+ * `isDetected` AND `getStatus` therefore answer from the hub's slice
67215
+ * (`hubMotionNativeProvider`; without its own `getStatus` the framework's
67216
+ * default reads this process's empty local state and answers `null`). An
67217
+ * unreadable hub fails both; never `false` for "unknown" (D49, D393).
66950
67218
  */
66951
67219
  registerMotionCap() {
66952
- this.ctx.registerNativeCap(motionCapability, { isDetected: async ({ deviceId }) => {
66953
- if (deviceId !== this.id) throw new Error(`HikvisionCamera: deviceId mismatch, expected ${this.id}, got ${deviceId}`);
66954
- return readHubMotionDetected(this.ctx.api.deviceState, this.id);
66955
- } });
67220
+ const motionProvider = hubMotionNativeProvider(this.ctx.api.deviceState, this.id, "HikvisionCamera");
67221
+ this.ctx.registerNativeCap(motionCapability, motionProvider);
66956
67222
  }
66957
67223
  handleMotionEvent(ev, camStreamId) {
66958
67224
  const now = ev.observedAt;