@camstack/addon-export-hap 1.2.38 → 1.2.39
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/hap-export.addon.js +184 -34
- package/dist/hap-export.addon.mjs +184 -34
- package/package.json +1 -1
package/dist/hap-export.addon.js
CHANGED
|
@@ -5886,6 +5886,13 @@ var BaseAddon = class {
|
|
|
5886
5886
|
_readinessGeneration = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2, 14);
|
|
5887
5887
|
/** Capability names this addon registered at init — used to emit matching `down` events on shutdown. */
|
|
5888
5888
|
_registeredCapNames = [];
|
|
5889
|
+
/**
|
|
5890
|
+
* True only after `readAddonStore` actually answered. Constructor
|
|
5891
|
+
* defaults look like stored config when the store is down — a forked
|
|
5892
|
+
* addon that auto-starts from those defaults (cloudflare-tunnel quick
|
|
5893
|
+
* mode, 2026-08-25) is not "the operator chose this".
|
|
5894
|
+
*/
|
|
5895
|
+
settingsStoreReady = false;
|
|
5889
5896
|
/** Default config values. Provided via constructor. */
|
|
5890
5897
|
defaults;
|
|
5891
5898
|
constructor(defaults) {
|
|
@@ -6286,7 +6293,9 @@ var BaseAddon = class {
|
|
|
6286
6293
|
];
|
|
6287
6294
|
let lastErr;
|
|
6288
6295
|
for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
|
|
6289
|
-
|
|
6296
|
+
const stored = await settings.readAddonStore() ?? {};
|
|
6297
|
+
this.settingsStoreReady = true;
|
|
6298
|
+
return stored;
|
|
6290
6299
|
} catch (err) {
|
|
6291
6300
|
lastErr = err;
|
|
6292
6301
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -6294,6 +6303,7 @@ var BaseAddon = class {
|
|
|
6294
6303
|
if (attempt === delaysMs.length) break;
|
|
6295
6304
|
await new Promise((r) => setTimeout(r, delaysMs[attempt]));
|
|
6296
6305
|
}
|
|
6306
|
+
this.settingsStoreReady = false;
|
|
6297
6307
|
this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
|
|
6298
6308
|
return {};
|
|
6299
6309
|
}
|
|
@@ -8832,6 +8842,12 @@ var ModelVariantGroupSchema = object({
|
|
|
8832
8842
|
*/
|
|
8833
8843
|
resolution: number().int().positive().optional()
|
|
8834
8844
|
});
|
|
8845
|
+
var ModelProviderIdSchema = _enum([
|
|
8846
|
+
"camstack",
|
|
8847
|
+
"frigate",
|
|
8848
|
+
"scrypted",
|
|
8849
|
+
"custom"
|
|
8850
|
+
]);
|
|
8835
8851
|
var ModelCatalogEntrySchema = object({
|
|
8836
8852
|
id: string(),
|
|
8837
8853
|
name: string(),
|
|
@@ -8929,6 +8945,12 @@ var ModelCatalogEntrySchema = object({
|
|
|
8929
8945
|
*/
|
|
8930
8946
|
group: ModelVariantGroupSchema.optional(),
|
|
8931
8947
|
/**
|
|
8948
|
+
* Catalog source for the pipeline stepper's provider-first picker. Absent on
|
|
8949
|
+
* built-in CamStack entries (treated as `camstack`) and on registry rows
|
|
8950
|
+
* persisted before this field existed (`inferModelProvider` fills those).
|
|
8951
|
+
*/
|
|
8952
|
+
provider: ModelProviderIdSchema.optional(),
|
|
8953
|
+
/**
|
|
8932
8954
|
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
8933
8955
|
* applies (Frigate / COCO public catalog). Set on a custom model whose raw
|
|
8934
8956
|
* labels already ARE the CamStack macros (Scrypted identity map).
|
|
@@ -12537,6 +12559,27 @@ var LinkedDeviceSchema = object({
|
|
|
12537
12559
|
features: array(string()),
|
|
12538
12560
|
producesTrackedEvents: boolean().optional()
|
|
12539
12561
|
});
|
|
12562
|
+
/** One camera's resolved linked set, tagged with the camera it belongs to.
|
|
12563
|
+
* The batch answer needs the tag; the single-device answer already has it
|
|
12564
|
+
* from the input, which is why `getLinkedDevices` keeps the untagged shape. */
|
|
12565
|
+
var LinkedDevicesForDeviceSchema = object({
|
|
12566
|
+
deviceId: number(),
|
|
12567
|
+
mode: LinkedDevicesModeSchema,
|
|
12568
|
+
devices: array(LinkedDeviceSchema)
|
|
12569
|
+
});
|
|
12570
|
+
/** One device's binding map — the shape `getBindings`, `getBindingsBatch` and
|
|
12571
|
+
* `getAllBindings` all answer in. Declared once: three copies of the same
|
|
12572
|
+
* object literal is exactly how the three drift apart. */
|
|
12573
|
+
var DeviceBindingsForDeviceSchema = object({
|
|
12574
|
+
deviceId: number(),
|
|
12575
|
+
entries: array(object({
|
|
12576
|
+
capName: string(),
|
|
12577
|
+
kind: _enum(["native", "wrapped"]),
|
|
12578
|
+
providerAddonId: string(),
|
|
12579
|
+
providerNodeId: string(),
|
|
12580
|
+
nativeAddonId: string()
|
|
12581
|
+
}))
|
|
12582
|
+
});
|
|
12540
12583
|
var SavedDeviceRowSchema = object({
|
|
12541
12584
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
12542
12585
|
id: number(),
|
|
@@ -12762,11 +12805,25 @@ method(object({
|
|
|
12762
12805
|
projection: _enum(["full", "slim"]).optional(),
|
|
12763
12806
|
/** Return only camera devices. Filtering server-side instead of
|
|
12764
12807
|
* shipping 293 rows to find 12. */
|
|
12765
|
-
isCamera: boolean().optional()
|
|
12808
|
+
isCamera: boolean().optional(),
|
|
12809
|
+
/**
|
|
12810
|
+
* Return only these device ids. For the caller that already KNOWS the
|
|
12811
|
+
* handful it wants and needs a field the id-bearing answer does not
|
|
12812
|
+
* carry — the viewer's linked-devices panel joins `type` and `online`
|
|
12813
|
+
* onto ~8 linked ids and, unfiltered, dragged the fleet across to do
|
|
12814
|
+
* it: 433 KB slim / 958 KB full for 967 devices, on a query that
|
|
12815
|
+
* refetches on the reconcile interval, on a phone.
|
|
12816
|
+
*
|
|
12817
|
+
* Safe to send at a hub that predates it: Zod STRIPS unknown input
|
|
12818
|
+
* keys rather than rejecting them (verified against the live hub
|
|
12819
|
+
* 2026-08-25 — 967 rows came back), so an old hub answers exactly what
|
|
12820
|
+
* it answers today and the caller filters as it already does.
|
|
12821
|
+
*/
|
|
12822
|
+
deviceIds: array(number()).optional()
|
|
12766
12823
|
}), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
12767
12824
|
mode: LinkedDevicesModeSchema,
|
|
12768
12825
|
devices: array(LinkedDeviceSchema)
|
|
12769
|
-
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
12826
|
+
})), method(object({ deviceIds: array(number()) }), array(LinkedDevicesForDeviceSchema)), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
12770
12827
|
deviceId: number(),
|
|
12771
12828
|
values: record(string(), unknown())
|
|
12772
12829
|
}), object({ success: literal(true) }), {
|
|
@@ -12793,25 +12850,7 @@ method(object({
|
|
|
12793
12850
|
}), method(object({ deviceId: number() }), array(StreamProbeResultSchema), {
|
|
12794
12851
|
kind: "mutation",
|
|
12795
12852
|
auth: "admin"
|
|
12796
|
-
}), method(object({ deviceId: number() }), object({
|
|
12797
|
-
deviceId: number(),
|
|
12798
|
-
entries: array(object({
|
|
12799
|
-
capName: string(),
|
|
12800
|
-
kind: _enum(["native", "wrapped"]),
|
|
12801
|
-
providerAddonId: string(),
|
|
12802
|
-
providerNodeId: string(),
|
|
12803
|
-
nativeAddonId: string()
|
|
12804
|
-
}))
|
|
12805
|
-
})), method(object({}), array(object({
|
|
12806
|
-
deviceId: number(),
|
|
12807
|
-
entries: array(object({
|
|
12808
|
-
capName: string(),
|
|
12809
|
-
kind: _enum(["native", "wrapped"]),
|
|
12810
|
-
providerAddonId: string(),
|
|
12811
|
-
providerNodeId: string(),
|
|
12812
|
-
nativeAddonId: string()
|
|
12813
|
-
}))
|
|
12814
|
-
}))), method(object({
|
|
12853
|
+
}), method(object({ deviceId: number() }), DeviceBindingsForDeviceSchema), method(object({ deviceIds: array(number()) }), array(DeviceBindingsForDeviceSchema)), method(object({}), array(DeviceBindingsForDeviceSchema)), method(object({
|
|
12815
12854
|
deviceId: number(),
|
|
12816
12855
|
capName: string(),
|
|
12817
12856
|
wrapperAddonId: string(),
|
|
@@ -15183,12 +15222,15 @@ var NcOccupancyConditionSchema = object({
|
|
|
15183
15222
|
* there is no second switch that can disagree with the first and every rule
|
|
15184
15223
|
* authored before the decision migrates for free (`audioModeOf`):
|
|
15185
15224
|
*
|
|
15186
|
-
* - **LABEL mode — `labels` present.** The rule fires
|
|
15187
|
-
*
|
|
15188
|
-
* `hitPercent` and `samplingSeconds` are ignored
|
|
15189
|
-
*
|
|
15190
|
-
*
|
|
15191
|
-
*
|
|
15225
|
+
* - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
|
|
15226
|
+
* labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
|
|
15227
|
+
* `hitPercent` and `samplingSeconds` are still ignored — a percentage of
|
|
15228
|
+
* frames is the wrong question for a classifier that labels 1–3 frames
|
|
15229
|
+
* per episode. The count window is the brake that drops a single-frame
|
|
15230
|
+
* false positive; the rule's own `throttle` cooldown is the other. The
|
|
15231
|
+
* per-label confidence floor is the analyzer's (`classificationMinScore`,
|
|
15232
|
+
* per device) — a label only reaches this condition if the classifier was
|
|
15233
|
+
* already confident enough. `confirmHits: 1` restores first-frame fire.
|
|
15192
15234
|
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
15193
15235
|
* the condition: at least `hitPercent`% of the samples over
|
|
15194
15236
|
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
@@ -15215,14 +15257,22 @@ var NcOccupancyConditionSchema = object({
|
|
|
15215
15257
|
* an operator who typed `dog` mean the same thing.
|
|
15216
15258
|
*/
|
|
15217
15259
|
var NcAudioConditionSchema = object({
|
|
15218
|
-
/** LABEL MODE: audio macro labels. Present ⇒
|
|
15260
|
+
/** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
|
|
15219
15261
|
labels: array(string().min(1)).min(1).optional(),
|
|
15220
15262
|
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
15221
15263
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
15222
15264
|
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
15223
15265
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
15224
15266
|
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
15225
|
-
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
15267
|
+
samplingSeconds: number().int().min(1).max(300).default(10),
|
|
15268
|
+
/**
|
|
15269
|
+
* LABEL MODE: how many labelled frames must land inside
|
|
15270
|
+
* {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
|
|
15271
|
+
* Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
|
|
15272
|
+
*/
|
|
15273
|
+
confirmHits: number().int().min(1).max(20).optional(),
|
|
15274
|
+
/** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
|
|
15275
|
+
confirmWindowSec: number().int().min(1).max(60).optional()
|
|
15226
15276
|
});
|
|
15227
15277
|
/**
|
|
15228
15278
|
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
@@ -17596,6 +17646,46 @@ var RecentTracksPageSchema = object({
|
|
|
17596
17646
|
/** Cursor for the next page, or null when this page is the last. */
|
|
17597
17647
|
nextCursor: string().nullable()
|
|
17598
17648
|
});
|
|
17649
|
+
var LIST_GROUPS_DEFAULT_LIMIT = 40;
|
|
17650
|
+
var LIST_GROUPS_MAX_LIMIT = 100;
|
|
17651
|
+
var AnalyticsGroupRecordSchema = object({
|
|
17652
|
+
id: string(),
|
|
17653
|
+
deviceId: number().int(),
|
|
17654
|
+
openedAt: number().int(),
|
|
17655
|
+
closedAt: number().int(),
|
|
17656
|
+
timestamp: number().int(),
|
|
17657
|
+
memberCount: number().int(),
|
|
17658
|
+
memberTrackIds: array(string()).readonly(),
|
|
17659
|
+
className: string(),
|
|
17660
|
+
classes: array(string()).readonly(),
|
|
17661
|
+
/** Relative event-media path, or null when the group has no picture yet. */
|
|
17662
|
+
mediaUrl: string().nullable(),
|
|
17663
|
+
singleton: boolean()
|
|
17664
|
+
});
|
|
17665
|
+
var AnalyticsGroupMemberSchema = object({
|
|
17666
|
+
trackId: string(),
|
|
17667
|
+
deviceId: number().int(),
|
|
17668
|
+
className: string(),
|
|
17669
|
+
firstSeen: number().int(),
|
|
17670
|
+
lastSeen: number().int(),
|
|
17671
|
+
mediaUrl: string().nullable()
|
|
17672
|
+
});
|
|
17673
|
+
var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
|
|
17674
|
+
var ListGroupsQueryInput = object({
|
|
17675
|
+
/** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
|
|
17676
|
+
deviceIds: array(number()),
|
|
17677
|
+
/** Window lower bound on `closedAt` (inclusive). */
|
|
17678
|
+
since: number().optional(),
|
|
17679
|
+
/** Window upper bound on `openedAt` (inclusive). */
|
|
17680
|
+
until: number().optional(),
|
|
17681
|
+
limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
|
|
17682
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
17683
|
+
cursor: string().optional()
|
|
17684
|
+
});
|
|
17685
|
+
var ListGroupsPageSchema = object({
|
|
17686
|
+
groups: array(AnalyticsGroupRecordSchema).readonly(),
|
|
17687
|
+
nextCursor: string().nullable()
|
|
17688
|
+
});
|
|
17599
17689
|
var KeyEventQueryInput = object({
|
|
17600
17690
|
deviceId: number(),
|
|
17601
17691
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -17671,7 +17761,9 @@ var TrackCascadeCountsSchema = object({
|
|
|
17671
17761
|
/** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
|
|
17672
17762
|
plates: number().int(),
|
|
17673
17763
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
17674
|
-
embeddings: number().int()
|
|
17764
|
+
embeddings: number().int(),
|
|
17765
|
+
/** Group membership + group rows removed with their last member (best-effort). */
|
|
17766
|
+
groups: number().int()
|
|
17675
17767
|
});
|
|
17676
17768
|
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
17677
17769
|
var DiskReconcileCountsSchema = object({
|
|
@@ -17817,7 +17909,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17817
17909
|
* stationary registry). Default false: the timeline lists passages,
|
|
17818
17910
|
* not parking records (operator decision, 2026-08-15). */
|
|
17819
17911
|
includeStationary: boolean().optional()
|
|
17820
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
17912
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
|
|
17913
|
+
deviceId: number(),
|
|
17914
|
+
groupId: string().min(1)
|
|
17915
|
+
}), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
17821
17916
|
kind: "mutation",
|
|
17822
17917
|
auth: "admin"
|
|
17823
17918
|
}), 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({
|
|
@@ -18127,7 +18222,8 @@ var PipelineModelOptionSchema = object({
|
|
|
18127
18222
|
sizeMB: number()
|
|
18128
18223
|
})),
|
|
18129
18224
|
group: ModelVariantGroupSchema.optional(),
|
|
18130
|
-
legacy: boolean().optional()
|
|
18225
|
+
legacy: boolean().optional(),
|
|
18226
|
+
provider: ModelProviderIdSchema.optional()
|
|
18131
18227
|
});
|
|
18132
18228
|
var ConfigFieldBridge = custom();
|
|
18133
18229
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -24759,7 +24855,12 @@ var PlateInfoSchema = object({
|
|
|
24759
24855
|
plateBbox: BoundingBoxSchema.optional(),
|
|
24760
24856
|
/** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
|
|
24761
24857
|
keyFrameMediaKey: string().optional(),
|
|
24762
|
-
base64: string().optional()
|
|
24858
|
+
base64: string().optional(),
|
|
24859
|
+
/**
|
|
24860
|
+
* Same crop as a data-plane URL. `getPlateByTrack` returns this and
|
|
24861
|
+
* never inlines JPEG; `listPlates` still inlines for the admin-ui.
|
|
24862
|
+
*/
|
|
24863
|
+
cropUrl: string().optional()
|
|
24763
24864
|
});
|
|
24764
24865
|
var MediaFileLiteSchema = object({
|
|
24765
24866
|
key: string(),
|
|
@@ -28424,6 +28525,12 @@ Object.freeze({
|
|
|
28424
28525
|
addonId: null,
|
|
28425
28526
|
access: "view"
|
|
28426
28527
|
},
|
|
28528
|
+
"deviceManager.getBindingsBatch": {
|
|
28529
|
+
capName: "device-manager",
|
|
28530
|
+
capScope: "system",
|
|
28531
|
+
addonId: null,
|
|
28532
|
+
access: "view"
|
|
28533
|
+
},
|
|
28427
28534
|
"deviceManager.getChildren": {
|
|
28428
28535
|
capName: "device-manager",
|
|
28429
28536
|
capScope: "system",
|
|
@@ -28484,6 +28591,12 @@ Object.freeze({
|
|
|
28484
28591
|
addonId: null,
|
|
28485
28592
|
access: "view"
|
|
28486
28593
|
},
|
|
28594
|
+
"deviceManager.getLinkedDevicesBatch": {
|
|
28595
|
+
capName: "device-manager",
|
|
28596
|
+
capScope: "system",
|
|
28597
|
+
addonId: null,
|
|
28598
|
+
access: "view"
|
|
28599
|
+
},
|
|
28487
28600
|
"deviceManager.getRoleDisplayDefaults": {
|
|
28488
28601
|
capName: "device-manager",
|
|
28489
28602
|
capScope: "system",
|
|
@@ -30254,6 +30367,12 @@ Object.freeze({
|
|
|
30254
30367
|
addonId: null,
|
|
30255
30368
|
access: "view"
|
|
30256
30369
|
},
|
|
30370
|
+
"pipelineAnalytics.getGroup": {
|
|
30371
|
+
capName: "pipeline-analytics",
|
|
30372
|
+
capScope: "device",
|
|
30373
|
+
addonId: null,
|
|
30374
|
+
access: "view"
|
|
30375
|
+
},
|
|
30257
30376
|
"pipelineAnalytics.getKeyEvents": {
|
|
30258
30377
|
capName: "pipeline-analytics",
|
|
30259
30378
|
capScope: "device",
|
|
@@ -30338,6 +30457,12 @@ Object.freeze({
|
|
|
30338
30457
|
addonId: null,
|
|
30339
30458
|
access: "view"
|
|
30340
30459
|
},
|
|
30460
|
+
"pipelineAnalytics.listGroups": {
|
|
30461
|
+
capName: "pipeline-analytics",
|
|
30462
|
+
capScope: "device",
|
|
30463
|
+
addonId: null,
|
|
30464
|
+
access: "view"
|
|
30465
|
+
},
|
|
30341
30466
|
"pipelineAnalytics.listOpsLog": {
|
|
30342
30467
|
capName: "pipeline-analytics",
|
|
30343
30468
|
capScope: "device",
|
|
@@ -33119,6 +33244,11 @@ Object.freeze({
|
|
|
33119
33244
|
form: "single",
|
|
33120
33245
|
optional: false
|
|
33121
33246
|
}],
|
|
33247
|
+
"deviceManager.getBindingsBatch": [{
|
|
33248
|
+
name: "deviceIds",
|
|
33249
|
+
form: "array",
|
|
33250
|
+
optional: false
|
|
33251
|
+
}],
|
|
33122
33252
|
"deviceManager.getChildren": [{
|
|
33123
33253
|
name: "parentDeviceId",
|
|
33124
33254
|
form: "single",
|
|
@@ -33164,6 +33294,11 @@ Object.freeze({
|
|
|
33164
33294
|
form: "single",
|
|
33165
33295
|
optional: false
|
|
33166
33296
|
}],
|
|
33297
|
+
"deviceManager.getLinkedDevicesBatch": [{
|
|
33298
|
+
name: "deviceIds",
|
|
33299
|
+
form: "array",
|
|
33300
|
+
optional: false
|
|
33301
|
+
}],
|
|
33167
33302
|
"deviceManager.getSettingsSchema": [{
|
|
33168
33303
|
name: "deviceId",
|
|
33169
33304
|
form: "single",
|
|
@@ -33184,6 +33319,11 @@ Object.freeze({
|
|
|
33184
33319
|
form: "single",
|
|
33185
33320
|
optional: false
|
|
33186
33321
|
}],
|
|
33322
|
+
"deviceManager.listAll": [{
|
|
33323
|
+
name: "deviceIds",
|
|
33324
|
+
form: "array",
|
|
33325
|
+
optional: true
|
|
33326
|
+
}],
|
|
33187
33327
|
"deviceManager.loadConfig": [{
|
|
33188
33328
|
name: "deviceId",
|
|
33189
33329
|
form: "single",
|
|
@@ -33757,6 +33897,11 @@ Object.freeze({
|
|
|
33757
33897
|
form: "single",
|
|
33758
33898
|
optional: false
|
|
33759
33899
|
}],
|
|
33900
|
+
"pipelineAnalytics.getGroup": [{
|
|
33901
|
+
name: "deviceId",
|
|
33902
|
+
form: "single",
|
|
33903
|
+
optional: false
|
|
33904
|
+
}],
|
|
33760
33905
|
"pipelineAnalytics.getKeyEvents": [{
|
|
33761
33906
|
name: "deviceId",
|
|
33762
33907
|
form: "single",
|
|
@@ -33812,6 +33957,11 @@ Object.freeze({
|
|
|
33812
33957
|
form: "array",
|
|
33813
33958
|
optional: false
|
|
33814
33959
|
}],
|
|
33960
|
+
"pipelineAnalytics.listGroups": [{
|
|
33961
|
+
name: "deviceIds",
|
|
33962
|
+
form: "array",
|
|
33963
|
+
optional: false
|
|
33964
|
+
}],
|
|
33815
33965
|
"pipelineAnalytics.listOpsLog": [{
|
|
33816
33966
|
name: "deviceId",
|
|
33817
33967
|
form: "single",
|
|
@@ -5874,6 +5874,13 @@ var BaseAddon = class {
|
|
|
5874
5874
|
_readinessGeneration = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2, 14);
|
|
5875
5875
|
/** Capability names this addon registered at init — used to emit matching `down` events on shutdown. */
|
|
5876
5876
|
_registeredCapNames = [];
|
|
5877
|
+
/**
|
|
5878
|
+
* True only after `readAddonStore` actually answered. Constructor
|
|
5879
|
+
* defaults look like stored config when the store is down — a forked
|
|
5880
|
+
* addon that auto-starts from those defaults (cloudflare-tunnel quick
|
|
5881
|
+
* mode, 2026-08-25) is not "the operator chose this".
|
|
5882
|
+
*/
|
|
5883
|
+
settingsStoreReady = false;
|
|
5877
5884
|
/** Default config values. Provided via constructor. */
|
|
5878
5885
|
defaults;
|
|
5879
5886
|
constructor(defaults) {
|
|
@@ -6274,7 +6281,9 @@ var BaseAddon = class {
|
|
|
6274
6281
|
];
|
|
6275
6282
|
let lastErr;
|
|
6276
6283
|
for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
|
|
6277
|
-
|
|
6284
|
+
const stored = await settings.readAddonStore() ?? {};
|
|
6285
|
+
this.settingsStoreReady = true;
|
|
6286
|
+
return stored;
|
|
6278
6287
|
} catch (err) {
|
|
6279
6288
|
lastErr = err;
|
|
6280
6289
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -6282,6 +6291,7 @@ var BaseAddon = class {
|
|
|
6282
6291
|
if (attempt === delaysMs.length) break;
|
|
6283
6292
|
await new Promise((r) => setTimeout(r, delaysMs[attempt]));
|
|
6284
6293
|
}
|
|
6294
|
+
this.settingsStoreReady = false;
|
|
6285
6295
|
this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
|
|
6286
6296
|
return {};
|
|
6287
6297
|
}
|
|
@@ -8820,6 +8830,12 @@ var ModelVariantGroupSchema = object({
|
|
|
8820
8830
|
*/
|
|
8821
8831
|
resolution: number().int().positive().optional()
|
|
8822
8832
|
});
|
|
8833
|
+
var ModelProviderIdSchema = _enum([
|
|
8834
|
+
"camstack",
|
|
8835
|
+
"frigate",
|
|
8836
|
+
"scrypted",
|
|
8837
|
+
"custom"
|
|
8838
|
+
]);
|
|
8823
8839
|
var ModelCatalogEntrySchema = object({
|
|
8824
8840
|
id: string(),
|
|
8825
8841
|
name: string(),
|
|
@@ -8917,6 +8933,12 @@ var ModelCatalogEntrySchema = object({
|
|
|
8917
8933
|
*/
|
|
8918
8934
|
group: ModelVariantGroupSchema.optional(),
|
|
8919
8935
|
/**
|
|
8936
|
+
* Catalog source for the pipeline stepper's provider-first picker. Absent on
|
|
8937
|
+
* built-in CamStack entries (treated as `camstack`) and on registry rows
|
|
8938
|
+
* persisted before this field existed (`inferModelProvider` fills those).
|
|
8939
|
+
*/
|
|
8940
|
+
provider: ModelProviderIdSchema.optional(),
|
|
8941
|
+
/**
|
|
8920
8942
|
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
8921
8943
|
* applies (Frigate / COCO public catalog). Set on a custom model whose raw
|
|
8922
8944
|
* labels already ARE the CamStack macros (Scrypted identity map).
|
|
@@ -12525,6 +12547,27 @@ var LinkedDeviceSchema = object({
|
|
|
12525
12547
|
features: array(string()),
|
|
12526
12548
|
producesTrackedEvents: boolean().optional()
|
|
12527
12549
|
});
|
|
12550
|
+
/** One camera's resolved linked set, tagged with the camera it belongs to.
|
|
12551
|
+
* The batch answer needs the tag; the single-device answer already has it
|
|
12552
|
+
* from the input, which is why `getLinkedDevices` keeps the untagged shape. */
|
|
12553
|
+
var LinkedDevicesForDeviceSchema = object({
|
|
12554
|
+
deviceId: number(),
|
|
12555
|
+
mode: LinkedDevicesModeSchema,
|
|
12556
|
+
devices: array(LinkedDeviceSchema)
|
|
12557
|
+
});
|
|
12558
|
+
/** One device's binding map — the shape `getBindings`, `getBindingsBatch` and
|
|
12559
|
+
* `getAllBindings` all answer in. Declared once: three copies of the same
|
|
12560
|
+
* object literal is exactly how the three drift apart. */
|
|
12561
|
+
var DeviceBindingsForDeviceSchema = object({
|
|
12562
|
+
deviceId: number(),
|
|
12563
|
+
entries: array(object({
|
|
12564
|
+
capName: string(),
|
|
12565
|
+
kind: _enum(["native", "wrapped"]),
|
|
12566
|
+
providerAddonId: string(),
|
|
12567
|
+
providerNodeId: string(),
|
|
12568
|
+
nativeAddonId: string()
|
|
12569
|
+
}))
|
|
12570
|
+
});
|
|
12528
12571
|
var SavedDeviceRowSchema = object({
|
|
12529
12572
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
12530
12573
|
id: number(),
|
|
@@ -12750,11 +12793,25 @@ method(object({
|
|
|
12750
12793
|
projection: _enum(["full", "slim"]).optional(),
|
|
12751
12794
|
/** Return only camera devices. Filtering server-side instead of
|
|
12752
12795
|
* shipping 293 rows to find 12. */
|
|
12753
|
-
isCamera: boolean().optional()
|
|
12796
|
+
isCamera: boolean().optional(),
|
|
12797
|
+
/**
|
|
12798
|
+
* Return only these device ids. For the caller that already KNOWS the
|
|
12799
|
+
* handful it wants and needs a field the id-bearing answer does not
|
|
12800
|
+
* carry — the viewer's linked-devices panel joins `type` and `online`
|
|
12801
|
+
* onto ~8 linked ids and, unfiltered, dragged the fleet across to do
|
|
12802
|
+
* it: 433 KB slim / 958 KB full for 967 devices, on a query that
|
|
12803
|
+
* refetches on the reconcile interval, on a phone.
|
|
12804
|
+
*
|
|
12805
|
+
* Safe to send at a hub that predates it: Zod STRIPS unknown input
|
|
12806
|
+
* keys rather than rejecting them (verified against the live hub
|
|
12807
|
+
* 2026-08-25 — 967 rows came back), so an old hub answers exactly what
|
|
12808
|
+
* it answers today and the caller filters as it already does.
|
|
12809
|
+
*/
|
|
12810
|
+
deviceIds: array(number()).optional()
|
|
12754
12811
|
}), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
12755
12812
|
mode: LinkedDevicesModeSchema,
|
|
12756
12813
|
devices: array(LinkedDeviceSchema)
|
|
12757
|
-
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
12814
|
+
})), method(object({ deviceIds: array(number()) }), array(LinkedDevicesForDeviceSchema)), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
12758
12815
|
deviceId: number(),
|
|
12759
12816
|
values: record(string(), unknown())
|
|
12760
12817
|
}), object({ success: literal(true) }), {
|
|
@@ -12781,25 +12838,7 @@ method(object({
|
|
|
12781
12838
|
}), method(object({ deviceId: number() }), array(StreamProbeResultSchema), {
|
|
12782
12839
|
kind: "mutation",
|
|
12783
12840
|
auth: "admin"
|
|
12784
|
-
}), method(object({ deviceId: number() }), object({
|
|
12785
|
-
deviceId: number(),
|
|
12786
|
-
entries: array(object({
|
|
12787
|
-
capName: string(),
|
|
12788
|
-
kind: _enum(["native", "wrapped"]),
|
|
12789
|
-
providerAddonId: string(),
|
|
12790
|
-
providerNodeId: string(),
|
|
12791
|
-
nativeAddonId: string()
|
|
12792
|
-
}))
|
|
12793
|
-
})), method(object({}), array(object({
|
|
12794
|
-
deviceId: number(),
|
|
12795
|
-
entries: array(object({
|
|
12796
|
-
capName: string(),
|
|
12797
|
-
kind: _enum(["native", "wrapped"]),
|
|
12798
|
-
providerAddonId: string(),
|
|
12799
|
-
providerNodeId: string(),
|
|
12800
|
-
nativeAddonId: string()
|
|
12801
|
-
}))
|
|
12802
|
-
}))), method(object({
|
|
12841
|
+
}), method(object({ deviceId: number() }), DeviceBindingsForDeviceSchema), method(object({ deviceIds: array(number()) }), array(DeviceBindingsForDeviceSchema)), method(object({}), array(DeviceBindingsForDeviceSchema)), method(object({
|
|
12803
12842
|
deviceId: number(),
|
|
12804
12843
|
capName: string(),
|
|
12805
12844
|
wrapperAddonId: string(),
|
|
@@ -15171,12 +15210,15 @@ var NcOccupancyConditionSchema = object({
|
|
|
15171
15210
|
* there is no second switch that can disagree with the first and every rule
|
|
15172
15211
|
* authored before the decision migrates for free (`audioModeOf`):
|
|
15173
15212
|
*
|
|
15174
|
-
* - **LABEL mode — `labels` present.** The rule fires
|
|
15175
|
-
*
|
|
15176
|
-
* `hitPercent` and `samplingSeconds` are ignored
|
|
15177
|
-
*
|
|
15178
|
-
*
|
|
15179
|
-
*
|
|
15213
|
+
* - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
|
|
15214
|
+
* labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
|
|
15215
|
+
* `hitPercent` and `samplingSeconds` are still ignored — a percentage of
|
|
15216
|
+
* frames is the wrong question for a classifier that labels 1–3 frames
|
|
15217
|
+
* per episode. The count window is the brake that drops a single-frame
|
|
15218
|
+
* false positive; the rule's own `throttle` cooldown is the other. The
|
|
15219
|
+
* per-label confidence floor is the analyzer's (`classificationMinScore`,
|
|
15220
|
+
* per device) — a label only reaches this condition if the classifier was
|
|
15221
|
+
* already confident enough. `confirmHits: 1` restores first-frame fire.
|
|
15180
15222
|
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
15181
15223
|
* the condition: at least `hitPercent`% of the samples over
|
|
15182
15224
|
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
@@ -15203,14 +15245,22 @@ var NcOccupancyConditionSchema = object({
|
|
|
15203
15245
|
* an operator who typed `dog` mean the same thing.
|
|
15204
15246
|
*/
|
|
15205
15247
|
var NcAudioConditionSchema = object({
|
|
15206
|
-
/** LABEL MODE: audio macro labels. Present ⇒
|
|
15248
|
+
/** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
|
|
15207
15249
|
labels: array(string().min(1)).min(1).optional(),
|
|
15208
15250
|
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
15209
15251
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
15210
15252
|
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
15211
15253
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
15212
15254
|
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
15213
|
-
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
15255
|
+
samplingSeconds: number().int().min(1).max(300).default(10),
|
|
15256
|
+
/**
|
|
15257
|
+
* LABEL MODE: how many labelled frames must land inside
|
|
15258
|
+
* {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
|
|
15259
|
+
* Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
|
|
15260
|
+
*/
|
|
15261
|
+
confirmHits: number().int().min(1).max(20).optional(),
|
|
15262
|
+
/** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
|
|
15263
|
+
confirmWindowSec: number().int().min(1).max(60).optional()
|
|
15214
15264
|
});
|
|
15215
15265
|
/**
|
|
15216
15266
|
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
@@ -17584,6 +17634,46 @@ var RecentTracksPageSchema = object({
|
|
|
17584
17634
|
/** Cursor for the next page, or null when this page is the last. */
|
|
17585
17635
|
nextCursor: string().nullable()
|
|
17586
17636
|
});
|
|
17637
|
+
var LIST_GROUPS_DEFAULT_LIMIT = 40;
|
|
17638
|
+
var LIST_GROUPS_MAX_LIMIT = 100;
|
|
17639
|
+
var AnalyticsGroupRecordSchema = object({
|
|
17640
|
+
id: string(),
|
|
17641
|
+
deviceId: number().int(),
|
|
17642
|
+
openedAt: number().int(),
|
|
17643
|
+
closedAt: number().int(),
|
|
17644
|
+
timestamp: number().int(),
|
|
17645
|
+
memberCount: number().int(),
|
|
17646
|
+
memberTrackIds: array(string()).readonly(),
|
|
17647
|
+
className: string(),
|
|
17648
|
+
classes: array(string()).readonly(),
|
|
17649
|
+
/** Relative event-media path, or null when the group has no picture yet. */
|
|
17650
|
+
mediaUrl: string().nullable(),
|
|
17651
|
+
singleton: boolean()
|
|
17652
|
+
});
|
|
17653
|
+
var AnalyticsGroupMemberSchema = object({
|
|
17654
|
+
trackId: string(),
|
|
17655
|
+
deviceId: number().int(),
|
|
17656
|
+
className: string(),
|
|
17657
|
+
firstSeen: number().int(),
|
|
17658
|
+
lastSeen: number().int(),
|
|
17659
|
+
mediaUrl: string().nullable()
|
|
17660
|
+
});
|
|
17661
|
+
var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
|
|
17662
|
+
var ListGroupsQueryInput = object({
|
|
17663
|
+
/** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
|
|
17664
|
+
deviceIds: array(number()),
|
|
17665
|
+
/** Window lower bound on `closedAt` (inclusive). */
|
|
17666
|
+
since: number().optional(),
|
|
17667
|
+
/** Window upper bound on `openedAt` (inclusive). */
|
|
17668
|
+
until: number().optional(),
|
|
17669
|
+
limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
|
|
17670
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
17671
|
+
cursor: string().optional()
|
|
17672
|
+
});
|
|
17673
|
+
var ListGroupsPageSchema = object({
|
|
17674
|
+
groups: array(AnalyticsGroupRecordSchema).readonly(),
|
|
17675
|
+
nextCursor: string().nullable()
|
|
17676
|
+
});
|
|
17587
17677
|
var KeyEventQueryInput = object({
|
|
17588
17678
|
deviceId: number(),
|
|
17589
17679
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -17659,7 +17749,9 @@ var TrackCascadeCountsSchema = object({
|
|
|
17659
17749
|
/** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
|
|
17660
17750
|
plates: number().int(),
|
|
17661
17751
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
17662
|
-
embeddings: number().int()
|
|
17752
|
+
embeddings: number().int(),
|
|
17753
|
+
/** Group membership + group rows removed with their last member (best-effort). */
|
|
17754
|
+
groups: number().int()
|
|
17663
17755
|
});
|
|
17664
17756
|
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
17665
17757
|
var DiskReconcileCountsSchema = object({
|
|
@@ -17805,7 +17897,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17805
17897
|
* stationary registry). Default false: the timeline lists passages,
|
|
17806
17898
|
* not parking records (operator decision, 2026-08-15). */
|
|
17807
17899
|
includeStationary: boolean().optional()
|
|
17808
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
17900
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
|
|
17901
|
+
deviceId: number(),
|
|
17902
|
+
groupId: string().min(1)
|
|
17903
|
+
}), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
17809
17904
|
kind: "mutation",
|
|
17810
17905
|
auth: "admin"
|
|
17811
17906
|
}), 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({
|
|
@@ -18115,7 +18210,8 @@ var PipelineModelOptionSchema = object({
|
|
|
18115
18210
|
sizeMB: number()
|
|
18116
18211
|
})),
|
|
18117
18212
|
group: ModelVariantGroupSchema.optional(),
|
|
18118
|
-
legacy: boolean().optional()
|
|
18213
|
+
legacy: boolean().optional(),
|
|
18214
|
+
provider: ModelProviderIdSchema.optional()
|
|
18119
18215
|
});
|
|
18120
18216
|
var ConfigFieldBridge = custom();
|
|
18121
18217
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -24747,7 +24843,12 @@ var PlateInfoSchema = object({
|
|
|
24747
24843
|
plateBbox: BoundingBoxSchema.optional(),
|
|
24748
24844
|
/** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
|
|
24749
24845
|
keyFrameMediaKey: string().optional(),
|
|
24750
|
-
base64: string().optional()
|
|
24846
|
+
base64: string().optional(),
|
|
24847
|
+
/**
|
|
24848
|
+
* Same crop as a data-plane URL. `getPlateByTrack` returns this and
|
|
24849
|
+
* never inlines JPEG; `listPlates` still inlines for the admin-ui.
|
|
24850
|
+
*/
|
|
24851
|
+
cropUrl: string().optional()
|
|
24751
24852
|
});
|
|
24752
24853
|
var MediaFileLiteSchema = object({
|
|
24753
24854
|
key: string(),
|
|
@@ -28412,6 +28513,12 @@ Object.freeze({
|
|
|
28412
28513
|
addonId: null,
|
|
28413
28514
|
access: "view"
|
|
28414
28515
|
},
|
|
28516
|
+
"deviceManager.getBindingsBatch": {
|
|
28517
|
+
capName: "device-manager",
|
|
28518
|
+
capScope: "system",
|
|
28519
|
+
addonId: null,
|
|
28520
|
+
access: "view"
|
|
28521
|
+
},
|
|
28415
28522
|
"deviceManager.getChildren": {
|
|
28416
28523
|
capName: "device-manager",
|
|
28417
28524
|
capScope: "system",
|
|
@@ -28472,6 +28579,12 @@ Object.freeze({
|
|
|
28472
28579
|
addonId: null,
|
|
28473
28580
|
access: "view"
|
|
28474
28581
|
},
|
|
28582
|
+
"deviceManager.getLinkedDevicesBatch": {
|
|
28583
|
+
capName: "device-manager",
|
|
28584
|
+
capScope: "system",
|
|
28585
|
+
addonId: null,
|
|
28586
|
+
access: "view"
|
|
28587
|
+
},
|
|
28475
28588
|
"deviceManager.getRoleDisplayDefaults": {
|
|
28476
28589
|
capName: "device-manager",
|
|
28477
28590
|
capScope: "system",
|
|
@@ -30242,6 +30355,12 @@ Object.freeze({
|
|
|
30242
30355
|
addonId: null,
|
|
30243
30356
|
access: "view"
|
|
30244
30357
|
},
|
|
30358
|
+
"pipelineAnalytics.getGroup": {
|
|
30359
|
+
capName: "pipeline-analytics",
|
|
30360
|
+
capScope: "device",
|
|
30361
|
+
addonId: null,
|
|
30362
|
+
access: "view"
|
|
30363
|
+
},
|
|
30245
30364
|
"pipelineAnalytics.getKeyEvents": {
|
|
30246
30365
|
capName: "pipeline-analytics",
|
|
30247
30366
|
capScope: "device",
|
|
@@ -30326,6 +30445,12 @@ Object.freeze({
|
|
|
30326
30445
|
addonId: null,
|
|
30327
30446
|
access: "view"
|
|
30328
30447
|
},
|
|
30448
|
+
"pipelineAnalytics.listGroups": {
|
|
30449
|
+
capName: "pipeline-analytics",
|
|
30450
|
+
capScope: "device",
|
|
30451
|
+
addonId: null,
|
|
30452
|
+
access: "view"
|
|
30453
|
+
},
|
|
30329
30454
|
"pipelineAnalytics.listOpsLog": {
|
|
30330
30455
|
capName: "pipeline-analytics",
|
|
30331
30456
|
capScope: "device",
|
|
@@ -33107,6 +33232,11 @@ Object.freeze({
|
|
|
33107
33232
|
form: "single",
|
|
33108
33233
|
optional: false
|
|
33109
33234
|
}],
|
|
33235
|
+
"deviceManager.getBindingsBatch": [{
|
|
33236
|
+
name: "deviceIds",
|
|
33237
|
+
form: "array",
|
|
33238
|
+
optional: false
|
|
33239
|
+
}],
|
|
33110
33240
|
"deviceManager.getChildren": [{
|
|
33111
33241
|
name: "parentDeviceId",
|
|
33112
33242
|
form: "single",
|
|
@@ -33152,6 +33282,11 @@ Object.freeze({
|
|
|
33152
33282
|
form: "single",
|
|
33153
33283
|
optional: false
|
|
33154
33284
|
}],
|
|
33285
|
+
"deviceManager.getLinkedDevicesBatch": [{
|
|
33286
|
+
name: "deviceIds",
|
|
33287
|
+
form: "array",
|
|
33288
|
+
optional: false
|
|
33289
|
+
}],
|
|
33155
33290
|
"deviceManager.getSettingsSchema": [{
|
|
33156
33291
|
name: "deviceId",
|
|
33157
33292
|
form: "single",
|
|
@@ -33172,6 +33307,11 @@ Object.freeze({
|
|
|
33172
33307
|
form: "single",
|
|
33173
33308
|
optional: false
|
|
33174
33309
|
}],
|
|
33310
|
+
"deviceManager.listAll": [{
|
|
33311
|
+
name: "deviceIds",
|
|
33312
|
+
form: "array",
|
|
33313
|
+
optional: true
|
|
33314
|
+
}],
|
|
33175
33315
|
"deviceManager.loadConfig": [{
|
|
33176
33316
|
name: "deviceId",
|
|
33177
33317
|
form: "single",
|
|
@@ -33745,6 +33885,11 @@ Object.freeze({
|
|
|
33745
33885
|
form: "single",
|
|
33746
33886
|
optional: false
|
|
33747
33887
|
}],
|
|
33888
|
+
"pipelineAnalytics.getGroup": [{
|
|
33889
|
+
name: "deviceId",
|
|
33890
|
+
form: "single",
|
|
33891
|
+
optional: false
|
|
33892
|
+
}],
|
|
33748
33893
|
"pipelineAnalytics.getKeyEvents": [{
|
|
33749
33894
|
name: "deviceId",
|
|
33750
33895
|
form: "single",
|
|
@@ -33800,6 +33945,11 @@ Object.freeze({
|
|
|
33800
33945
|
form: "array",
|
|
33801
33946
|
optional: false
|
|
33802
33947
|
}],
|
|
33948
|
+
"pipelineAnalytics.listGroups": [{
|
|
33949
|
+
name: "deviceIds",
|
|
33950
|
+
form: "array",
|
|
33951
|
+
optional: false
|
|
33952
|
+
}],
|
|
33803
33953
|
"pipelineAnalytics.listOpsLog": [{
|
|
33804
33954
|
name: "deviceId",
|
|
33805
33955
|
form: "single",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-export-hap",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.39",
|
|
4
4
|
"description": "HomeKit (HAP) exporter for CamStack devices. Publishes each exposed device as its own HomeKit accessory: cameras and doorbells with SRTP streaming, HomeKit Secure Video, motion, two-way audio, PTZ and battery; switches, lights, locks and sensors through a capability→service table.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|