@camstack/addon-model-studio 1.1.181 → 1.1.183
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/{MotionZonesSettings-D2-zQjQZ.mjs → MotionZonesSettings-D5fe7czg.mjs} +2 -2
- package/dist/{PrivacyMaskSettings-DvWwawcZ.mjs → PrivacyMaskSettings-C2hylmd3.mjs} +4 -4
- package/dist/{SceneMonitorEditor-Duajxv_A.mjs → SceneMonitorEditor-CLZ8DeD3.mjs} +3 -3
- package/dist/_stub.js +15 -15
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-BBY6_TNd.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-Ca-jPREF.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CEWbeCwN.mjs +26 -0
- package/dist/{hostInit-D9K6OWiX.mjs → hostInit-DiUsU_UL.mjs} +2 -2
- package/dist/model-studio.addon.js +273 -205
- package/dist/model-studio.addon.mjs +273 -205
- package/dist/{player-overlays-BYYRZ16B.mjs → player-overlays-CgxP2Qzw.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/dist/{responsive-D88q7dKI.mjs → responsive-F2i_EZ7a.mjs} +1 -1
- package/dist/{scene-monitor-copy-BBWU6bfw.mjs → scene-monitor-copy-RkL6wtjU.mjs} +1 -1
- package/dist/{square-_I0mPZ7d.mjs → square-C4QMTFWA.mjs} +1 -1
- package/dist/{trash-2-D9kzsUUY.mjs → trash-2-BtfILwcu.mjs} +1 -1
- package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DHLDVQJr.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-DflrE0ec.mjs} +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-JwlaJnAm.mjs +0 -26
|
@@ -5941,7 +5941,7 @@ var ZodIssueCode = {
|
|
|
5941
5941
|
var ZodFirstPartyTypeKind;
|
|
5942
5942
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5943
5943
|
//#endregion
|
|
5944
|
-
//#region ../types/dist/sleep-
|
|
5944
|
+
//#region ../types/dist/sleep-C-v96WpE.mjs
|
|
5945
5945
|
/**
|
|
5946
5946
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5947
5947
|
* window to float samples (D455).
|
|
@@ -7556,6 +7556,10 @@ function toNodeId(idOrRunnerId) {
|
|
|
7556
7556
|
const head = idOrRunnerId.split("/")[0];
|
|
7557
7557
|
return head === void 0 || head.length === 0 ? idOrRunnerId : head;
|
|
7558
7558
|
}
|
|
7559
|
+
object({
|
|
7560
|
+
field: string().min(1),
|
|
7561
|
+
on: literal("advance")
|
|
7562
|
+
});
|
|
7559
7563
|
/**
|
|
7560
7564
|
* Output schema shared by the contribution + live methods.
|
|
7561
7565
|
*
|
|
@@ -8047,7 +8051,43 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
8047
8051
|
return DeviceRole;
|
|
8048
8052
|
}({});
|
|
8049
8053
|
//#endregion
|
|
8050
|
-
//#region ../types/dist/composition-
|
|
8054
|
+
//#region ../types/dist/composition-BK-GTFYb.mjs
|
|
8055
|
+
/**
|
|
8056
|
+
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
8057
|
+
* valutatore puro del suo FRONTE.
|
|
8058
|
+
*
|
|
8059
|
+
* Viveva dentro il builtin virtual-doorbell
|
|
8060
|
+
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
8061
|
+
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
8062
|
+
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
8063
|
+
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
8064
|
+
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
8065
|
+
* SPOSTA qui e il doorbell la ri-esporta.
|
|
8066
|
+
*
|
|
8067
|
+
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
8068
|
+
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
8069
|
+
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
8070
|
+
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
8071
|
+
*/
|
|
8072
|
+
/**
|
|
8073
|
+
* Known binary / switch source caps → the boolean slice field whose
|
|
8074
|
+
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
8075
|
+
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
8076
|
+
* state, connectivity's connected flag) are deliberately excluded — a
|
|
8077
|
+
* reconnect is not a doorbell press, and it is not a recording either.
|
|
8078
|
+
*/
|
|
8079
|
+
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
8080
|
+
contact: "entryOpen",
|
|
8081
|
+
binary: "on",
|
|
8082
|
+
switch: "on",
|
|
8083
|
+
motion: "detected",
|
|
8084
|
+
flood: "flooded",
|
|
8085
|
+
gas: "detected",
|
|
8086
|
+
smoke: "detected",
|
|
8087
|
+
"carbon-monoxide": "detected",
|
|
8088
|
+
vibration: "detected",
|
|
8089
|
+
tamper: "tampered"
|
|
8090
|
+
};
|
|
8051
8091
|
/**
|
|
8052
8092
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8053
8093
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
@@ -8245,6 +8285,20 @@ var table = {
|
|
|
8245
8285
|
const present = args.flatMap((a, i) => a === null ? [] : [asFiniteNumber(a, "latest", i)]);
|
|
8246
8286
|
return present.length === 0 ? null : finiteResult(Math.max(...present), "latest");
|
|
8247
8287
|
}
|
|
8288
|
+
},
|
|
8289
|
+
rose: {
|
|
8290
|
+
minArgs: 2,
|
|
8291
|
+
maxArgs: 3,
|
|
8292
|
+
apply: () => {
|
|
8293
|
+
throw new ExpressionEvalError("rose: stateful evaluation context is required");
|
|
8294
|
+
}
|
|
8295
|
+
},
|
|
8296
|
+
count: {
|
|
8297
|
+
minArgs: 1,
|
|
8298
|
+
maxArgs: 1,
|
|
8299
|
+
apply: () => {
|
|
8300
|
+
throw new ExpressionEvalError("count: stateful evaluation context is required");
|
|
8301
|
+
}
|
|
8248
8302
|
}
|
|
8249
8303
|
};
|
|
8250
8304
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -8759,6 +8813,7 @@ var CompositionItemEntrySchema = object({
|
|
|
8759
8813
|
var CompositionFeatureSchema = discriminatedUnion("kind", [object({
|
|
8760
8814
|
kind: literal("fields"),
|
|
8761
8815
|
cap: string().min(1),
|
|
8816
|
+
enabled: boolean().optional(),
|
|
8762
8817
|
fields: record(string().min(1), CompositionFieldSourceSchema).refine((fields) => Object.keys(fields).length <= 32, { message: `at most 32 fields per capability` }),
|
|
8763
8818
|
/**
|
|
8764
8819
|
* Items of the cap's item array, keyed by item key (D663). Naming `items`
|
|
@@ -8770,6 +8825,7 @@ var CompositionFeatureSchema = discriminatedUnion("kind", [object({
|
|
|
8770
8825
|
}), object({
|
|
8771
8826
|
kind: literal("passthrough"),
|
|
8772
8827
|
cap: string().min(1),
|
|
8828
|
+
enabled: boolean().optional(),
|
|
8773
8829
|
source: CompositionSourceRefSchema
|
|
8774
8830
|
})]);
|
|
8775
8831
|
var CompositionSchema = object({
|
|
@@ -8799,7 +8855,6 @@ var CompositionSchema = object({
|
|
|
8799
8855
|
});
|
|
8800
8856
|
new Set([
|
|
8801
8857
|
"track",
|
|
8802
|
-
"summary",
|
|
8803
8858
|
"face",
|
|
8804
8859
|
"identity",
|
|
8805
8860
|
"plate",
|
|
@@ -13421,6 +13476,15 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
|
|
|
13421
13476
|
}),
|
|
13422
13477
|
lastChangedAt: number()
|
|
13423
13478
|
});
|
|
13479
|
+
EventCategory.DoorbellOnPressed;
|
|
13480
|
+
var CompositionEventPlanSchema = object({
|
|
13481
|
+
featureIndex: number().int().nonnegative(),
|
|
13482
|
+
cap: string(),
|
|
13483
|
+
eventName: string(),
|
|
13484
|
+
category: _enum(EventCategory),
|
|
13485
|
+
stateField: string(),
|
|
13486
|
+
fieldKey: string()
|
|
13487
|
+
});
|
|
13424
13488
|
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
|
|
13425
13489
|
var CompositionProblemSchema = object({
|
|
13426
13490
|
code: _enum([
|
|
@@ -13470,12 +13534,14 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
13470
13534
|
]);
|
|
13471
13535
|
/**
|
|
13472
13536
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
13473
|
-
* field of its cap changes value · `constant` reads nothing, computed once
|
|
13537
|
+
* field of its cap changes value · `constant` reads nothing, computed once ·
|
|
13538
|
+
* `accumulator` advances from the target's seed/current output.
|
|
13474
13539
|
*/
|
|
13475
13540
|
var CompositionFieldRoleSchema = _enum([
|
|
13476
13541
|
"derived",
|
|
13477
13542
|
"clock",
|
|
13478
|
-
"constant"
|
|
13543
|
+
"constant",
|
|
13544
|
+
"accumulator"
|
|
13479
13545
|
]);
|
|
13480
13546
|
/** The item a planned field belongs to; its `path` is then the dotted path INSIDE the item. */
|
|
13481
13547
|
var CompositionFieldItemSchema = object({
|
|
@@ -13511,6 +13577,7 @@ var CompositionFeatureModeSchema = _enum([
|
|
|
13511
13577
|
"replace"
|
|
13512
13578
|
]);
|
|
13513
13579
|
var CompositionFeaturePlanSchema = object({
|
|
13580
|
+
/** Index in the stored feature array; disabled features are omitted rather than re-indexed. */
|
|
13514
13581
|
featureIndex: number().int().nonnegative(),
|
|
13515
13582
|
cap: string(),
|
|
13516
13583
|
mode: CompositionFeatureModeSchema
|
|
@@ -13519,7 +13586,8 @@ var CompositionValidationSchema = object({
|
|
|
13519
13586
|
ok: boolean(),
|
|
13520
13587
|
problems: array(CompositionProblemSchema),
|
|
13521
13588
|
fields: array(CompositionFieldPlanSchema),
|
|
13522
|
-
features: array(CompositionFeaturePlanSchema)
|
|
13589
|
+
features: array(CompositionFeaturePlanSchema),
|
|
13590
|
+
events: array(CompositionEventPlanSchema)
|
|
13523
13591
|
});
|
|
13524
13592
|
/**
|
|
13525
13593
|
* Mirrors `CoreBlockStatus`, pinned by `core-blocks-source.spec.ts`. `degraded`:
|
|
@@ -15130,6 +15198,34 @@ var DeviceBindingsForDeviceSchema = object({
|
|
|
15130
15198
|
nativeAddonId: string()
|
|
15131
15199
|
}))
|
|
15132
15200
|
});
|
|
15201
|
+
/**
|
|
15202
|
+
* The STORED wrapper activation for one `(device, capability)` pair — the row
|
|
15203
|
+
* `setWrapperActive` writes, read back three-way (D675):
|
|
15204
|
+
*
|
|
15205
|
+
* - `value` — the store answered and holds an activation: the bound wrapper's
|
|
15206
|
+
* addon id, or `null`, the operator's explicit "off" marker (D62);
|
|
15207
|
+
* - `missing` — the store answered, its activation map exists, and it holds
|
|
15208
|
+
* nothing for this pair: the operator never activated or deactivated a
|
|
15209
|
+
* wrapper here;
|
|
15210
|
+
* - `failed` — the store could not be read, holds no activation map at all
|
|
15211
|
+
* (an empty or unready snapshot, D44), or holds something that is not an
|
|
15212
|
+
* activation. It carries NO information: a consumer must never read it as
|
|
15213
|
+
* `missing` (D315, D393).
|
|
15214
|
+
*
|
|
15215
|
+
* This is the persisted INPUT, not the derived `getBindings` view — no registry
|
|
15216
|
+
* resolution, no `defaultActive` auto-binding, no cluster native-cap folding.
|
|
15217
|
+
*/
|
|
15218
|
+
var WrapperActivationReadSchema = discriminatedUnion("kind", [
|
|
15219
|
+
object({
|
|
15220
|
+
kind: literal("value"),
|
|
15221
|
+
wrapperAddonId: string().nullable()
|
|
15222
|
+
}),
|
|
15223
|
+
object({ kind: literal("missing") }),
|
|
15224
|
+
object({
|
|
15225
|
+
kind: literal("failed"),
|
|
15226
|
+
error: string()
|
|
15227
|
+
})
|
|
15228
|
+
]);
|
|
15133
15229
|
var SavedDeviceRowSchema = object({
|
|
15134
15230
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
15135
15231
|
id: number(),
|
|
@@ -15480,7 +15576,10 @@ method(object({
|
|
|
15480
15576
|
}), _void(), {
|
|
15481
15577
|
kind: "mutation",
|
|
15482
15578
|
auth: "admin"
|
|
15483
|
-
}), method(object({
|
|
15579
|
+
}), method(object({
|
|
15580
|
+
deviceId: number(),
|
|
15581
|
+
capName: string().min(1)
|
|
15582
|
+
}), WrapperActivationReadSchema), method(object({ capName: string() }), array(string())), method(object({ deviceType: string() }), array(object({
|
|
15484
15583
|
capName: string(),
|
|
15485
15584
|
wrappers: array(string())
|
|
15486
15585
|
}))), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), object({
|
|
@@ -20597,6 +20696,102 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
20597
20696
|
});
|
|
20598
20697
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
20599
20698
|
/**
|
|
20699
|
+
* What started a camera's onboard motion (D672). `camera` is the camera's own
|
|
20700
|
+
* firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
|
|
20701
|
+
* wire means the camera: only the camera-sensors bridge ever says `sensor`.
|
|
20702
|
+
*/
|
|
20703
|
+
var MotionTriggeredBySchema = discriminatedUnion("kind", [object({ kind: literal("camera") }), object({
|
|
20704
|
+
kind: literal("sensor"),
|
|
20705
|
+
deviceId: number().int().positive()
|
|
20706
|
+
})]);
|
|
20707
|
+
Object.freeze({ kind: "camera" });
|
|
20708
|
+
var CameraSensorRefSchema = object({
|
|
20709
|
+
addonId: string().min(1),
|
|
20710
|
+
stableId: string().min(1)
|
|
20711
|
+
});
|
|
20712
|
+
function cameraSensorRefKey(ref) {
|
|
20713
|
+
return `${ref.addonId}/${ref.stableId}`;
|
|
20714
|
+
}
|
|
20715
|
+
/** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
|
|
20716
|
+
var CameraSensorsModeSchema = _enum(["in-addition"]);
|
|
20717
|
+
object({
|
|
20718
|
+
mode: CameraSensorsModeSchema,
|
|
20719
|
+
sensors: array(CameraSensorRefSchema).min(1).max(8)
|
|
20720
|
+
}).superRefine((value, ctx) => {
|
|
20721
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20722
|
+
value.sensors.forEach((ref, index) => {
|
|
20723
|
+
const key = cameraSensorRefKey(ref);
|
|
20724
|
+
if (seen.has(key)) ctx.addIssue({
|
|
20725
|
+
code: "custom",
|
|
20726
|
+
path: ["sensors", index],
|
|
20727
|
+
message: `duplicate camera sensor ${key}`
|
|
20728
|
+
});
|
|
20729
|
+
seen.add(key);
|
|
20730
|
+
});
|
|
20731
|
+
});
|
|
20732
|
+
var RefFields = {
|
|
20733
|
+
addonId: string(),
|
|
20734
|
+
stableId: string()
|
|
20735
|
+
};
|
|
20736
|
+
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20737
|
+
object({
|
|
20738
|
+
...RefFields,
|
|
20739
|
+
state: literal("ready"),
|
|
20740
|
+
deviceId: number(),
|
|
20741
|
+
name: string(),
|
|
20742
|
+
caps: array(string()).readonly()
|
|
20743
|
+
}),
|
|
20744
|
+
object({
|
|
20745
|
+
...RefFields,
|
|
20746
|
+
state: literal("offline"),
|
|
20747
|
+
deviceId: number(),
|
|
20748
|
+
name: string(),
|
|
20749
|
+
reason: _enum(["offline", "disabled"])
|
|
20750
|
+
}),
|
|
20751
|
+
object({
|
|
20752
|
+
...RefFields,
|
|
20753
|
+
state: literal("missing"),
|
|
20754
|
+
reason: string()
|
|
20755
|
+
}),
|
|
20756
|
+
object({
|
|
20757
|
+
...RefFields,
|
|
20758
|
+
state: literal("unsupported"),
|
|
20759
|
+
deviceId: number(),
|
|
20760
|
+
name: string(),
|
|
20761
|
+
reason: string()
|
|
20762
|
+
}),
|
|
20763
|
+
object({
|
|
20764
|
+
...RefFields,
|
|
20765
|
+
state: literal("unreadable"),
|
|
20766
|
+
reason: string()
|
|
20767
|
+
})
|
|
20768
|
+
]);
|
|
20769
|
+
/**
|
|
20770
|
+
* Why a configured camera forwards NOTHING from its sensors, however ready they
|
|
20771
|
+
* are (D672): it does not list `onboard` in `motionSources` (attaching a sensor
|
|
20772
|
+
* does not add it), or it has no active detection config at all (the bridge
|
|
20773
|
+
* reads the active config). Absent = forwarded, or an older node that does not
|
|
20774
|
+
* say.
|
|
20775
|
+
*/
|
|
20776
|
+
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20777
|
+
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
20778
|
+
object({ state: literal("not-configured") }),
|
|
20779
|
+
object({
|
|
20780
|
+
state: literal("unreadable"),
|
|
20781
|
+
reason: string()
|
|
20782
|
+
}),
|
|
20783
|
+
object({
|
|
20784
|
+
state: literal("configured"),
|
|
20785
|
+
mode: CameraSensorsModeSchema,
|
|
20786
|
+
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
20787
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional()
|
|
20788
|
+
})
|
|
20789
|
+
]);
|
|
20790
|
+
Object.freeze({
|
|
20791
|
+
state: "unreadable",
|
|
20792
|
+
reason: "camera sensor mappings not loaded"
|
|
20793
|
+
});
|
|
20794
|
+
/**
|
|
20600
20795
|
* A model choice has a SCOPE, and a scope change has a workflow.
|
|
20601
20796
|
*
|
|
20602
20797
|
* ## The two scopes
|
|
@@ -21345,6 +21540,12 @@ var MotionEventSchema = object({
|
|
|
21345
21540
|
/** Populated by B5 (recording playback URL for this event). */
|
|
21346
21541
|
mediaUrl: string().optional(),
|
|
21347
21542
|
/**
|
|
21543
|
+
* The FIRST trigger of an `onboard` episode, written once at open (D672).
|
|
21544
|
+
* Absent = not recorded (a row written before D672, or an analyzer /
|
|
21545
|
+
* device-activity episode) — never read as "the camera" (D393).
|
|
21546
|
+
*/
|
|
21547
|
+
triggeredBy: MotionTriggeredBySchema.optional(),
|
|
21548
|
+
/**
|
|
21348
21549
|
* One row per motion EPISODE, not one per push (D475). `null` while the
|
|
21349
21550
|
* episode is still open — a further rising edge extends it in place rather
|
|
21350
21551
|
* than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
|
|
@@ -21838,131 +22039,6 @@ var RecentTracksQueryInput = object({
|
|
|
21838
22039
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21839
22040
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21840
22041
|
});
|
|
21841
|
-
/**
|
|
21842
|
-
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
21843
|
-
* `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
|
|
21844
|
-
* 'summary'`, served by the event-media plane at `/m/<id>`), null until the
|
|
21845
|
-
* first frame with a member visible has been materialised (D482 — it was the
|
|
21846
|
-
* row's composite key, which embedded the owner and could name another table's
|
|
21847
|
-
* row once event ids became per-table rowids).
|
|
21848
|
-
*/
|
|
21849
|
-
var SummarySchema = object({
|
|
21850
|
-
id: string(),
|
|
21851
|
-
deviceId: number(),
|
|
21852
|
-
openedAt: number(),
|
|
21853
|
-
lastActiveAt: number(),
|
|
21854
|
-
sealedAt: number().nullable(),
|
|
21855
|
-
memberCount: number().int().nonnegative(),
|
|
21856
|
-
groupShotMediaId: number().int().nullable()
|
|
21857
|
-
});
|
|
21858
|
-
var SummariesQueryInput = object({
|
|
21859
|
-
deviceIds: array(number()).min(1),
|
|
21860
|
-
since: number().optional(),
|
|
21861
|
-
until: number().optional(),
|
|
21862
|
-
limit: number().int().min(1).max(200).default(50),
|
|
21863
|
-
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
21864
|
-
* meaning of "dog" on every summary surface. */
|
|
21865
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21866
|
-
});
|
|
21867
|
-
var SummaryDetailSchema = object({
|
|
21868
|
-
summary: SummarySchema,
|
|
21869
|
-
/** Members in absorption order, oldest join first. */
|
|
21870
|
-
members: array(object({
|
|
21871
|
-
trackId: string(),
|
|
21872
|
-
/**
|
|
21873
|
-
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
21874
|
-
* and the track no longer exists to fill it.
|
|
21875
|
-
*
|
|
21876
|
-
* The join, not the latest opinion: class voting can re-decide a track's
|
|
21877
|
-
* class afterwards, and a group's composition is the history of who came
|
|
21878
|
-
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
21879
|
-
* dog" — rather than being handed a second, denormalised tally that would
|
|
21880
|
-
* drift from the members it claims to describe.
|
|
21881
|
-
*/
|
|
21882
|
-
className: string().nullable(),
|
|
21883
|
-
/** `primary` is the one member that carries the group's identity. */
|
|
21884
|
-
role: _enum([
|
|
21885
|
-
"primary",
|
|
21886
|
-
"sibling",
|
|
21887
|
-
"child"
|
|
21888
|
-
]).nullable(),
|
|
21889
|
-
joinedAt: number(),
|
|
21890
|
-
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
21891
|
-
* at read time. Absent when nothing resolved, never an empty string. */
|
|
21892
|
-
label: string().optional(),
|
|
21893
|
-
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
21894
|
-
* recognised nobody, and absent for a member whose track has been pruned —
|
|
21895
|
-
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
21896
|
-
subLabel: string().optional()
|
|
21897
|
-
})).readonly()
|
|
21898
|
-
});
|
|
21899
|
-
/**
|
|
21900
|
-
* What a LIST of groups carries: the envelope plus what it is MADE OF.
|
|
21901
|
-
*
|
|
21902
|
-
* Coarse on purpose — the operator's rule is "only the rough data on the list,
|
|
21903
|
-
* we extend when we notice we need more". Enough to draw the card ("two people
|
|
21904
|
-
* and a dog") and no more. The MEMBERS, their names and the per-member links
|
|
21905
|
-
* are on {@link getSummary}: shipping every member of every group so a client
|
|
21906
|
-
* can count them turns a page of two hundred groups into a thousand records to
|
|
21907
|
-
* draw two hundred badges.
|
|
21908
|
-
*/
|
|
21909
|
-
var SummaryListItemSchema = object({
|
|
21910
|
-
summary: SummarySchema,
|
|
21911
|
-
/** Class counts, most numerous first; `className: null` is a member whose
|
|
21912
|
-
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
21913
|
-
classes: array(object({
|
|
21914
|
-
className: string().nullable(),
|
|
21915
|
-
count: number().int().positive()
|
|
21916
|
-
})).readonly()
|
|
21917
|
-
});
|
|
21918
|
-
var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
|
|
21919
|
-
/**
|
|
21920
|
-
* The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
|
|
21921
|
-
*
|
|
21922
|
-
* The reel on the cameras page and the Events gallery both ride a cursor, so a
|
|
21923
|
-
* summaries feed that could only answer "the last N for these cameras"
|
|
21924
|
-
* (`listSummaries`) would make groups available in the timeline and nowhere
|
|
21925
|
-
* else. Two feeds with different ordering contracts would be two ideas of what
|
|
21926
|
-
* "newest" means, on one screen.
|
|
21927
|
-
*/
|
|
21928
|
-
var RecentSummariesQueryInput = object({
|
|
21929
|
-
/** Devices to merge. An empty array yields an empty page. */
|
|
21930
|
-
deviceIds: array(number()),
|
|
21931
|
-
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
21932
|
-
since: number().optional(),
|
|
21933
|
-
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
21934
|
-
until: number().optional(),
|
|
21935
|
-
limit: number().int().min(1).max(500).default(100),
|
|
21936
|
-
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
21937
|
-
cursor: string().optional(),
|
|
21938
|
-
/**
|
|
21939
|
-
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
21940
|
-
* deliberately the same name: the events filter tree emits one list of ticked
|
|
21941
|
-
* taxonomy nodes, and a summaries feed that called it something else would
|
|
21942
|
-
* make the operator's one filter component produce two shapes.
|
|
21943
|
-
*
|
|
21944
|
-
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
21945
|
-
* me the arrivals with a dog" has to return the group of four people who had
|
|
21946
|
-
* one with them; a filter on the group's own fields could only ever answer
|
|
21947
|
-
* about its primary.
|
|
21948
|
-
*
|
|
21949
|
-
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
21950
|
-
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
21951
|
-
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
21952
|
-
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
21953
|
-
* that read only the class would answer "animal" and never "dog".
|
|
21954
|
-
*
|
|
21955
|
-
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
21956
|
-
*/
|
|
21957
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21958
|
-
});
|
|
21959
|
-
var RecentSummariesPageSchema = object({
|
|
21960
|
-
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
21961
|
-
* {@link listSummaries} — one list shape, so a card renders the same
|
|
21962
|
-
* whichever feed drew it. */
|
|
21963
|
-
summaries: array(SummaryListItemSchema).readonly(),
|
|
21964
|
-
nextCursor: string().nullable()
|
|
21965
|
-
});
|
|
21966
22042
|
var RecentTracksPageSchema = object({
|
|
21967
22043
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
21968
22044
|
tracks: array(TrackSchema).readonly(),
|
|
@@ -22474,7 +22550,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
22474
22550
|
classes: array(string()).optional(),
|
|
22475
22551
|
/** See {@link ExcludeSourcesDoc}. */
|
|
22476
22552
|
excludeSources: array(TrackSourceSchema).optional()
|
|
22477
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
22553
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
22478
22554
|
kind: "mutation",
|
|
22479
22555
|
auth: "admin"
|
|
22480
22556
|
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({ deviceIds: array(number()).min(1).max(200) }), array(EventKindsForDeviceSchema).readonly()), method(object({
|
|
@@ -23654,6 +23730,23 @@ var MotionSourceEnum = _enum([
|
|
|
23654
23730
|
*/
|
|
23655
23731
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
23656
23732
|
/**
|
|
23733
|
+
* The operator-facing name of each MOTION source (D672: `onboard` = the
|
|
23734
|
+
* camera's sensors — its own motion plus any sensor attached to it). The wire
|
|
23735
|
+
* value stays `onboard`; only the label changed. `detectionSources: 'onboard'`
|
|
23736
|
+
* ("Camera onboard AI") and the notification source filter keep their labels.
|
|
23737
|
+
*/
|
|
23738
|
+
var MOTION_SOURCE_LABELS = {
|
|
23739
|
+
analyzer: "Frame-diff Analyzer (motion addon)",
|
|
23740
|
+
onboard: "Camera sensors",
|
|
23741
|
+
"device-activity": "Device activity (the device says it is working)"
|
|
23742
|
+
};
|
|
23743
|
+
/** The order the motion-source picker offers them in (not the enum's order). */
|
|
23744
|
+
var MOTION_SOURCE_PICKER_ORDER = [
|
|
23745
|
+
"analyzer",
|
|
23746
|
+
"onboard",
|
|
23747
|
+
"device-activity"
|
|
23748
|
+
];
|
|
23749
|
+
/**
|
|
23657
23750
|
* Which root detector a camera runs — EXACTLY ONE.
|
|
23658
23751
|
*
|
|
23659
23752
|
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
@@ -24000,7 +24093,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
24000
24093
|
*/
|
|
24001
24094
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
24002
24095
|
});
|
|
24003
|
-
|
|
24096
|
+
MOTION_SOURCE_PICKER_ORDER.map((value) => value === "onboard" ? {
|
|
24097
|
+
value,
|
|
24098
|
+
label: MOTION_SOURCE_LABELS[value],
|
|
24099
|
+
description: "The camera's own motion, plus any sensor attached to it"
|
|
24100
|
+
} : {
|
|
24101
|
+
value,
|
|
24102
|
+
label: MOTION_SOURCE_LABELS[value]
|
|
24103
|
+
}), motionFpsField.min, motionFpsField.max, motionFpsField.step, motionFpsField.default, detectionFpsField.min, detectionFpsField.max, detectionFpsField.step, detectionFpsField.default, motionCooldownMsField.min, motionCooldownMsField.max, motionCooldownMsField.step, motionCooldownMsField.default, maxSessionHoldMsField.min, maxSessionHoldMsField.max, maxSessionHoldMsField.step, maxSessionHoldMsField.default, audioMotionWindowMsField.min, audioMotionWindowMsField.max, audioMotionWindowMsField.step, audioMotionWindowMsField.default, preRollInferenceFramesField.min, preRollInferenceFramesField.max, preRollInferenceFramesField.step, preRollInferenceFramesField.default, occupancyRecheckSecField.min, occupancyRecheckSecField.max, occupancyRecheckSecField.step, occupancyRecheckSecField.default, occupancyRecheckFramesField.min, occupancyRecheckFramesField.max, occupancyRecheckFramesField.step, occupancyRecheckFramesField.default;
|
|
24004
24104
|
/**
|
|
24005
24105
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
24006
24106
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -24574,6 +24674,11 @@ var CameraStatusSchema = object({
|
|
|
24574
24674
|
*/
|
|
24575
24675
|
switchedOff: array(CameraSwitchIdSchema).readonly(),
|
|
24576
24676
|
/**
|
|
24677
|
+
* The camera's attached sensors (D672). Optional only for a status composed
|
|
24678
|
+
* by an orchestrator older than D672; this orchestrator always sets it.
|
|
24679
|
+
*/
|
|
24680
|
+
cameraSensors: CameraSensorsStatusSchema.optional(),
|
|
24681
|
+
/**
|
|
24577
24682
|
* Stages of the bounded fan-out that were CUT SHORT — a timeout or a
|
|
24578
24683
|
* rejection — and whose block is therefore `null` because we could not
|
|
24579
24684
|
* READ it, not because there is nothing there.
|
|
@@ -26996,42 +27101,6 @@ DeviceType.Camera, method(object({
|
|
|
26996
27101
|
kind: "query",
|
|
26997
27102
|
auth: "protected"
|
|
26998
27103
|
});
|
|
26999
|
-
/**
|
|
27000
|
-
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
27001
|
-
* valutatore puro del suo FRONTE.
|
|
27002
|
-
*
|
|
27003
|
-
* Viveva dentro il builtin virtual-doorbell
|
|
27004
|
-
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
27005
|
-
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
27006
|
-
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
27007
|
-
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
27008
|
-
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
27009
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
27010
|
-
*
|
|
27011
|
-
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
27012
|
-
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
27013
|
-
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
27014
|
-
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
27015
|
-
*/
|
|
27016
|
-
/**
|
|
27017
|
-
* Known binary / switch source caps → the boolean slice field whose
|
|
27018
|
-
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
27019
|
-
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
27020
|
-
* state, connectivity's connected flag) are deliberately excluded — a
|
|
27021
|
-
* reconnect is not a doorbell press, and it is not a recording either.
|
|
27022
|
-
*/
|
|
27023
|
-
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
27024
|
-
contact: "entryOpen",
|
|
27025
|
-
binary: "on",
|
|
27026
|
-
switch: "on",
|
|
27027
|
-
motion: "detected",
|
|
27028
|
-
flood: "flooded",
|
|
27029
|
-
gas: "detected",
|
|
27030
|
-
smoke: "detected",
|
|
27031
|
-
"carbon-monoxide": "detected",
|
|
27032
|
-
vibration: "detected",
|
|
27033
|
-
tamper: "tampered"
|
|
27034
|
-
};
|
|
27035
27104
|
object({
|
|
27036
27105
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
27037
27106
|
lastPressedAt: number().nullable(),
|
|
@@ -30681,7 +30750,9 @@ object({
|
|
|
30681
30750
|
detected: boolean(),
|
|
30682
30751
|
timestamp: number(),
|
|
30683
30752
|
source: MotionSourceEnum,
|
|
30684
|
-
regions: array(MotionRegionSchema).readonly().optional()
|
|
30753
|
+
regions: array(MotionRegionSchema).readonly().optional(),
|
|
30754
|
+
/** Who started it (D672). Absent = the camera itself. Only `onboard` carries `sensor`. */
|
|
30755
|
+
triggeredBy: MotionTriggeredBySchema.optional()
|
|
30685
30756
|
});
|
|
30686
30757
|
DeviceType.Camera, DeviceType.Sensor, method(object({ deviceId: number() }), boolean());
|
|
30687
30758
|
object({
|
|
@@ -33003,12 +33074,21 @@ var RecordingStorageUsageSchema = object({
|
|
|
33003
33074
|
*/
|
|
33004
33075
|
devicesRead: _enum(["archive", "unavailable"]).optional(),
|
|
33005
33076
|
/**
|
|
33077
|
+
* Is the `archive` answer WHOLE (D674): the hour ledger loaded without
|
|
33078
|
+
* hitting its row cap, and at least one location resolved? Only then may a
|
|
33079
|
+
* camera ABSENT from `devices[]` be read as "no footage" — and only then is a
|
|
33080
|
+
* row's `oldestMs` the archive's oldest rather than the oldest of a fraction.
|
|
33081
|
+
* OPTIONAL: a recorder predating D674 omits it, and a consumer must read the
|
|
33082
|
+
* absence as `false`. A retention floor is a delete; it never guesses.
|
|
33083
|
+
*/
|
|
33084
|
+
complete: boolean().optional(),
|
|
33085
|
+
/**
|
|
33006
33086
|
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
33007
|
-
* of the payload without it:
|
|
33008
|
-
*
|
|
33009
|
-
*
|
|
33010
|
-
*
|
|
33011
|
-
*
|
|
33087
|
+
* of the payload without it: a recorder that could not build it omits it. A
|
|
33088
|
+
* UI that dereferences it unconditionally crashes the whole Storage page over
|
|
33089
|
+
* a missing disk bar. (The hub's cap routers pass output through unvalidated
|
|
33090
|
+
* since 2026-07-11 — `cap-router-builder.ts` — so a newer recorder's fields
|
|
33091
|
+
* are not stripped by an older hub.)
|
|
33012
33092
|
*/
|
|
33013
33093
|
locations: array(RecordingLocationUsageSchema).optional()
|
|
33014
33094
|
});
|
|
@@ -35779,7 +35859,12 @@ Object.freeze({
|
|
|
35779
35859
|
number: {
|
|
35780
35860
|
kind: "fixed",
|
|
35781
35861
|
result: ["number", "null"]
|
|
35782
|
-
}
|
|
35862
|
+
},
|
|
35863
|
+
rose: {
|
|
35864
|
+
kind: "fixed",
|
|
35865
|
+
result: ["number", "null"]
|
|
35866
|
+
},
|
|
35867
|
+
count: NUMBER
|
|
35783
35868
|
});
|
|
35784
35869
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
35785
35870
|
/**
|
|
@@ -38894,6 +38979,12 @@ Object.freeze({
|
|
|
38894
38979
|
addonId: null,
|
|
38895
38980
|
access: "view"
|
|
38896
38981
|
},
|
|
38982
|
+
"deviceManager.getWrapperActivation": {
|
|
38983
|
+
capName: "device-manager",
|
|
38984
|
+
capScope: "system",
|
|
38985
|
+
addonId: null,
|
|
38986
|
+
access: "view"
|
|
38987
|
+
},
|
|
38897
38988
|
"deviceManager.listAll": {
|
|
38898
38989
|
capName: "device-manager",
|
|
38899
38990
|
capScope: "system",
|
|
@@ -41168,12 +41259,6 @@ Object.freeze({
|
|
|
41168
41259
|
addonId: null,
|
|
41169
41260
|
access: "view"
|
|
41170
41261
|
},
|
|
41171
|
-
"pipelineAnalytics.getSummary": {
|
|
41172
|
-
capName: "pipeline-analytics",
|
|
41173
|
-
capScope: "device",
|
|
41174
|
-
addonId: null,
|
|
41175
|
-
access: "view"
|
|
41176
|
-
},
|
|
41177
41262
|
"pipelineAnalytics.getTrack": {
|
|
41178
41263
|
capName: "pipeline-analytics",
|
|
41179
41264
|
capScope: "device",
|
|
@@ -41234,12 +41319,6 @@ Object.freeze({
|
|
|
41234
41319
|
addonId: null,
|
|
41235
41320
|
access: "view"
|
|
41236
41321
|
},
|
|
41237
|
-
"pipelineAnalytics.listRecentSummaries": {
|
|
41238
|
-
capName: "pipeline-analytics",
|
|
41239
|
-
capScope: "device",
|
|
41240
|
-
addonId: null,
|
|
41241
|
-
access: "view"
|
|
41242
|
-
},
|
|
41243
41322
|
"pipelineAnalytics.listRecentTracks": {
|
|
41244
41323
|
capName: "pipeline-analytics",
|
|
41245
41324
|
capScope: "device",
|
|
@@ -41270,12 +41349,6 @@ Object.freeze({
|
|
|
41270
41349
|
addonId: null,
|
|
41271
41350
|
access: "view"
|
|
41272
41351
|
},
|
|
41273
|
-
"pipelineAnalytics.listSummaries": {
|
|
41274
|
-
capName: "pipeline-analytics",
|
|
41275
|
-
capScope: "device",
|
|
41276
|
-
addonId: null,
|
|
41277
|
-
access: "view"
|
|
41278
|
-
},
|
|
41279
41352
|
"pipelineAnalytics.listTrackMedia": {
|
|
41280
41353
|
capName: "pipeline-analytics",
|
|
41281
41354
|
capScope: "device",
|
|
@@ -44703,6 +44776,11 @@ Object.freeze({
|
|
|
44703
44776
|
form: "single",
|
|
44704
44777
|
optional: false
|
|
44705
44778
|
}],
|
|
44779
|
+
"deviceManager.getWrapperActivation": [{
|
|
44780
|
+
name: "deviceId",
|
|
44781
|
+
form: "single",
|
|
44782
|
+
optional: false
|
|
44783
|
+
}],
|
|
44706
44784
|
"deviceManager.listAll": [{
|
|
44707
44785
|
name: "deviceIds",
|
|
44708
44786
|
form: "array",
|
|
@@ -45440,11 +45518,6 @@ Object.freeze({
|
|
|
45440
45518
|
form: "single",
|
|
45441
45519
|
optional: true
|
|
45442
45520
|
}],
|
|
45443
|
-
"pipelineAnalytics.listRecentSummaries": [{
|
|
45444
|
-
name: "deviceIds",
|
|
45445
|
-
form: "array",
|
|
45446
|
-
optional: false
|
|
45447
|
-
}],
|
|
45448
45521
|
"pipelineAnalytics.listRecentTracks": [{
|
|
45449
45522
|
name: "deviceIds",
|
|
45450
45523
|
form: "array",
|
|
@@ -45455,11 +45528,6 @@ Object.freeze({
|
|
|
45455
45528
|
form: "array",
|
|
45456
45529
|
optional: true
|
|
45457
45530
|
}],
|
|
45458
|
-
"pipelineAnalytics.listSummaries": [{
|
|
45459
|
-
name: "deviceIds",
|
|
45460
|
-
form: "array",
|
|
45461
|
-
optional: false
|
|
45462
|
-
}],
|
|
45463
45531
|
"pipelineAnalytics.listTrackMedia": [{
|
|
45464
45532
|
name: "deviceId",
|
|
45465
45533
|
form: "single",
|