@camstack/addon-provider-homematic 1.2.125 → 1.2.126

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 +123 -77
  2. package/dist/addon.mjs +123 -77
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -10543,11 +10543,11 @@ var ModelVariantGroupSchema = object({
10543
10543
  /** Quantization axis. Omit ⇒ the fp32 base build. */
10544
10544
  precision: _enum(["fp32", "int8"]).optional(),
10545
10545
  /**
10546
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
10547
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
10548
- * future performance variants plug into.
10546
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
10547
+ * an alternate training of the same family (Scrypted `relu_test`); chip
10548
+ * label is "Test".
10549
10549
  */
10550
- optimization: _enum(["standard", "fast"]).optional(),
10550
+ optimization: _enum(["standard", "test"]).optional(),
10551
10551
  /**
10552
10552
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
10553
10553
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -10570,9 +10570,10 @@ var ModelProviderIdSchema = _enum([
10570
10570
  * are per upstream. A persisted custom-model row written when this field was a
10571
10571
  * string still parses — the string is lifted into `{ weights }`.
10572
10572
  *
10573
- * Every licence surface (the admin "Models and licenses" page,
10574
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
10575
- * these records by `scripts/gen-model-licenses.ts` (D661).
10573
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
10574
+ * model table) is GENERATED from these records by
10575
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
10576
+ * `camstack/docs` → `/docs/detection/models`.
10576
10577
  */
10577
10578
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
10578
10579
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -14252,7 +14253,7 @@ DeviceType.Camera;
14252
14253
  * This matters here more than anywhere else in the repo, because every provider
14253
14254
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14254
14255
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14255
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14256
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14256
14257
  * camera's own page will ask for its own login. That is correct, and pre-
14257
14258
  * filling it is the operator's business, not ours.
14258
14259
  *
@@ -17554,7 +17555,7 @@ method(object({
17554
17555
  timeoutMs: 6e5
17555
17556
  });
17556
17557
  method(object({
17557
- nodeId: string(),
17558
+ targetNodeId: string(),
17558
17559
  modelId: string(),
17559
17560
  format: _enum(MODEL_FORMATS),
17560
17561
  entry: ModelCatalogEntrySchema
@@ -20058,8 +20059,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20058
20059
  disabledTargetIds: array(string()).default([])
20059
20060
  });
20060
20061
  /**
20061
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20062
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
20062
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
20063
+ * report a still-true state. `addons` is the crash-looped addons only and
20064
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
20063
20065
  * job is not an open state, and the alarm stays instant.
20064
20066
  */
20065
20067
  var NcStateSummarySectionIdSchema = _enum([
@@ -20071,6 +20073,7 @@ var NcStateSummarySectionIdSchema = _enum([
20071
20073
  "detection-blind",
20072
20074
  "nodes",
20073
20075
  "addons",
20076
+ "addon-updates",
20074
20077
  "updates"
20075
20078
  ]);
20076
20079
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20551,7 +20554,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20551
20554
  * When this mode may be armed. Absent / null = always allowed (same as a
20552
20555
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20553
20556
  */
20554
- schedule: NcScheduleSchema.optional()
20557
+ schedule: NcScheduleSchema.optional(),
20558
+ /**
20559
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20560
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20561
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20562
+ */
20563
+ notifyDuringEntryDelay: boolean().optional(),
20564
+ /**
20565
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20566
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20567
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20568
+ */
20569
+ notifySensorRewatched: boolean().optional()
20555
20570
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20556
20571
  var NcAlarmModeDelaysEditListSchema = array(object({
20557
20572
  mode: AlarmArmModeSchema,
@@ -20560,7 +20575,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20560
20575
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20561
20576
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20562
20577
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20563
- schedule: NcScheduleSchema.nullable().optional()
20578
+ schedule: NcScheduleSchema.nullable().optional(),
20579
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20580
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20581
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20582
+ notifySensorRewatched: boolean().nullable().optional()
20564
20583
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20565
20584
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20566
20585
  var NcAlarmNonBlockingEditSchema = object({
@@ -21521,39 +21540,19 @@ Object.freeze(Object.fromEntries([{
21521
21540
  label: "Face recognition model",
21522
21541
  defaultModelId: "auraface-r100",
21523
21542
  indexName: "the enrolled face gallery",
21524
- options: [
21525
- {
21526
- id: "auraface-r100",
21527
- label: "AuraFace R100"
21528
- },
21529
- {
21530
- id: "arcface-r100",
21531
- label: "ArcFace (ResNet34)"
21532
- },
21533
- {
21534
- id: "inception-resnet-v1",
21535
- label: "Inception ResNet V1"
21536
- }
21537
- ]
21543
+ options: [{
21544
+ id: "auraface-r100",
21545
+ label: "AuraFace R100"
21546
+ }]
21538
21547
  }, {
21539
21548
  stepId: "clip-embedding",
21540
21549
  label: "Semantic search model",
21541
- defaultModelId: "mobileclip-s1",
21550
+ defaultModelId: "siglip2-b16-224",
21542
21551
  indexName: "the object semantic-search index",
21543
- options: [
21544
- {
21545
- id: "mobileclip-s1",
21546
- label: "MobileCLIP S1"
21547
- },
21548
- {
21549
- id: "mobileclip-s2",
21550
- label: "MobileCLIP S2"
21551
- },
21552
- {
21553
- id: "siglip2-b16-224",
21554
- label: "SigLIP2 B/16 (Apache-2.0)"
21555
- }
21556
- ]
21552
+ options: [{
21553
+ id: "siglip2-b16-224",
21554
+ label: "SigLIP2 B/16 (Apache-2.0)"
21555
+ }]
21557
21556
  }].map((s) => [s.stepId, s.defaultModelId])));
21558
21557
  var CLUSTER_STEP_SETTING_FIELDS = [{
21559
21558
  stepId: "face-embedding",
@@ -24441,6 +24440,22 @@ var MotionSourceEnum = _enum([
24441
24440
  "device-activity"
24442
24441
  ]);
24443
24442
  /**
24443
+ * What opened an on-motion detection SESSION: the motion source that passed the
24444
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
24445
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
24446
+ * device name as the orchestrator's camera-sensors resolution last read it;
24447
+ * absent when unknown or when the camera itself triggered.
24448
+ *
24449
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
24450
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
24451
+ * runner never decides anything on it.
24452
+ */
24453
+ var SessionTriggerSchema = object({
24454
+ source: MotionSourceEnum,
24455
+ triggeredBy: MotionTriggeredBySchema,
24456
+ sensorName: string().optional()
24457
+ });
24458
+ /**
24444
24459
  * List of motion sources active on a camera. Empty array is valid:
24445
24460
  * "no source" — happens for battery cams without firmware motion when
24446
24461
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24692,6 +24707,14 @@ var RunnerCameraConfigSchema = object({
24692
24707
  */
24693
24708
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24694
24709
  /**
24710
+ * What opened this attach, on a SESSION attach only (see
24711
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24712
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24713
+ * behind it, and every attach from an orchestrator older than the field — the
24714
+ * runner then names no source on the phase event.
24715
+ */
24716
+ sessionTrigger: SessionTriggerSchema.optional(),
24717
+ /**
24695
24718
  * WHICH root detector runs for this camera. The detection counterpart of
24696
24719
  * {@link motionSources}, same shape and same discipline: a per-camera list
24697
24720
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32080,7 +32103,7 @@ var LocalInterfaceSchema = object({
32080
32103
  name: string(),
32081
32104
  family: _enum(["IPv4", "IPv6"]),
32082
32105
  address: string(),
32083
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
32106
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32084
32107
  cidr: string(),
32085
32108
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32086
32109
  netmask: string(),
@@ -32134,7 +32157,8 @@ var ConnectionEndpointSchema = object({
32134
32157
  "lan-ipv4",
32135
32158
  "lan-ipv6",
32136
32159
  "public",
32137
- "loopback"
32160
+ "loopback",
32161
+ "app-link"
32138
32162
  ]),
32139
32163
  /**
32140
32164
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -32203,15 +32227,27 @@ var GetConnectionEndpointsResultSchema = object({
32203
32227
  localPort: AdvertisedLocalPortSchema
32204
32228
  });
32205
32229
  /**
32206
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
32207
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
32208
- * what AUTO currently picks, so the UI can show the effective value either way.
32230
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
32231
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
32232
+ * so the UI can show it either way.
32209
32233
  */
32210
32234
  var NotificationEndpointSchema = object({
32211
32235
  /** The operator's explicit choice, or null for AUTO. */
32212
32236
  baseUrl: string().nullable(),
32213
- /** What the ranking currently resolves to (null when nothing is reachable). */
32214
- resolved: string().nullable()
32237
+ /**
32238
+ * The effective flagged address: the explicit choice, else (AUTO) the
32239
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
32240
+ * answered the public tunnel / mesh here, or null.
32241
+ */
32242
+ resolved: string().nullable(),
32243
+ /**
32244
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
32245
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
32246
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
32247
+ * hub advertises neither; the app link is then minted without `hub=`.
32248
+ * Absent on a pre-D709 hub.
32249
+ */
32250
+ appLinkHub: string().nullable()
32215
32251
  });
32216
32252
  /**
32217
32253
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -32265,7 +32301,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
32265
32301
  * Pass `'https'` when the caller is itself loaded over HTTPS
32266
32302
  * to avoid mixed-content blocks in the browser. The public
32267
32303
  * tunnel always emits `https://` regardless. */
32268
- scheme: _enum(["http", "https"]).optional()
32304
+ scheme: _enum(["http", "https"]).optional(),
32305
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
32306
+ * an address notification links can be flagged with, not a hub
32307
+ * route. Default `false`: racers and rankers never see it. */
32308
+ includeAppLink: boolean().optional()
32269
32309
  }), 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, {
32270
32310
  kind: "mutation",
32271
32311
  auth: "admin"
@@ -32594,7 +32634,7 @@ var MeshPeerSchema = object({
32594
32634
  tags: array(string()).readonly(),
32595
32635
  /** True when the peer advertises itself as an exit-node candidate. */
32596
32636
  exitNodeOption: boolean(),
32597
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
32637
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
32598
32638
  advertisedRoutes: array(string()).readonly(),
32599
32639
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
32600
32640
  userLogin: string().nullable(),
@@ -33922,7 +33962,13 @@ var OsdStatusSchema = object({ overlays: array(object({
33922
33962
  */
33923
33963
  availablePositions: array(OsdPositionEnum).readonly(),
33924
33964
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
33925
- readOnly: boolean().optional()
33965
+ readOnly: boolean().optional(),
33966
+ /**
33967
+ * Firmware text ceiling for this overlay. Absent = no known limit.
33968
+ * The OSD manager truncates here on every write — never stores its own
33969
+ * copy on the binding.
33970
+ */
33971
+ maxCharacters: number().int().positive().optional()
33926
33972
  })).readonly() });
33927
33973
  var OsdOverlayPatchSchema = object({
33928
33974
  enabled: boolean().optional(),
@@ -33973,7 +34019,9 @@ var OsdTemplateBindingSchema = object({
33973
34019
  valuePath: string().min(1).max(64),
33974
34020
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
33975
34021
  displayUnit: string().max(16).optional(),
33976
- maxDecimals: number().int().min(0).max(4).default(1)
34022
+ maxDecimals: number().int().min(0).max(4).default(1),
34023
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
34024
+ valueMap: record(string(), string()).optional()
33977
34025
  });
33978
34026
  /**
33979
34027
  * A named template: bindings (alias → leaf field) + a parser that
@@ -34023,18 +34071,11 @@ var OsdSlotBindingSchema = object({
34023
34071
  source: OsdSourceSchema,
34024
34072
  /** `${value}` and `${unit}` are substituted; every occurrence. */
34025
34073
  template: string().max(96).default("${value}"),
34026
- /** Truncate with an ellipsis past this length. Absent = no limit. */
34027
- maxCharacters: number().int().min(4).max(64).optional(),
34028
34074
  /**
34029
34075
  * Decimal places for a numeric value. `0` yields an integer — the
34030
34076
  * documented workaround for firmwares that reject `.` in overlay text.
34031
34077
  */
34032
34078
  maxDecimals: number().int().min(0).max(4).default(1),
34033
- /**
34034
- * Appended via `${unit}` when no unit conversion produces a label.
34035
- * Prefer `source.displayUnit` for converted device-state values.
34036
- */
34037
- unitLabel: string().max(8).optional(),
34038
34079
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
34039
34080
  valueMap: record(string(), string()).optional(),
34040
34081
  /** Time windows in which the slot is shown. Absent = always. */
@@ -34043,9 +34084,7 @@ var OsdSlotBindingSchema = object({
34043
34084
  * Display gate, in the notification centre's condition vocabulary.
34044
34085
  * Only the keys reported by `getConditionSupport` are accepted.
34045
34086
  */
34046
- conditions: NcConditionsSchema.optional(),
34047
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
34048
- fallbackText: string().max(64).default("")
34087
+ conditions: NcConditionsSchema.optional()
34049
34088
  });
34050
34089
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
34051
34090
  var OsdSlotViewSchema = object({
@@ -52278,12 +52317,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
52278
52317
  {
52279
52318
  id: "addons",
52280
52319
  family: "system",
52281
- label: "Addons",
52282
- kinds: [
52283
- "addon-crash-loop",
52284
- "addon-update-available",
52285
- "addon-updated"
52286
- ]
52320
+ label: "Addons stopped",
52321
+ kinds: ["addon-crash-loop"]
52322
+ },
52323
+ {
52324
+ id: "addon-updates",
52325
+ family: "system",
52326
+ label: "Addon updates",
52327
+ kinds: ["addon-update-available", "addon-updated"]
52287
52328
  },
52288
52329
  {
52289
52330
  id: "updates",
@@ -52443,13 +52484,15 @@ var STATE_SUMMARY_SECTION_VARS = [
52443
52484
  },
52444
52485
  {
52445
52486
  name: "summaryAddons",
52446
- label: "Summary: addons",
52447
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
52448
- kinds: [
52449
- "addon-crash-loop",
52450
- "addon-update-available",
52451
- "addon-updated"
52452
- ]
52487
+ label: "Summary: addons stopped",
52488
+ example: "hub — recorder stopped after repeated crashes",
52489
+ kinds: ["addon-crash-loop"]
52490
+ },
52491
+ {
52492
+ name: "summaryAddonUpdates",
52493
+ label: "Summary: addon updates",
52494
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
52495
+ kinds: ["addon-update-available", "addon-updated"]
52453
52496
  },
52454
52497
  {
52455
52498
  name: "summaryUpdates",
@@ -52533,6 +52576,7 @@ var STATE_SUMMARY_VARS = [
52533
52576
  [...RULE_BODY_ONLY],
52534
52577
  [...RULE_TEXT],
52535
52578
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
52579
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
52536
52580
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
52537
52581
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
52538
52582
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -52573,6 +52617,8 @@ var STATE_SUMMARY_VARS = [
52573
52617
  [...RULE_TEXT],
52574
52618
  [...RULE_TEXT],
52575
52619
  [...RULE_TEXT],
52620
+ [...RULE_TEXT],
52621
+ [...RULE_TEXT],
52576
52622
  ...STATE_SUMMARY_VARS
52577
52623
  ];
52578
52624
  new Set([
@@ -53299,7 +53345,7 @@ function buildConnectionFormSchema() {
53299
53345
  key: "host",
53300
53346
  label: "Host / IP",
53301
53347
  required: true,
53302
- placeholder: "192.168.x.x"
53348
+ placeholder: "192.168.10.50"
53303
53349
  }]
53304
53350
  },
53305
53351
  {
package/dist/addon.mjs CHANGED
@@ -10544,11 +10544,11 @@ var ModelVariantGroupSchema = object({
10544
10544
  /** Quantization axis. Omit ⇒ the fp32 base build. */
10545
10545
  precision: _enum(["fp32", "int8"]).optional(),
10546
10546
  /**
10547
- * Speed-optimization axis. Omit ⇒ the standard build. `fast` marks a
10548
- * latency-optimized export (e.g. ReLU-activation variant) — the slot the
10549
- * future performance variants plug into.
10547
+ * Training / latency-variant axis. Omit ⇒ the standard build. `test` marks
10548
+ * an alternate training of the same family (Scrypted `relu_test`); chip
10549
+ * label is "Test".
10550
10550
  */
10551
- optimization: _enum(["standard", "fast"]).optional(),
10551
+ optimization: _enum(["standard", "test"]).optional(),
10552
10552
  /**
10553
10553
  * Input-resolution axis (square input side, px). Omit ⇒ the family's native
10554
10554
  * resolution (640 for yolo26). Reduced-input builds (320 / 256) are a big,
@@ -10571,9 +10571,10 @@ var ModelProviderIdSchema = _enum([
10571
10571
  * are per upstream. A persisted custom-model row written when this field was a
10572
10572
  * string still parses — the string is lifted into `{ weights }`.
10573
10573
  *
10574
- * Every licence surface (the admin "Models and licenses" page,
10575
- * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
10576
- * these records by `scripts/gen-model-licenses.ts` (D661).
10574
+ * Every machine licence surface (`THIRD_PARTY_MODELS.md`, the Hugging Face
10575
+ * model table) is GENERATED from these records by
10576
+ * `scripts/gen-model-licenses.ts` (D661). Operator-facing docs live in
10577
+ * `camstack/docs` → `/docs/detection/models`.
10577
10578
  */
10578
10579
  var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
10579
10580
  /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
@@ -14253,7 +14254,7 @@ DeviceType.Camera;
14253
14254
  * This matters here more than anywhere else in the repo, because every provider
14254
14255
  * that knows a device's host knows its PASSWORD too: `{ host, port, username,
14255
14256
  * password }` sit in one object on Hikvision, Amcrest, Reolink and ONVIF alike,
14256
- * and `http://admin:hunter2@192.168.x.x/` is a URL a browser accepts. The
14257
+ * and `http://admin:hunter2@192.168.60.139/` is a URL a browser accepts. The
14257
14258
  * camera's own page will ask for its own login. That is correct, and pre-
14258
14259
  * filling it is the operator's business, not ours.
14259
14260
  *
@@ -17555,7 +17556,7 @@ method(object({
17555
17556
  timeoutMs: 6e5
17556
17557
  });
17557
17558
  method(object({
17558
- nodeId: string(),
17559
+ targetNodeId: string(),
17559
17560
  modelId: string(),
17560
17561
  format: _enum(MODEL_FORMATS),
17561
17562
  entry: ModelCatalogEntrySchema
@@ -20059,8 +20060,9 @@ var NcRuleSchema = NcRuleInputSchema.extend({
20059
20060
  disabledTargetIds: array(string()).default([])
20060
20061
  });
20061
20062
  /**
20062
- * The state-summary SECTIONS (D647 / D698): the D637 kind groups that report a
20063
- * still-true state. `backups-exports` and `alarm` are not sections — a completed
20063
+ * The state-summary SECTIONS (D647 / D698 / D708): the D637 kind groups that
20064
+ * report a still-true state. `addons` is the crash-looped addons only and
20065
+ * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
20064
20066
  * job is not an open state, and the alarm stays instant.
20065
20067
  */
20066
20068
  var NcStateSummarySectionIdSchema = _enum([
@@ -20072,6 +20074,7 @@ var NcStateSummarySectionIdSchema = _enum([
20072
20074
  "detection-blind",
20073
20075
  "nodes",
20074
20076
  "addons",
20077
+ "addon-updates",
20075
20078
  "updates"
20076
20079
  ]);
20077
20080
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
@@ -20552,7 +20555,19 @@ var NcAlarmModeDelaysListSchema = array(object({
20552
20555
  * When this mode may be armed. Absent / null = always allowed (same as a
20553
20556
  * rule with no `schedule`). Evaluated with {@link isScheduleActive}.
20554
20557
  */
20555
- schedule: NcScheduleSchema.optional()
20558
+ schedule: NcScheduleSchema.optional(),
20559
+ /**
20560
+ * D706: while this mode's ENTRY DELAY runs, do the alarm rules' own pushes go out (as an
20561
+ * intrusion naming the locations)? Absent = false — the entry-delay notification is the
20562
+ * only one, and the matches ride the triggered notification's mosaic (D705).
20563
+ */
20564
+ notifyDuringEntryDelay: boolean().optional(),
20565
+ /**
20566
+ * D706: notify "watched again" when a sensor this arm bypassed closes and opens again.
20567
+ * Absent = false (logged, not sent). Even when true it is not sent when that same sensor
20568
+ * is the one that starts the entry delay — the entry-delay notification already names it.
20569
+ */
20570
+ notifySensorRewatched: boolean().optional()
20556
20571
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one entry per arm mode" });
20557
20572
  var NcAlarmModeDelaysEditListSchema = array(object({
20558
20573
  mode: AlarmArmModeSchema,
@@ -20561,7 +20576,11 @@ var NcAlarmModeDelaysEditListSchema = array(object({
20561
20576
  triggeredDurationSec: NcAlarmTriggeredSecSchema.nullable().optional(),
20562
20577
  postTriggeredAction: NcAlarmPostTriggeredActionSchema.nullable().optional(),
20563
20578
  /** Set a schedule, or `null` to clear (mode always allowed again). */
20564
- schedule: NcScheduleSchema.nullable().optional()
20579
+ schedule: NcScheduleSchema.nullable().optional(),
20580
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20581
+ notifyDuringEntryDelay: boolean().nullable().optional(),
20582
+ /** D706: set the switch, or `null` to clear it (back to the default, false). */
20583
+ notifySensorRewatched: boolean().nullable().optional()
20565
20584
  })).max(8).refine(uniqueModes, { message: "modeDelays: at most one edit per arm mode" });
20566
20585
  /** One switch of the alarm table: put ONE device on, or take it off, ONE mode's list. */
20567
20586
  var NcAlarmNonBlockingEditSchema = object({
@@ -21522,39 +21541,19 @@ Object.freeze(Object.fromEntries([{
21522
21541
  label: "Face recognition model",
21523
21542
  defaultModelId: "auraface-r100",
21524
21543
  indexName: "the enrolled face gallery",
21525
- options: [
21526
- {
21527
- id: "auraface-r100",
21528
- label: "AuraFace R100"
21529
- },
21530
- {
21531
- id: "arcface-r100",
21532
- label: "ArcFace (ResNet34)"
21533
- },
21534
- {
21535
- id: "inception-resnet-v1",
21536
- label: "Inception ResNet V1"
21537
- }
21538
- ]
21544
+ options: [{
21545
+ id: "auraface-r100",
21546
+ label: "AuraFace R100"
21547
+ }]
21539
21548
  }, {
21540
21549
  stepId: "clip-embedding",
21541
21550
  label: "Semantic search model",
21542
- defaultModelId: "mobileclip-s1",
21551
+ defaultModelId: "siglip2-b16-224",
21543
21552
  indexName: "the object semantic-search index",
21544
- options: [
21545
- {
21546
- id: "mobileclip-s1",
21547
- label: "MobileCLIP S1"
21548
- },
21549
- {
21550
- id: "mobileclip-s2",
21551
- label: "MobileCLIP S2"
21552
- },
21553
- {
21554
- id: "siglip2-b16-224",
21555
- label: "SigLIP2 B/16 (Apache-2.0)"
21556
- }
21557
- ]
21553
+ options: [{
21554
+ id: "siglip2-b16-224",
21555
+ label: "SigLIP2 B/16 (Apache-2.0)"
21556
+ }]
21558
21557
  }].map((s) => [s.stepId, s.defaultModelId])));
21559
21558
  var CLUSTER_STEP_SETTING_FIELDS = [{
21560
21559
  stepId: "face-embedding",
@@ -24442,6 +24441,22 @@ var MotionSourceEnum = _enum([
24442
24441
  "device-activity"
24443
24442
  ]);
24444
24443
  /**
24444
+ * What opened an on-motion detection SESSION: the motion source that passed the
24445
+ * camera's `motionSources` gate, and what raised it (the camera itself, or a
24446
+ * sensor the operator attached — D672). `sensorName` is the attached sensor's
24447
+ * device name as the orchestrator's camera-sensors resolution last read it;
24448
+ * absent when unknown or when the camera itself triggered.
24449
+ *
24450
+ * Carried on the session attach ONLY so the runner's `DetectionPhaseTransition`
24451
+ * can say what started the session (D672 rule 11, amended 2026-10-06). The
24452
+ * runner never decides anything on it.
24453
+ */
24454
+ var SessionTriggerSchema = object({
24455
+ source: MotionSourceEnum,
24456
+ triggeredBy: MotionTriggeredBySchema,
24457
+ sensorName: string().optional()
24458
+ });
24459
+ /**
24445
24460
  * List of motion sources active on a camera. Empty array is valid:
24446
24461
  * "no source" — happens for battery cams without firmware motion when
24447
24462
  * the operator hasn't opted into the SW analyzer (would hold the
@@ -24693,6 +24708,14 @@ var RunnerCameraConfigSchema = object({
24693
24708
  */
24694
24709
  motionSources: MotionSourcesSchema.default(["analyzer"]),
24695
24710
  /**
24711
+ * What opened this attach, on a SESSION attach only (see
24712
+ * {@link SessionTriggerSchema}). OPTIONAL with no default: absent on a
24713
+ * standing attach, an occupancy burst, a re-dispatch with no motion event
24714
+ * behind it, and every attach from an orchestrator older than the field — the
24715
+ * runner then names no source on the phase event.
24716
+ */
24717
+ sessionTrigger: SessionTriggerSchema.optional(),
24718
+ /**
24696
24719
  * WHICH root detector runs for this camera. The detection counterpart of
24697
24720
  * {@link motionSources}, same shape and same discipline: a per-camera list
24698
24721
  * of sources the system understands, vendor-agnostic, owned here.
@@ -32081,7 +32104,7 @@ var LocalInterfaceSchema = object({
32081
32104
  name: string(),
32082
32105
  family: _enum(["IPv4", "IPv6"]),
32083
32106
  address: string(),
32084
- /** CIDR shorthand (e.g. `192.168.x.x/24`). Empty when OS doesn't expose. */
32107
+ /** CIDR shorthand (e.g. `192.168.10.10/24`). Empty when OS doesn't expose. */
32085
32108
  cidr: string(),
32086
32109
  /** OS netmask. Stable across calls so the SDK can hash on it. */
32087
32110
  netmask: string(),
@@ -32135,7 +32158,8 @@ var ConnectionEndpointSchema = object({
32135
32158
  "lan-ipv4",
32136
32159
  "lan-ipv6",
32137
32160
  "public",
32138
- "loopback"
32161
+ "loopback",
32162
+ "app-link"
32139
32163
  ]),
32140
32164
  /**
32141
32165
  * Originating-interface kind — `lan`/`wifi`/`docker`/`vpn`/`other`/
@@ -32204,15 +32228,27 @@ var GetConnectionEndpointsResultSchema = object({
32204
32228
  localPort: AdvertisedLocalPortSchema
32205
32229
  });
32206
32230
  /**
32207
- * The chosen outbound endpoint for notification artifacts. `baseUrl: null` =
32208
- * AUTO (resolved from the candidate ranking at send time); `resolved` reports
32209
- * what AUTO currently picks, so the UI can show the effective value either way.
32231
+ * The address flagged for notification links. `baseUrl: null` = AUTO, which
32232
+ * since D709 is the CamStack app link; `resolved` reports the effective value,
32233
+ * so the UI can show it either way.
32210
32234
  */
32211
32235
  var NotificationEndpointSchema = object({
32212
32236
  /** The operator's explicit choice, or null for AUTO. */
32213
32237
  baseUrl: string().nullable(),
32214
- /** What the ranking currently resolves to (null when nothing is reachable). */
32215
- resolved: string().nullable()
32238
+ /**
32239
+ * The effective flagged address: the explicit choice, else (AUTO) the
32240
+ * CamStack app link `https://camstack.zentik.app` (D709). A pre-D709 hub
32241
+ * answered the public tunnel / mesh here, or null.
32242
+ */
32243
+ resolved: string().nullable(),
32244
+ /**
32245
+ * The hub origin an app link carries as `hub=` (D709): the hub's best
32246
+ * public HTTPS address — the tunnel, then the mesh (Tailscale MagicDNS) —
32247
+ * picked from this cap's own palette by `pickAppLinkHub`. `null` when the
32248
+ * hub advertises neither; the app link is then minted without `hub=`.
32249
+ * Absent on a pre-D709 hub.
32250
+ */
32251
+ appLinkHub: string().nullable()
32216
32252
  });
32217
32253
  /**
32218
32254
  * The URLs the SDK / viewer should race for API access. `baseUrls` empty =
@@ -32266,7 +32302,11 @@ method(_void(), ListResultSchema), method(_void(), PreferredSchema), method(obje
32266
32302
  * Pass `'https'` when the caller is itself loaded over HTTPS
32267
32303
  * to avoid mixed-content blocks in the browser. The public
32268
32304
  * tunnel always emits `https://` regardless. */
32269
- scheme: _enum(["http", "https"]).optional()
32305
+ scheme: _enum(["http", "https"]).optional(),
32306
+ /** Append the CamStack app link entry (`kind: 'app-link'`, D709) —
32307
+ * an address notification links can be flagged with, not a hub
32308
+ * route. Default `false`: racers and rankers never see it. */
32309
+ includeAppLink: boolean().optional()
32270
32310
  }), 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, {
32271
32311
  kind: "mutation",
32272
32312
  auth: "admin"
@@ -32595,7 +32635,7 @@ var MeshPeerSchema = object({
32595
32635
  tags: array(string()).readonly(),
32596
32636
  /** True when the peer advertises itself as an exit-node candidate. */
32597
32637
  exitNodeOption: boolean(),
32598
- /** Subnet routes the peer advertises (e.g. `["192.168.x.x/24"]`). */
32638
+ /** Subnet routes the peer advertises (e.g. `["192.168.10.0/24"]`). */
32599
32639
  advertisedRoutes: array(string()).readonly(),
32600
32640
  /** Owner account login (e.g. `foo@example.com`). Null for tagged peers. */
32601
32641
  userLogin: string().nullable(),
@@ -33923,7 +33963,13 @@ var OsdStatusSchema = object({ overlays: array(object({
33923
33963
  */
33924
33964
  availablePositions: array(OsdPositionEnum).readonly(),
33925
33965
  /** Firmware does not allow editing the `text` field (e.g. timestamp). */
33926
- readOnly: boolean().optional()
33966
+ readOnly: boolean().optional(),
33967
+ /**
33968
+ * Firmware text ceiling for this overlay. Absent = no known limit.
33969
+ * The OSD manager truncates here on every write — never stores its own
33970
+ * copy on the binding.
33971
+ */
33972
+ maxCharacters: number().int().positive().optional()
33927
33973
  })).readonly() });
33928
33974
  var OsdOverlayPatchSchema = object({
33929
33975
  enabled: boolean().optional(),
@@ -33974,7 +34020,9 @@ var OsdTemplateBindingSchema = object({
33974
34020
  valuePath: string().min(1).max(64),
33975
34021
  /** Convert TO this unit at render (`tryConvertUnit`). Absent = source unit. */
33976
34022
  displayUnit: string().max(16).optional(),
33977
- maxDecimals: number().int().min(0).max(4).default(1)
34023
+ maxDecimals: number().int().min(0).max(4).default(1),
34024
+ /** Raw value → display text (same shape as slot binding). Empty string hides. */
34025
+ valueMap: record(string(), string()).optional()
33978
34026
  });
33979
34027
  /**
33980
34028
  * A named template: bindings (alias → leaf field) + a parser that
@@ -34024,18 +34072,11 @@ var OsdSlotBindingSchema = object({
34024
34072
  source: OsdSourceSchema,
34025
34073
  /** `${value}` and `${unit}` are substituted; every occurrence. */
34026
34074
  template: string().max(96).default("${value}"),
34027
- /** Truncate with an ellipsis past this length. Absent = no limit. */
34028
- maxCharacters: number().int().min(4).max(64).optional(),
34029
34075
  /**
34030
34076
  * Decimal places for a numeric value. `0` yields an integer — the
34031
34077
  * documented workaround for firmwares that reject `.` in overlay text.
34032
34078
  */
34033
34079
  maxDecimals: number().int().min(0).max(4).default(1),
34034
- /**
34035
- * Appended via `${unit}` when no unit conversion produces a label.
34036
- * Prefer `source.displayUnit` for converted device-state values.
34037
- */
34038
- unitLabel: string().max(8).optional(),
34039
34080
  /** Raw value → display text, e.g. `{"true":"MOTION","false":""}`. */
34040
34081
  valueMap: record(string(), string()).optional(),
34041
34082
  /** Time windows in which the slot is shown. Absent = always. */
@@ -34044,9 +34085,7 @@ var OsdSlotBindingSchema = object({
34044
34085
  * Display gate, in the notification centre's condition vocabulary.
34045
34086
  * Only the keys reported by `getConditionSupport` are accepted.
34046
34087
  */
34047
- conditions: NcConditionsSchema.optional(),
34048
- /** Rendered when the gate is closed or the value unreadable. Empty = hide. */
34049
- fallbackText: string().max(64).default("")
34088
+ conditions: NcConditionsSchema.optional()
34050
34089
  });
34051
34090
  /** One camera slot, as the operator sees it: firmware truth + our binding. */
34052
34091
  var OsdSlotViewSchema = object({
@@ -52279,12 +52318,14 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
52279
52318
  {
52280
52319
  id: "addons",
52281
52320
  family: "system",
52282
- label: "Addons",
52283
- kinds: [
52284
- "addon-crash-loop",
52285
- "addon-update-available",
52286
- "addon-updated"
52287
- ]
52321
+ label: "Addons stopped",
52322
+ kinds: ["addon-crash-loop"]
52323
+ },
52324
+ {
52325
+ id: "addon-updates",
52326
+ family: "system",
52327
+ label: "Addon updates",
52328
+ kinds: ["addon-update-available", "addon-updated"]
52288
52329
  },
52289
52330
  {
52290
52331
  id: "updates",
@@ -52444,13 +52485,15 @@ var STATE_SUMMARY_SECTION_VARS = [
52444
52485
  },
52445
52486
  {
52446
52487
  name: "summaryAddons",
52447
- label: "Summary: addons",
52448
- example: "@camstack/addon-recorder 1.2.3 → 1.2.4",
52449
- kinds: [
52450
- "addon-crash-loop",
52451
- "addon-update-available",
52452
- "addon-updated"
52453
- ]
52488
+ label: "Summary: addons stopped",
52489
+ example: "hub — recorder stopped after repeated crashes",
52490
+ kinds: ["addon-crash-loop"]
52491
+ },
52492
+ {
52493
+ name: "summaryAddonUpdates",
52494
+ label: "Summary: addon updates",
52495
+ example: "hub:\n• @camstack/addon-recorder 1.2.3 → 1.2.4",
52496
+ kinds: ["addon-update-available", "addon-updated"]
52454
52497
  },
52455
52498
  {
52456
52499
  name: "summaryUpdates",
@@ -52534,6 +52577,7 @@ var STATE_SUMMARY_VARS = [
52534
52577
  [...RULE_BODY_ONLY],
52535
52578
  [...RULE_TEXT],
52536
52579
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
52580
+ ([...RULE_TEXT], [...COMBINED_ALARM]),
52537
52581
  ([...RULE_TEXT], [...DEVICE_EVENTS]),
52538
52582
  ([...RULE_TEXT], [...BATTERY, ...CONSUMABLE]),
52539
52583
  ([...RULE_TEXT], [...CONSUMABLE]),
@@ -52574,6 +52618,8 @@ var STATE_SUMMARY_VARS = [
52574
52618
  [...RULE_TEXT],
52575
52619
  [...RULE_TEXT],
52576
52620
  [...RULE_TEXT],
52621
+ [...RULE_TEXT],
52622
+ [...RULE_TEXT],
52577
52623
  ...STATE_SUMMARY_VARS
52578
52624
  ];
52579
52625
  new Set([
@@ -53300,7 +53346,7 @@ function buildConnectionFormSchema() {
53300
53346
  key: "host",
53301
53347
  label: "Host / IP",
53302
53348
  required: true,
53303
- placeholder: "192.168.x.x"
53349
+ placeholder: "192.168.10.50"
53304
53350
  }]
53305
53351
  },
53306
53352
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-homematic",
3
- "version": "1.2.125",
3
+ "version": "1.2.126",
4
4
  "description": "Homematic / HomematicIP (CCU3 / RaspberryMatic) device-provider addon for CamStack — wraps the nodehomematic library",
5
5
  "keywords": [
6
6
  "camstack",