@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
|
@@ -5920,7 +5920,7 @@ var ZodIssueCode = {
|
|
|
5920
5920
|
var ZodFirstPartyTypeKind;
|
|
5921
5921
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5922
5922
|
//#endregion
|
|
5923
|
-
//#region ../types/dist/sleep-
|
|
5923
|
+
//#region ../types/dist/sleep-C-v96WpE.mjs
|
|
5924
5924
|
/**
|
|
5925
5925
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5926
5926
|
* window to float samples (D455).
|
|
@@ -7535,6 +7535,10 @@ function toNodeId(idOrRunnerId) {
|
|
|
7535
7535
|
const head = idOrRunnerId.split("/")[0];
|
|
7536
7536
|
return head === void 0 || head.length === 0 ? idOrRunnerId : head;
|
|
7537
7537
|
}
|
|
7538
|
+
object({
|
|
7539
|
+
field: string().min(1),
|
|
7540
|
+
on: literal("advance")
|
|
7541
|
+
});
|
|
7538
7542
|
/**
|
|
7539
7543
|
* Output schema shared by the contribution + live methods.
|
|
7540
7544
|
*
|
|
@@ -8026,7 +8030,43 @@ var DeviceRole = /* @__PURE__ */ function(DeviceRole) {
|
|
|
8026
8030
|
return DeviceRole;
|
|
8027
8031
|
}({});
|
|
8028
8032
|
//#endregion
|
|
8029
|
-
//#region ../types/dist/composition-
|
|
8033
|
+
//#region ../types/dist/composition-BK-GTFYb.mjs
|
|
8034
|
+
/**
|
|
8035
|
+
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
8036
|
+
* valutatore puro del suo FRONTE.
|
|
8037
|
+
*
|
|
8038
|
+
* Viveva dentro il builtin virtual-doorbell
|
|
8039
|
+
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
8040
|
+
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
8041
|
+
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
8042
|
+
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
8043
|
+
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
8044
|
+
* SPOSTA qui e il doorbell la ri-esporta.
|
|
8045
|
+
*
|
|
8046
|
+
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
8047
|
+
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
8048
|
+
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
8049
|
+
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
8050
|
+
*/
|
|
8051
|
+
/**
|
|
8052
|
+
* Known binary / switch source caps → the boolean slice field whose
|
|
8053
|
+
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
8054
|
+
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
8055
|
+
* state, connectivity's connected flag) are deliberately excluded — a
|
|
8056
|
+
* reconnect is not a doorbell press, and it is not a recording either.
|
|
8057
|
+
*/
|
|
8058
|
+
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
8059
|
+
contact: "entryOpen",
|
|
8060
|
+
binary: "on",
|
|
8061
|
+
switch: "on",
|
|
8062
|
+
motion: "detected",
|
|
8063
|
+
flood: "flooded",
|
|
8064
|
+
gas: "detected",
|
|
8065
|
+
smoke: "detected",
|
|
8066
|
+
"carbon-monoxide": "detected",
|
|
8067
|
+
vibration: "detected",
|
|
8068
|
+
tamper: "tampered"
|
|
8069
|
+
};
|
|
8030
8070
|
/**
|
|
8031
8071
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8032
8072
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
@@ -8224,6 +8264,20 @@ var table = {
|
|
|
8224
8264
|
const present = args.flatMap((a, i) => a === null ? [] : [asFiniteNumber(a, "latest", i)]);
|
|
8225
8265
|
return present.length === 0 ? null : finiteResult(Math.max(...present), "latest");
|
|
8226
8266
|
}
|
|
8267
|
+
},
|
|
8268
|
+
rose: {
|
|
8269
|
+
minArgs: 2,
|
|
8270
|
+
maxArgs: 3,
|
|
8271
|
+
apply: () => {
|
|
8272
|
+
throw new ExpressionEvalError("rose: stateful evaluation context is required");
|
|
8273
|
+
}
|
|
8274
|
+
},
|
|
8275
|
+
count: {
|
|
8276
|
+
minArgs: 1,
|
|
8277
|
+
maxArgs: 1,
|
|
8278
|
+
apply: () => {
|
|
8279
|
+
throw new ExpressionEvalError("count: stateful evaluation context is required");
|
|
8280
|
+
}
|
|
8227
8281
|
}
|
|
8228
8282
|
};
|
|
8229
8283
|
Object.freeze(Object.assign(Object.create(null), table));
|
|
@@ -8738,6 +8792,7 @@ var CompositionItemEntrySchema = object({
|
|
|
8738
8792
|
var CompositionFeatureSchema = discriminatedUnion("kind", [object({
|
|
8739
8793
|
kind: literal("fields"),
|
|
8740
8794
|
cap: string().min(1),
|
|
8795
|
+
enabled: boolean().optional(),
|
|
8741
8796
|
fields: record(string().min(1), CompositionFieldSourceSchema).refine((fields) => Object.keys(fields).length <= 32, { message: `at most 32 fields per capability` }),
|
|
8742
8797
|
/**
|
|
8743
8798
|
* Items of the cap's item array, keyed by item key (D663). Naming `items`
|
|
@@ -8749,6 +8804,7 @@ var CompositionFeatureSchema = discriminatedUnion("kind", [object({
|
|
|
8749
8804
|
}), object({
|
|
8750
8805
|
kind: literal("passthrough"),
|
|
8751
8806
|
cap: string().min(1),
|
|
8807
|
+
enabled: boolean().optional(),
|
|
8752
8808
|
source: CompositionSourceRefSchema
|
|
8753
8809
|
})]);
|
|
8754
8810
|
var CompositionSchema = object({
|
|
@@ -8778,7 +8834,6 @@ var CompositionSchema = object({
|
|
|
8778
8834
|
});
|
|
8779
8835
|
new Set([
|
|
8780
8836
|
"track",
|
|
8781
|
-
"summary",
|
|
8782
8837
|
"face",
|
|
8783
8838
|
"identity",
|
|
8784
8839
|
"plate",
|
|
@@ -13400,6 +13455,15 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
|
|
|
13400
13455
|
}),
|
|
13401
13456
|
lastChangedAt: number()
|
|
13402
13457
|
});
|
|
13458
|
+
EventCategory.DoorbellOnPressed;
|
|
13459
|
+
var CompositionEventPlanSchema = object({
|
|
13460
|
+
featureIndex: number().int().nonnegative(),
|
|
13461
|
+
cap: string(),
|
|
13462
|
+
eventName: string(),
|
|
13463
|
+
category: _enum(EventCategory),
|
|
13464
|
+
stateField: string(),
|
|
13465
|
+
fieldKey: string()
|
|
13466
|
+
});
|
|
13403
13467
|
/** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
|
|
13404
13468
|
var CompositionProblemSchema = object({
|
|
13405
13469
|
code: _enum([
|
|
@@ -13449,12 +13513,14 @@ var CompositionUnavailableModeSchema = _enum([
|
|
|
13449
13513
|
]);
|
|
13450
13514
|
/**
|
|
13451
13515
|
* `derived` reads a source · `clock` reads only `now`, recomputed when a sibling
|
|
13452
|
-
* field of its cap changes value · `constant` reads nothing, computed once
|
|
13516
|
+
* field of its cap changes value · `constant` reads nothing, computed once ·
|
|
13517
|
+
* `accumulator` advances from the target's seed/current output.
|
|
13453
13518
|
*/
|
|
13454
13519
|
var CompositionFieldRoleSchema = _enum([
|
|
13455
13520
|
"derived",
|
|
13456
13521
|
"clock",
|
|
13457
|
-
"constant"
|
|
13522
|
+
"constant",
|
|
13523
|
+
"accumulator"
|
|
13458
13524
|
]);
|
|
13459
13525
|
/** The item a planned field belongs to; its `path` is then the dotted path INSIDE the item. */
|
|
13460
13526
|
var CompositionFieldItemSchema = object({
|
|
@@ -13490,6 +13556,7 @@ var CompositionFeatureModeSchema = _enum([
|
|
|
13490
13556
|
"replace"
|
|
13491
13557
|
]);
|
|
13492
13558
|
var CompositionFeaturePlanSchema = object({
|
|
13559
|
+
/** Index in the stored feature array; disabled features are omitted rather than re-indexed. */
|
|
13493
13560
|
featureIndex: number().int().nonnegative(),
|
|
13494
13561
|
cap: string(),
|
|
13495
13562
|
mode: CompositionFeatureModeSchema
|
|
@@ -13498,7 +13565,8 @@ var CompositionValidationSchema = object({
|
|
|
13498
13565
|
ok: boolean(),
|
|
13499
13566
|
problems: array(CompositionProblemSchema),
|
|
13500
13567
|
fields: array(CompositionFieldPlanSchema),
|
|
13501
|
-
features: array(CompositionFeaturePlanSchema)
|
|
13568
|
+
features: array(CompositionFeaturePlanSchema),
|
|
13569
|
+
events: array(CompositionEventPlanSchema)
|
|
13502
13570
|
});
|
|
13503
13571
|
/**
|
|
13504
13572
|
* Mirrors `CoreBlockStatus`, pinned by `core-blocks-source.spec.ts`. `degraded`:
|
|
@@ -15109,6 +15177,34 @@ var DeviceBindingsForDeviceSchema = object({
|
|
|
15109
15177
|
nativeAddonId: string()
|
|
15110
15178
|
}))
|
|
15111
15179
|
});
|
|
15180
|
+
/**
|
|
15181
|
+
* The STORED wrapper activation for one `(device, capability)` pair — the row
|
|
15182
|
+
* `setWrapperActive` writes, read back three-way (D675):
|
|
15183
|
+
*
|
|
15184
|
+
* - `value` — the store answered and holds an activation: the bound wrapper's
|
|
15185
|
+
* addon id, or `null`, the operator's explicit "off" marker (D62);
|
|
15186
|
+
* - `missing` — the store answered, its activation map exists, and it holds
|
|
15187
|
+
* nothing for this pair: the operator never activated or deactivated a
|
|
15188
|
+
* wrapper here;
|
|
15189
|
+
* - `failed` — the store could not be read, holds no activation map at all
|
|
15190
|
+
* (an empty or unready snapshot, D44), or holds something that is not an
|
|
15191
|
+
* activation. It carries NO information: a consumer must never read it as
|
|
15192
|
+
* `missing` (D315, D393).
|
|
15193
|
+
*
|
|
15194
|
+
* This is the persisted INPUT, not the derived `getBindings` view — no registry
|
|
15195
|
+
* resolution, no `defaultActive` auto-binding, no cluster native-cap folding.
|
|
15196
|
+
*/
|
|
15197
|
+
var WrapperActivationReadSchema = discriminatedUnion("kind", [
|
|
15198
|
+
object({
|
|
15199
|
+
kind: literal("value"),
|
|
15200
|
+
wrapperAddonId: string().nullable()
|
|
15201
|
+
}),
|
|
15202
|
+
object({ kind: literal("missing") }),
|
|
15203
|
+
object({
|
|
15204
|
+
kind: literal("failed"),
|
|
15205
|
+
error: string()
|
|
15206
|
+
})
|
|
15207
|
+
]);
|
|
15112
15208
|
var SavedDeviceRowSchema = object({
|
|
15113
15209
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
15114
15210
|
id: number(),
|
|
@@ -15459,7 +15555,10 @@ method(object({
|
|
|
15459
15555
|
}), _void(), {
|
|
15460
15556
|
kind: "mutation",
|
|
15461
15557
|
auth: "admin"
|
|
15462
|
-
}), method(object({
|
|
15558
|
+
}), method(object({
|
|
15559
|
+
deviceId: number(),
|
|
15560
|
+
capName: string().min(1)
|
|
15561
|
+
}), WrapperActivationReadSchema), method(object({ capName: string() }), array(string())), method(object({ deviceType: string() }), array(object({
|
|
15463
15562
|
capName: string(),
|
|
15464
15563
|
wrappers: array(string())
|
|
15465
15564
|
}))), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), SettingsSchemaWithValuesSchema.nullable()), method(object({ deviceId: number() }), object({
|
|
@@ -20576,6 +20675,102 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
20576
20675
|
});
|
|
20577
20676
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
20578
20677
|
/**
|
|
20678
|
+
* What started a camera's onboard motion (D672). `camera` is the camera's own
|
|
20679
|
+
* firmware; `sensor` is a device the operator ATTACHED to it. Absent on the
|
|
20680
|
+
* wire means the camera: only the camera-sensors bridge ever says `sensor`.
|
|
20681
|
+
*/
|
|
20682
|
+
var MotionTriggeredBySchema = discriminatedUnion("kind", [object({ kind: literal("camera") }), object({
|
|
20683
|
+
kind: literal("sensor"),
|
|
20684
|
+
deviceId: number().int().positive()
|
|
20685
|
+
})]);
|
|
20686
|
+
Object.freeze({ kind: "camera" });
|
|
20687
|
+
var CameraSensorRefSchema = object({
|
|
20688
|
+
addonId: string().min(1),
|
|
20689
|
+
stableId: string().min(1)
|
|
20690
|
+
});
|
|
20691
|
+
function cameraSensorRefKey(ref) {
|
|
20692
|
+
return `${ref.addonId}/${ref.stableId}`;
|
|
20693
|
+
}
|
|
20694
|
+
/** CS-1 accepts exactly one mode; CS-2 (D673) widens it to confirm / replace. */
|
|
20695
|
+
var CameraSensorsModeSchema = _enum(["in-addition"]);
|
|
20696
|
+
object({
|
|
20697
|
+
mode: CameraSensorsModeSchema,
|
|
20698
|
+
sensors: array(CameraSensorRefSchema).min(1).max(8)
|
|
20699
|
+
}).superRefine((value, ctx) => {
|
|
20700
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20701
|
+
value.sensors.forEach((ref, index) => {
|
|
20702
|
+
const key = cameraSensorRefKey(ref);
|
|
20703
|
+
if (seen.has(key)) ctx.addIssue({
|
|
20704
|
+
code: "custom",
|
|
20705
|
+
path: ["sensors", index],
|
|
20706
|
+
message: `duplicate camera sensor ${key}`
|
|
20707
|
+
});
|
|
20708
|
+
seen.add(key);
|
|
20709
|
+
});
|
|
20710
|
+
});
|
|
20711
|
+
var RefFields = {
|
|
20712
|
+
addonId: string(),
|
|
20713
|
+
stableId: string()
|
|
20714
|
+
};
|
|
20715
|
+
var CameraSensorAttachmentSchema = discriminatedUnion("state", [
|
|
20716
|
+
object({
|
|
20717
|
+
...RefFields,
|
|
20718
|
+
state: literal("ready"),
|
|
20719
|
+
deviceId: number(),
|
|
20720
|
+
name: string(),
|
|
20721
|
+
caps: array(string()).readonly()
|
|
20722
|
+
}),
|
|
20723
|
+
object({
|
|
20724
|
+
...RefFields,
|
|
20725
|
+
state: literal("offline"),
|
|
20726
|
+
deviceId: number(),
|
|
20727
|
+
name: string(),
|
|
20728
|
+
reason: _enum(["offline", "disabled"])
|
|
20729
|
+
}),
|
|
20730
|
+
object({
|
|
20731
|
+
...RefFields,
|
|
20732
|
+
state: literal("missing"),
|
|
20733
|
+
reason: string()
|
|
20734
|
+
}),
|
|
20735
|
+
object({
|
|
20736
|
+
...RefFields,
|
|
20737
|
+
state: literal("unsupported"),
|
|
20738
|
+
deviceId: number(),
|
|
20739
|
+
name: string(),
|
|
20740
|
+
reason: string()
|
|
20741
|
+
}),
|
|
20742
|
+
object({
|
|
20743
|
+
...RefFields,
|
|
20744
|
+
state: literal("unreadable"),
|
|
20745
|
+
reason: string()
|
|
20746
|
+
})
|
|
20747
|
+
]);
|
|
20748
|
+
/**
|
|
20749
|
+
* Why a configured camera forwards NOTHING from its sensors, however ready they
|
|
20750
|
+
* are (D672): it does not list `onboard` in `motionSources` (attaching a sensor
|
|
20751
|
+
* does not add it), or it has no active detection config at all (the bridge
|
|
20752
|
+
* reads the active config). Absent = forwarded, or an older node that does not
|
|
20753
|
+
* say.
|
|
20754
|
+
*/
|
|
20755
|
+
var CameraSensorsNotForwardedSchema = _enum(["onboard-not-listed", "no-active-detection"]);
|
|
20756
|
+
var CameraSensorsStatusSchema = discriminatedUnion("state", [
|
|
20757
|
+
object({ state: literal("not-configured") }),
|
|
20758
|
+
object({
|
|
20759
|
+
state: literal("unreadable"),
|
|
20760
|
+
reason: string()
|
|
20761
|
+
}),
|
|
20762
|
+
object({
|
|
20763
|
+
state: literal("configured"),
|
|
20764
|
+
mode: CameraSensorsModeSchema,
|
|
20765
|
+
sensors: array(CameraSensorAttachmentSchema).readonly(),
|
|
20766
|
+
notForwarded: CameraSensorsNotForwardedSchema.optional()
|
|
20767
|
+
})
|
|
20768
|
+
]);
|
|
20769
|
+
Object.freeze({
|
|
20770
|
+
state: "unreadable",
|
|
20771
|
+
reason: "camera sensor mappings not loaded"
|
|
20772
|
+
});
|
|
20773
|
+
/**
|
|
20579
20774
|
* A model choice has a SCOPE, and a scope change has a workflow.
|
|
20580
20775
|
*
|
|
20581
20776
|
* ## The two scopes
|
|
@@ -21324,6 +21519,12 @@ var MotionEventSchema = object({
|
|
|
21324
21519
|
/** Populated by B5 (recording playback URL for this event). */
|
|
21325
21520
|
mediaUrl: string().optional(),
|
|
21326
21521
|
/**
|
|
21522
|
+
* The FIRST trigger of an `onboard` episode, written once at open (D672).
|
|
21523
|
+
* Absent = not recorded (a row written before D672, or an analyzer /
|
|
21524
|
+
* device-activity episode) — never read as "the camera" (D393).
|
|
21525
|
+
*/
|
|
21526
|
+
triggeredBy: MotionTriggeredBySchema.optional(),
|
|
21527
|
+
/**
|
|
21327
21528
|
* One row per motion EPISODE, not one per push (D475). `null` while the
|
|
21328
21529
|
* episode is still open — a further rising edge extends it in place rather
|
|
21329
21530
|
* than inserting a new row. Set once, at close, to `lastOnAt - startedAt`
|
|
@@ -21817,131 +22018,6 @@ var RecentTracksQueryInput = object({
|
|
|
21817
22018
|
/** See {@link ExcludeSourcesDoc}. */
|
|
21818
22019
|
excludeSources: array(TrackSourceSchema).optional()
|
|
21819
22020
|
});
|
|
21820
|
-
/**
|
|
21821
|
-
* A Summary (D359): the per-camera session envelope that references tracks.
|
|
21822
|
-
* `groupShotMediaId` is the media ROW id of its group shot (`ownerKind:
|
|
21823
|
-
* 'summary'`, served by the event-media plane at `/m/<id>`), null until the
|
|
21824
|
-
* first frame with a member visible has been materialised (D482 — it was the
|
|
21825
|
-
* row's composite key, which embedded the owner and could name another table's
|
|
21826
|
-
* row once event ids became per-table rowids).
|
|
21827
|
-
*/
|
|
21828
|
-
var SummarySchema = object({
|
|
21829
|
-
id: string(),
|
|
21830
|
-
deviceId: number(),
|
|
21831
|
-
openedAt: number(),
|
|
21832
|
-
lastActiveAt: number(),
|
|
21833
|
-
sealedAt: number().nullable(),
|
|
21834
|
-
memberCount: number().int().nonnegative(),
|
|
21835
|
-
groupShotMediaId: number().int().nullable()
|
|
21836
|
-
});
|
|
21837
|
-
var SummariesQueryInput = object({
|
|
21838
|
-
deviceIds: array(number()).min(1),
|
|
21839
|
-
since: number().optional(),
|
|
21840
|
-
until: number().optional(),
|
|
21841
|
-
limit: number().int().min(1).max(200).default(50),
|
|
21842
|
-
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
21843
|
-
* meaning of "dog" on every summary surface. */
|
|
21844
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21845
|
-
});
|
|
21846
|
-
var SummaryDetailSchema = object({
|
|
21847
|
-
summary: SummarySchema,
|
|
21848
|
-
/** Members in absorption order, oldest join first. */
|
|
21849
|
-
members: array(object({
|
|
21850
|
-
trackId: string(),
|
|
21851
|
-
/**
|
|
21852
|
-
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
21853
|
-
* and the track no longer exists to fill it.
|
|
21854
|
-
*
|
|
21855
|
-
* The join, not the latest opinion: class voting can re-decide a track's
|
|
21856
|
-
* class afterwards, and a group's composition is the history of who came
|
|
21857
|
-
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
21858
|
-
* dog" — rather than being handed a second, denormalised tally that would
|
|
21859
|
-
* drift from the members it claims to describe.
|
|
21860
|
-
*/
|
|
21861
|
-
className: string().nullable(),
|
|
21862
|
-
/** `primary` is the one member that carries the group's identity. */
|
|
21863
|
-
role: _enum([
|
|
21864
|
-
"primary",
|
|
21865
|
-
"sibling",
|
|
21866
|
-
"child"
|
|
21867
|
-
]).nullable(),
|
|
21868
|
-
joinedAt: number(),
|
|
21869
|
-
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
21870
|
-
* at read time. Absent when nothing resolved, never an empty string. */
|
|
21871
|
-
label: string().optional(),
|
|
21872
|
-
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
21873
|
-
* recognised nobody, and absent for a member whose track has been pruned —
|
|
21874
|
-
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
21875
|
-
subLabel: string().optional()
|
|
21876
|
-
})).readonly()
|
|
21877
|
-
});
|
|
21878
|
-
/**
|
|
21879
|
-
* What a LIST of groups carries: the envelope plus what it is MADE OF.
|
|
21880
|
-
*
|
|
21881
|
-
* Coarse on purpose — the operator's rule is "only the rough data on the list,
|
|
21882
|
-
* we extend when we notice we need more". Enough to draw the card ("two people
|
|
21883
|
-
* and a dog") and no more. The MEMBERS, their names and the per-member links
|
|
21884
|
-
* are on {@link getSummary}: shipping every member of every group so a client
|
|
21885
|
-
* can count them turns a page of two hundred groups into a thousand records to
|
|
21886
|
-
* draw two hundred badges.
|
|
21887
|
-
*/
|
|
21888
|
-
var SummaryListItemSchema = object({
|
|
21889
|
-
summary: SummarySchema,
|
|
21890
|
-
/** Class counts, most numerous first; `className: null` is a member whose
|
|
21891
|
-
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
21892
|
-
classes: array(object({
|
|
21893
|
-
className: string().nullable(),
|
|
21894
|
-
count: number().int().positive()
|
|
21895
|
-
})).readonly()
|
|
21896
|
-
});
|
|
21897
|
-
var SummariesPageSchema = object({ summaries: array(SummaryListItemSchema).readonly() });
|
|
21898
|
-
/**
|
|
21899
|
-
* The paged feed, deliberately the SAME shape as {@link RecentTracksQueryInput}.
|
|
21900
|
-
*
|
|
21901
|
-
* The reel on the cameras page and the Events gallery both ride a cursor, so a
|
|
21902
|
-
* summaries feed that could only answer "the last N for these cameras"
|
|
21903
|
-
* (`listSummaries`) would make groups available in the timeline and nowhere
|
|
21904
|
-
* else. Two feeds with different ordering contracts would be two ideas of what
|
|
21905
|
-
* "newest" means, on one screen.
|
|
21906
|
-
*/
|
|
21907
|
-
var RecentSummariesQueryInput = object({
|
|
21908
|
-
/** Devices to merge. An empty array yields an empty page. */
|
|
21909
|
-
deviceIds: array(number()),
|
|
21910
|
-
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
21911
|
-
since: number().optional(),
|
|
21912
|
-
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
21913
|
-
until: number().optional(),
|
|
21914
|
-
limit: number().int().min(1).max(500).default(100),
|
|
21915
|
-
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
21916
|
-
cursor: string().optional(),
|
|
21917
|
-
/**
|
|
21918
|
-
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
21919
|
-
* deliberately the same name: the events filter tree emits one list of ticked
|
|
21920
|
-
* taxonomy nodes, and a summaries feed that called it something else would
|
|
21921
|
-
* make the operator's one filter component produce two shapes.
|
|
21922
|
-
*
|
|
21923
|
-
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
21924
|
-
* me the arrivals with a dog" has to return the group of four people who had
|
|
21925
|
-
* one with them; a filter on the group's own fields could only ever answer
|
|
21926
|
-
* about its primary.
|
|
21927
|
-
*
|
|
21928
|
-
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
21929
|
-
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
21930
|
-
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
21931
|
-
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
21932
|
-
* that read only the class would answer "animal" and never "dog".
|
|
21933
|
-
*
|
|
21934
|
-
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
21935
|
-
*/
|
|
21936
|
-
classes: array(string().min(1).max(60)).max(40).optional()
|
|
21937
|
-
});
|
|
21938
|
-
var RecentSummariesPageSchema = object({
|
|
21939
|
-
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
21940
|
-
* {@link listSummaries} — one list shape, so a card renders the same
|
|
21941
|
-
* whichever feed drew it. */
|
|
21942
|
-
summaries: array(SummaryListItemSchema).readonly(),
|
|
21943
|
-
nextCursor: string().nullable()
|
|
21944
|
-
});
|
|
21945
22021
|
var RecentTracksPageSchema = object({
|
|
21946
22022
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
21947
22023
|
tracks: array(TrackSchema).readonly(),
|
|
@@ -22453,7 +22529,7 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
22453
22529
|
classes: array(string()).optional(),
|
|
22454
22530
|
/** See {@link ExcludeSourcesDoc}. */
|
|
22455
22531
|
excludeSources: array(TrackSourceSchema).optional()
|
|
22456
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
22532
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
22457
22533
|
kind: "mutation",
|
|
22458
22534
|
auth: "admin"
|
|
22459
22535
|
}), 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({
|
|
@@ -23633,6 +23709,23 @@ var MotionSourceEnum = _enum([
|
|
|
23633
23709
|
*/
|
|
23634
23710
|
var MotionSourcesSchema = array(MotionSourceEnum);
|
|
23635
23711
|
/**
|
|
23712
|
+
* The operator-facing name of each MOTION source (D672: `onboard` = the
|
|
23713
|
+
* camera's sensors — its own motion plus any sensor attached to it). The wire
|
|
23714
|
+
* value stays `onboard`; only the label changed. `detectionSources: 'onboard'`
|
|
23715
|
+
* ("Camera onboard AI") and the notification source filter keep their labels.
|
|
23716
|
+
*/
|
|
23717
|
+
var MOTION_SOURCE_LABELS = {
|
|
23718
|
+
analyzer: "Frame-diff Analyzer (motion addon)",
|
|
23719
|
+
onboard: "Camera sensors",
|
|
23720
|
+
"device-activity": "Device activity (the device says it is working)"
|
|
23721
|
+
};
|
|
23722
|
+
/** The order the motion-source picker offers them in (not the enum's order). */
|
|
23723
|
+
var MOTION_SOURCE_PICKER_ORDER = [
|
|
23724
|
+
"analyzer",
|
|
23725
|
+
"onboard",
|
|
23726
|
+
"device-activity"
|
|
23727
|
+
];
|
|
23728
|
+
/**
|
|
23636
23729
|
* Which root detector a camera runs — EXACTLY ONE.
|
|
23637
23730
|
*
|
|
23638
23731
|
* Deliberately the SAME vocabulary post-analysis already tags every detection
|
|
@@ -23979,7 +24072,14 @@ var RunnerCameraConfigSchema = object({
|
|
|
23979
24072
|
*/
|
|
23980
24073
|
inferenceDevices: array(RunnerInferenceDeviceSchema).readonly().optional()
|
|
23981
24074
|
});
|
|
23982
|
-
|
|
24075
|
+
MOTION_SOURCE_PICKER_ORDER.map((value) => value === "onboard" ? {
|
|
24076
|
+
value,
|
|
24077
|
+
label: MOTION_SOURCE_LABELS[value],
|
|
24078
|
+
description: "The camera's own motion, plus any sensor attached to it"
|
|
24079
|
+
} : {
|
|
24080
|
+
value,
|
|
24081
|
+
label: MOTION_SOURCE_LABELS[value]
|
|
24082
|
+
}), 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;
|
|
23983
24083
|
/**
|
|
23984
24084
|
* Runtime load summary returned by `getLocalLoad`. Used by the orchestrator's
|
|
23985
24085
|
* load-balancing levels (L2 capacity-based, L3 hardware-aware) to decide
|
|
@@ -24553,6 +24653,11 @@ var CameraStatusSchema = object({
|
|
|
24553
24653
|
*/
|
|
24554
24654
|
switchedOff: array(CameraSwitchIdSchema).readonly(),
|
|
24555
24655
|
/**
|
|
24656
|
+
* The camera's attached sensors (D672). Optional only for a status composed
|
|
24657
|
+
* by an orchestrator older than D672; this orchestrator always sets it.
|
|
24658
|
+
*/
|
|
24659
|
+
cameraSensors: CameraSensorsStatusSchema.optional(),
|
|
24660
|
+
/**
|
|
24556
24661
|
* Stages of the bounded fan-out that were CUT SHORT — a timeout or a
|
|
24557
24662
|
* rejection — and whose block is therefore `null` because we could not
|
|
24558
24663
|
* READ it, not because there is nothing there.
|
|
@@ -26975,42 +27080,6 @@ DeviceType.Camera, method(object({
|
|
|
26975
27080
|
kind: "query",
|
|
26976
27081
|
auth: "protected"
|
|
26977
27082
|
});
|
|
26978
|
-
/**
|
|
26979
|
-
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
26980
|
-
* valutatore puro del suo FRONTE.
|
|
26981
|
-
*
|
|
26982
|
-
* Viveva dentro il builtin virtual-doorbell
|
|
26983
|
-
* (`@camstack/system` — `builtins/doorbell/trigger-engine.ts`) e i suoi
|
|
26984
|
-
* predicati erano privati al modulo. Il recorder ne ha bisogno per il trigger
|
|
26985
|
-
* `RecordingTriggers.sensorDeviceIds`: copiarla avrebbe creato la SECONDA
|
|
26986
|
-
* tabella, che diverge alla prima cap aggiunta e il cui sintomo — "il sensore
|
|
26987
|
-
* fa suonare il campanello ma non registra" — è esattamente D62. Quindi si
|
|
26988
|
-
* SPOSTA qui e il doorbell la ri-esporta.
|
|
26989
|
-
*
|
|
26990
|
-
* ⚠ NON è `DEVICE_STATE_READERS` (`catalogs/device-state-vocabulary.ts`), e le
|
|
26991
|
-
* due non vanno unificate: quella risponde a "qual è la PAROLA di stato per una
|
|
26992
|
-
* regola" (e include `presence`, `cover`, `alarm-panel`), questa a "qual è il
|
|
26993
|
-
* booleano il cui FRONTE conta". Vocabolari deliberatamente diversi.
|
|
26994
|
-
*/
|
|
26995
|
-
/**
|
|
26996
|
-
* Known binary / switch source caps → the boolean slice field whose
|
|
26997
|
-
* false→true rise counts as ACTIVE. Every entry is "fire on active".
|
|
26998
|
-
* Sensors whose "active" reading is not a plain boolean (presence's string
|
|
26999
|
-
* state, connectivity's connected flag) are deliberately excluded — a
|
|
27000
|
-
* reconnect is not a doorbell press, and it is not a recording either.
|
|
27001
|
-
*/
|
|
27002
|
-
var SOURCE_CAP_ACTIVE_FIELD = {
|
|
27003
|
-
contact: "entryOpen",
|
|
27004
|
-
binary: "on",
|
|
27005
|
-
switch: "on",
|
|
27006
|
-
motion: "detected",
|
|
27007
|
-
flood: "flooded",
|
|
27008
|
-
gas: "detected",
|
|
27009
|
-
smoke: "detected",
|
|
27010
|
-
"carbon-monoxide": "detected",
|
|
27011
|
-
vibration: "detected",
|
|
27012
|
-
tamper: "tampered"
|
|
27013
|
-
};
|
|
27014
27083
|
object({
|
|
27015
27084
|
/** Ms epoch of the last press. null = never observed since this provider started. */
|
|
27016
27085
|
lastPressedAt: number().nullable(),
|
|
@@ -30660,7 +30729,9 @@ object({
|
|
|
30660
30729
|
detected: boolean(),
|
|
30661
30730
|
timestamp: number(),
|
|
30662
30731
|
source: MotionSourceEnum,
|
|
30663
|
-
regions: array(MotionRegionSchema).readonly().optional()
|
|
30732
|
+
regions: array(MotionRegionSchema).readonly().optional(),
|
|
30733
|
+
/** Who started it (D672). Absent = the camera itself. Only `onboard` carries `sensor`. */
|
|
30734
|
+
triggeredBy: MotionTriggeredBySchema.optional()
|
|
30664
30735
|
});
|
|
30665
30736
|
DeviceType.Camera, DeviceType.Sensor, method(object({ deviceId: number() }), boolean());
|
|
30666
30737
|
object({
|
|
@@ -32982,12 +33053,21 @@ var RecordingStorageUsageSchema = object({
|
|
|
32982
33053
|
*/
|
|
32983
33054
|
devicesRead: _enum(["archive", "unavailable"]).optional(),
|
|
32984
33055
|
/**
|
|
33056
|
+
* Is the `archive` answer WHOLE (D674): the hour ledger loaded without
|
|
33057
|
+
* hitting its row cap, and at least one location resolved? Only then may a
|
|
33058
|
+
* camera ABSENT from `devices[]` be read as "no footage" — and only then is a
|
|
33059
|
+
* row's `oldestMs` the archive's oldest rather than the oldest of a fraction.
|
|
33060
|
+
* OPTIONAL: a recorder predating D674 omits it, and a consumer must read the
|
|
33061
|
+
* absence as `false`. A retention floor is a delete; it never guesses.
|
|
33062
|
+
*/
|
|
33063
|
+
complete: boolean().optional(),
|
|
33064
|
+
/**
|
|
32985
33065
|
* Per-physical-volume capacity. OPTIONAL, and consumers must render the rest
|
|
32986
|
-
* of the payload without it:
|
|
32987
|
-
*
|
|
32988
|
-
*
|
|
32989
|
-
*
|
|
32990
|
-
*
|
|
33066
|
+
* of the payload without it: a recorder that could not build it omits it. A
|
|
33067
|
+
* UI that dereferences it unconditionally crashes the whole Storage page over
|
|
33068
|
+
* a missing disk bar. (The hub's cap routers pass output through unvalidated
|
|
33069
|
+
* since 2026-07-11 — `cap-router-builder.ts` — so a newer recorder's fields
|
|
33070
|
+
* are not stripped by an older hub.)
|
|
32991
33071
|
*/
|
|
32992
33072
|
locations: array(RecordingLocationUsageSchema).optional()
|
|
32993
33073
|
});
|
|
@@ -35758,7 +35838,12 @@ Object.freeze({
|
|
|
35758
35838
|
number: {
|
|
35759
35839
|
kind: "fixed",
|
|
35760
35840
|
result: ["number", "null"]
|
|
35761
|
-
}
|
|
35841
|
+
},
|
|
35842
|
+
rose: {
|
|
35843
|
+
kind: "fixed",
|
|
35844
|
+
result: ["number", "null"]
|
|
35845
|
+
},
|
|
35846
|
+
count: NUMBER
|
|
35762
35847
|
});
|
|
35763
35848
|
`${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
|
|
35764
35849
|
/**
|
|
@@ -38873,6 +38958,12 @@ Object.freeze({
|
|
|
38873
38958
|
addonId: null,
|
|
38874
38959
|
access: "view"
|
|
38875
38960
|
},
|
|
38961
|
+
"deviceManager.getWrapperActivation": {
|
|
38962
|
+
capName: "device-manager",
|
|
38963
|
+
capScope: "system",
|
|
38964
|
+
addonId: null,
|
|
38965
|
+
access: "view"
|
|
38966
|
+
},
|
|
38876
38967
|
"deviceManager.listAll": {
|
|
38877
38968
|
capName: "device-manager",
|
|
38878
38969
|
capScope: "system",
|
|
@@ -41147,12 +41238,6 @@ Object.freeze({
|
|
|
41147
41238
|
addonId: null,
|
|
41148
41239
|
access: "view"
|
|
41149
41240
|
},
|
|
41150
|
-
"pipelineAnalytics.getSummary": {
|
|
41151
|
-
capName: "pipeline-analytics",
|
|
41152
|
-
capScope: "device",
|
|
41153
|
-
addonId: null,
|
|
41154
|
-
access: "view"
|
|
41155
|
-
},
|
|
41156
41241
|
"pipelineAnalytics.getTrack": {
|
|
41157
41242
|
capName: "pipeline-analytics",
|
|
41158
41243
|
capScope: "device",
|
|
@@ -41213,12 +41298,6 @@ Object.freeze({
|
|
|
41213
41298
|
addonId: null,
|
|
41214
41299
|
access: "view"
|
|
41215
41300
|
},
|
|
41216
|
-
"pipelineAnalytics.listRecentSummaries": {
|
|
41217
|
-
capName: "pipeline-analytics",
|
|
41218
|
-
capScope: "device",
|
|
41219
|
-
addonId: null,
|
|
41220
|
-
access: "view"
|
|
41221
|
-
},
|
|
41222
41301
|
"pipelineAnalytics.listRecentTracks": {
|
|
41223
41302
|
capName: "pipeline-analytics",
|
|
41224
41303
|
capScope: "device",
|
|
@@ -41249,12 +41328,6 @@ Object.freeze({
|
|
|
41249
41328
|
addonId: null,
|
|
41250
41329
|
access: "view"
|
|
41251
41330
|
},
|
|
41252
|
-
"pipelineAnalytics.listSummaries": {
|
|
41253
|
-
capName: "pipeline-analytics",
|
|
41254
|
-
capScope: "device",
|
|
41255
|
-
addonId: null,
|
|
41256
|
-
access: "view"
|
|
41257
|
-
},
|
|
41258
41331
|
"pipelineAnalytics.listTrackMedia": {
|
|
41259
41332
|
capName: "pipeline-analytics",
|
|
41260
41333
|
capScope: "device",
|
|
@@ -44682,6 +44755,11 @@ Object.freeze({
|
|
|
44682
44755
|
form: "single",
|
|
44683
44756
|
optional: false
|
|
44684
44757
|
}],
|
|
44758
|
+
"deviceManager.getWrapperActivation": [{
|
|
44759
|
+
name: "deviceId",
|
|
44760
|
+
form: "single",
|
|
44761
|
+
optional: false
|
|
44762
|
+
}],
|
|
44685
44763
|
"deviceManager.listAll": [{
|
|
44686
44764
|
name: "deviceIds",
|
|
44687
44765
|
form: "array",
|
|
@@ -45419,11 +45497,6 @@ Object.freeze({
|
|
|
45419
45497
|
form: "single",
|
|
45420
45498
|
optional: true
|
|
45421
45499
|
}],
|
|
45422
|
-
"pipelineAnalytics.listRecentSummaries": [{
|
|
45423
|
-
name: "deviceIds",
|
|
45424
|
-
form: "array",
|
|
45425
|
-
optional: false
|
|
45426
|
-
}],
|
|
45427
45500
|
"pipelineAnalytics.listRecentTracks": [{
|
|
45428
45501
|
name: "deviceIds",
|
|
45429
45502
|
form: "array",
|
|
@@ -45434,11 +45507,6 @@ Object.freeze({
|
|
|
45434
45507
|
form: "array",
|
|
45435
45508
|
optional: true
|
|
45436
45509
|
}],
|
|
45437
|
-
"pipelineAnalytics.listSummaries": [{
|
|
45438
|
-
name: "deviceIds",
|
|
45439
|
-
form: "array",
|
|
45440
|
-
optional: false
|
|
45441
|
-
}],
|
|
45442
45510
|
"pipelineAnalytics.listTrackMedia": [{
|
|
45443
45511
|
name: "deviceId",
|
|
45444
45512
|
form: "single",
|