@camstack/addon-provider-unraid 0.2.27 → 0.2.28
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/addon.js +184 -34
- package/dist/addon.mjs +184 -34
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -5801,6 +5801,13 @@ var BaseAddon = class {
|
|
|
5801
5801
|
_readinessGeneration = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2, 14);
|
|
5802
5802
|
/** Capability names this addon registered at init — used to emit matching `down` events on shutdown. */
|
|
5803
5803
|
_registeredCapNames = [];
|
|
5804
|
+
/**
|
|
5805
|
+
* True only after `readAddonStore` actually answered. Constructor
|
|
5806
|
+
* defaults look like stored config when the store is down — a forked
|
|
5807
|
+
* addon that auto-starts from those defaults (cloudflare-tunnel quick
|
|
5808
|
+
* mode, 2026-08-25) is not "the operator chose this".
|
|
5809
|
+
*/
|
|
5810
|
+
settingsStoreReady = false;
|
|
5804
5811
|
/** Default config values. Provided via constructor. */
|
|
5805
5812
|
defaults;
|
|
5806
5813
|
constructor(defaults) {
|
|
@@ -6201,7 +6208,9 @@ var BaseAddon = class {
|
|
|
6201
6208
|
];
|
|
6202
6209
|
let lastErr;
|
|
6203
6210
|
for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
|
|
6204
|
-
|
|
6211
|
+
const stored = await settings.readAddonStore() ?? {};
|
|
6212
|
+
this.settingsStoreReady = true;
|
|
6213
|
+
return stored;
|
|
6205
6214
|
} catch (err) {
|
|
6206
6215
|
lastErr = err;
|
|
6207
6216
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -6209,6 +6218,7 @@ var BaseAddon = class {
|
|
|
6209
6218
|
if (attempt === delaysMs.length) break;
|
|
6210
6219
|
await new Promise((r) => setTimeout(r, delaysMs[attempt]));
|
|
6211
6220
|
}
|
|
6221
|
+
this.settingsStoreReady = false;
|
|
6212
6222
|
this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
|
|
6213
6223
|
return {};
|
|
6214
6224
|
}
|
|
@@ -8112,6 +8122,12 @@ var ModelVariantGroupSchema = object({
|
|
|
8112
8122
|
*/
|
|
8113
8123
|
resolution: number().int().positive().optional()
|
|
8114
8124
|
});
|
|
8125
|
+
var ModelProviderIdSchema = _enum([
|
|
8126
|
+
"camstack",
|
|
8127
|
+
"frigate",
|
|
8128
|
+
"scrypted",
|
|
8129
|
+
"custom"
|
|
8130
|
+
]);
|
|
8115
8131
|
var ModelCatalogEntrySchema = object({
|
|
8116
8132
|
id: string(),
|
|
8117
8133
|
name: string(),
|
|
@@ -8209,6 +8225,12 @@ var ModelCatalogEntrySchema = object({
|
|
|
8209
8225
|
*/
|
|
8210
8226
|
group: ModelVariantGroupSchema.optional(),
|
|
8211
8227
|
/**
|
|
8228
|
+
* Catalog source for the pipeline stepper's provider-first picker. Absent on
|
|
8229
|
+
* built-in CamStack entries (treated as `camstack`) and on registry rows
|
|
8230
|
+
* persisted before this field existed (`inferModelProvider` fills those).
|
|
8231
|
+
*/
|
|
8232
|
+
provider: ModelProviderIdSchema.optional(),
|
|
8233
|
+
/**
|
|
8212
8234
|
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
8213
8235
|
* applies (Frigate / COCO public catalog). Set on a custom model whose raw
|
|
8214
8236
|
* labels already ARE the CamStack macros (Scrypted identity map).
|
|
@@ -12000,6 +12022,27 @@ var LinkedDeviceSchema = object({
|
|
|
12000
12022
|
features: array(string()),
|
|
12001
12023
|
producesTrackedEvents: boolean().optional()
|
|
12002
12024
|
});
|
|
12025
|
+
/** One camera's resolved linked set, tagged with the camera it belongs to.
|
|
12026
|
+
* The batch answer needs the tag; the single-device answer already has it
|
|
12027
|
+
* from the input, which is why `getLinkedDevices` keeps the untagged shape. */
|
|
12028
|
+
var LinkedDevicesForDeviceSchema = object({
|
|
12029
|
+
deviceId: number(),
|
|
12030
|
+
mode: LinkedDevicesModeSchema,
|
|
12031
|
+
devices: array(LinkedDeviceSchema)
|
|
12032
|
+
});
|
|
12033
|
+
/** One device's binding map — the shape `getBindings`, `getBindingsBatch` and
|
|
12034
|
+
* `getAllBindings` all answer in. Declared once: three copies of the same
|
|
12035
|
+
* object literal is exactly how the three drift apart. */
|
|
12036
|
+
var DeviceBindingsForDeviceSchema = object({
|
|
12037
|
+
deviceId: number(),
|
|
12038
|
+
entries: array(object({
|
|
12039
|
+
capName: string(),
|
|
12040
|
+
kind: _enum(["native", "wrapped"]),
|
|
12041
|
+
providerAddonId: string(),
|
|
12042
|
+
providerNodeId: string(),
|
|
12043
|
+
nativeAddonId: string()
|
|
12044
|
+
}))
|
|
12045
|
+
});
|
|
12003
12046
|
var SavedDeviceRowSchema = object({
|
|
12004
12047
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
12005
12048
|
id: number(),
|
|
@@ -12225,11 +12268,25 @@ method(object({
|
|
|
12225
12268
|
projection: _enum(["full", "slim"]).optional(),
|
|
12226
12269
|
/** Return only camera devices. Filtering server-side instead of
|
|
12227
12270
|
* shipping 293 rows to find 12. */
|
|
12228
|
-
isCamera: boolean().optional()
|
|
12271
|
+
isCamera: boolean().optional(),
|
|
12272
|
+
/**
|
|
12273
|
+
* Return only these device ids. For the caller that already KNOWS the
|
|
12274
|
+
* handful it wants and needs a field the id-bearing answer does not
|
|
12275
|
+
* carry — the viewer's linked-devices panel joins `type` and `online`
|
|
12276
|
+
* onto ~8 linked ids and, unfiltered, dragged the fleet across to do
|
|
12277
|
+
* it: 433 KB slim / 958 KB full for 967 devices, on a query that
|
|
12278
|
+
* refetches on the reconcile interval, on a phone.
|
|
12279
|
+
*
|
|
12280
|
+
* Safe to send at a hub that predates it: Zod STRIPS unknown input
|
|
12281
|
+
* keys rather than rejecting them (verified against the live hub
|
|
12282
|
+
* 2026-08-25 — 967 rows came back), so an old hub answers exactly what
|
|
12283
|
+
* it answers today and the caller filters as it already does.
|
|
12284
|
+
*/
|
|
12285
|
+
deviceIds: array(number()).optional()
|
|
12229
12286
|
}), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
12230
12287
|
mode: LinkedDevicesModeSchema,
|
|
12231
12288
|
devices: array(LinkedDeviceSchema)
|
|
12232
|
-
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
12289
|
+
})), 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({
|
|
12233
12290
|
deviceId: number(),
|
|
12234
12291
|
values: record(string(), unknown())
|
|
12235
12292
|
}), object({ success: literal(true) }), {
|
|
@@ -12256,25 +12313,7 @@ method(object({
|
|
|
12256
12313
|
}), method(object({ deviceId: number() }), array(StreamProbeResultSchema), {
|
|
12257
12314
|
kind: "mutation",
|
|
12258
12315
|
auth: "admin"
|
|
12259
|
-
}), method(object({ deviceId: number() }), object({
|
|
12260
|
-
deviceId: number(),
|
|
12261
|
-
entries: array(object({
|
|
12262
|
-
capName: string(),
|
|
12263
|
-
kind: _enum(["native", "wrapped"]),
|
|
12264
|
-
providerAddonId: string(),
|
|
12265
|
-
providerNodeId: string(),
|
|
12266
|
-
nativeAddonId: string()
|
|
12267
|
-
}))
|
|
12268
|
-
})), method(object({}), array(object({
|
|
12269
|
-
deviceId: number(),
|
|
12270
|
-
entries: array(object({
|
|
12271
|
-
capName: string(),
|
|
12272
|
-
kind: _enum(["native", "wrapped"]),
|
|
12273
|
-
providerAddonId: string(),
|
|
12274
|
-
providerNodeId: string(),
|
|
12275
|
-
nativeAddonId: string()
|
|
12276
|
-
}))
|
|
12277
|
-
}))), method(object({
|
|
12316
|
+
}), method(object({ deviceId: number() }), DeviceBindingsForDeviceSchema), method(object({ deviceIds: array(number()) }), array(DeviceBindingsForDeviceSchema)), method(object({}), array(DeviceBindingsForDeviceSchema)), method(object({
|
|
12278
12317
|
deviceId: number(),
|
|
12279
12318
|
capName: string(),
|
|
12280
12319
|
wrapperAddonId: string(),
|
|
@@ -14684,12 +14723,15 @@ var NcOccupancyConditionSchema = object({
|
|
|
14684
14723
|
* there is no second switch that can disagree with the first and every rule
|
|
14685
14724
|
* authored before the decision migrates for free (`audioModeOf`):
|
|
14686
14725
|
*
|
|
14687
|
-
* - **LABEL mode — `labels` present.** The rule fires
|
|
14688
|
-
*
|
|
14689
|
-
* `hitPercent` and `samplingSeconds` are ignored
|
|
14690
|
-
*
|
|
14691
|
-
*
|
|
14692
|
-
*
|
|
14726
|
+
* - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
|
|
14727
|
+
* labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
|
|
14728
|
+
* `hitPercent` and `samplingSeconds` are still ignored — a percentage of
|
|
14729
|
+
* frames is the wrong question for a classifier that labels 1–3 frames
|
|
14730
|
+
* per episode. The count window is the brake that drops a single-frame
|
|
14731
|
+
* false positive; the rule's own `throttle` cooldown is the other. The
|
|
14732
|
+
* per-label confidence floor is the analyzer's (`classificationMinScore`,
|
|
14733
|
+
* per device) — a label only reaches this condition if the classifier was
|
|
14734
|
+
* already confident enough. `confirmHits: 1` restores first-frame fire.
|
|
14693
14735
|
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
14694
14736
|
* the condition: at least `hitPercent`% of the samples over
|
|
14695
14737
|
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
@@ -14716,14 +14758,22 @@ var NcOccupancyConditionSchema = object({
|
|
|
14716
14758
|
* an operator who typed `dog` mean the same thing.
|
|
14717
14759
|
*/
|
|
14718
14760
|
var NcAudioConditionSchema = object({
|
|
14719
|
-
/** LABEL MODE: audio macro labels. Present ⇒
|
|
14761
|
+
/** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
|
|
14720
14762
|
labels: array(string().min(1)).min(1).optional(),
|
|
14721
14763
|
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
14722
14764
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
14723
14765
|
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
14724
14766
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
14725
14767
|
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
14726
|
-
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
14768
|
+
samplingSeconds: number().int().min(1).max(300).default(10),
|
|
14769
|
+
/**
|
|
14770
|
+
* LABEL MODE: how many labelled frames must land inside
|
|
14771
|
+
* {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
|
|
14772
|
+
* Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
|
|
14773
|
+
*/
|
|
14774
|
+
confirmHits: number().int().min(1).max(20).optional(),
|
|
14775
|
+
/** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
|
|
14776
|
+
confirmWindowSec: number().int().min(1).max(60).optional()
|
|
14727
14777
|
});
|
|
14728
14778
|
/**
|
|
14729
14779
|
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
@@ -17097,6 +17147,46 @@ var RecentTracksPageSchema = object({
|
|
|
17097
17147
|
/** Cursor for the next page, or null when this page is the last. */
|
|
17098
17148
|
nextCursor: string().nullable()
|
|
17099
17149
|
});
|
|
17150
|
+
var LIST_GROUPS_DEFAULT_LIMIT = 40;
|
|
17151
|
+
var LIST_GROUPS_MAX_LIMIT = 100;
|
|
17152
|
+
var AnalyticsGroupRecordSchema = object({
|
|
17153
|
+
id: string(),
|
|
17154
|
+
deviceId: number().int(),
|
|
17155
|
+
openedAt: number().int(),
|
|
17156
|
+
closedAt: number().int(),
|
|
17157
|
+
timestamp: number().int(),
|
|
17158
|
+
memberCount: number().int(),
|
|
17159
|
+
memberTrackIds: array(string()).readonly(),
|
|
17160
|
+
className: string(),
|
|
17161
|
+
classes: array(string()).readonly(),
|
|
17162
|
+
/** Relative event-media path, or null when the group has no picture yet. */
|
|
17163
|
+
mediaUrl: string().nullable(),
|
|
17164
|
+
singleton: boolean()
|
|
17165
|
+
});
|
|
17166
|
+
var AnalyticsGroupMemberSchema = object({
|
|
17167
|
+
trackId: string(),
|
|
17168
|
+
deviceId: number().int(),
|
|
17169
|
+
className: string(),
|
|
17170
|
+
firstSeen: number().int(),
|
|
17171
|
+
lastSeen: number().int(),
|
|
17172
|
+
mediaUrl: string().nullable()
|
|
17173
|
+
});
|
|
17174
|
+
var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
|
|
17175
|
+
var ListGroupsQueryInput = object({
|
|
17176
|
+
/** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
|
|
17177
|
+
deviceIds: array(number()),
|
|
17178
|
+
/** Window lower bound on `closedAt` (inclusive). */
|
|
17179
|
+
since: number().optional(),
|
|
17180
|
+
/** Window upper bound on `openedAt` (inclusive). */
|
|
17181
|
+
until: number().optional(),
|
|
17182
|
+
limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
|
|
17183
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
17184
|
+
cursor: string().optional()
|
|
17185
|
+
});
|
|
17186
|
+
var ListGroupsPageSchema = object({
|
|
17187
|
+
groups: array(AnalyticsGroupRecordSchema).readonly(),
|
|
17188
|
+
nextCursor: string().nullable()
|
|
17189
|
+
});
|
|
17100
17190
|
var KeyEventQueryInput = object({
|
|
17101
17191
|
deviceId: number(),
|
|
17102
17192
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -17172,7 +17262,9 @@ var TrackCascadeCountsSchema = object({
|
|
|
17172
17262
|
/** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
|
|
17173
17263
|
plates: number().int(),
|
|
17174
17264
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
17175
|
-
embeddings: number().int()
|
|
17265
|
+
embeddings: number().int(),
|
|
17266
|
+
/** Group membership + group rows removed with their last member (best-effort). */
|
|
17267
|
+
groups: number().int()
|
|
17176
17268
|
});
|
|
17177
17269
|
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
17178
17270
|
var DiskReconcileCountsSchema = object({
|
|
@@ -17318,7 +17410,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17318
17410
|
* stationary registry). Default false: the timeline lists passages,
|
|
17319
17411
|
* not parking records (operator decision, 2026-08-15). */
|
|
17320
17412
|
includeStationary: boolean().optional()
|
|
17321
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
17413
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
|
|
17414
|
+
deviceId: number(),
|
|
17415
|
+
groupId: string().min(1)
|
|
17416
|
+
}), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
17322
17417
|
kind: "mutation",
|
|
17323
17418
|
auth: "admin"
|
|
17324
17419
|
}), 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({
|
|
@@ -17628,7 +17723,8 @@ var PipelineModelOptionSchema = object({
|
|
|
17628
17723
|
sizeMB: number()
|
|
17629
17724
|
})),
|
|
17630
17725
|
group: ModelVariantGroupSchema.optional(),
|
|
17631
|
-
legacy: boolean().optional()
|
|
17726
|
+
legacy: boolean().optional(),
|
|
17727
|
+
provider: ModelProviderIdSchema.optional()
|
|
17632
17728
|
});
|
|
17633
17729
|
var ConfigFieldBridge = custom();
|
|
17634
17730
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -25742,7 +25838,12 @@ var PlateInfoSchema = object({
|
|
|
25742
25838
|
plateBbox: BoundingBoxSchema.optional(),
|
|
25743
25839
|
/** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
|
|
25744
25840
|
keyFrameMediaKey: string().optional(),
|
|
25745
|
-
base64: string().optional()
|
|
25841
|
+
base64: string().optional(),
|
|
25842
|
+
/**
|
|
25843
|
+
* Same crop as a data-plane URL. `getPlateByTrack` returns this and
|
|
25844
|
+
* never inlines JPEG; `listPlates` still inlines for the admin-ui.
|
|
25845
|
+
*/
|
|
25846
|
+
cropUrl: string().optional()
|
|
25746
25847
|
});
|
|
25747
25848
|
var MediaFileLiteSchema = object({
|
|
25748
25849
|
key: string(),
|
|
@@ -31266,6 +31367,12 @@ Object.freeze({
|
|
|
31266
31367
|
addonId: null,
|
|
31267
31368
|
access: "view"
|
|
31268
31369
|
},
|
|
31370
|
+
"deviceManager.getBindingsBatch": {
|
|
31371
|
+
capName: "device-manager",
|
|
31372
|
+
capScope: "system",
|
|
31373
|
+
addonId: null,
|
|
31374
|
+
access: "view"
|
|
31375
|
+
},
|
|
31269
31376
|
"deviceManager.getChildren": {
|
|
31270
31377
|
capName: "device-manager",
|
|
31271
31378
|
capScope: "system",
|
|
@@ -31326,6 +31433,12 @@ Object.freeze({
|
|
|
31326
31433
|
addonId: null,
|
|
31327
31434
|
access: "view"
|
|
31328
31435
|
},
|
|
31436
|
+
"deviceManager.getLinkedDevicesBatch": {
|
|
31437
|
+
capName: "device-manager",
|
|
31438
|
+
capScope: "system",
|
|
31439
|
+
addonId: null,
|
|
31440
|
+
access: "view"
|
|
31441
|
+
},
|
|
31329
31442
|
"deviceManager.getRoleDisplayDefaults": {
|
|
31330
31443
|
capName: "device-manager",
|
|
31331
31444
|
capScope: "system",
|
|
@@ -33096,6 +33209,12 @@ Object.freeze({
|
|
|
33096
33209
|
addonId: null,
|
|
33097
33210
|
access: "view"
|
|
33098
33211
|
},
|
|
33212
|
+
"pipelineAnalytics.getGroup": {
|
|
33213
|
+
capName: "pipeline-analytics",
|
|
33214
|
+
capScope: "device",
|
|
33215
|
+
addonId: null,
|
|
33216
|
+
access: "view"
|
|
33217
|
+
},
|
|
33099
33218
|
"pipelineAnalytics.getKeyEvents": {
|
|
33100
33219
|
capName: "pipeline-analytics",
|
|
33101
33220
|
capScope: "device",
|
|
@@ -33180,6 +33299,12 @@ Object.freeze({
|
|
|
33180
33299
|
addonId: null,
|
|
33181
33300
|
access: "view"
|
|
33182
33301
|
},
|
|
33302
|
+
"pipelineAnalytics.listGroups": {
|
|
33303
|
+
capName: "pipeline-analytics",
|
|
33304
|
+
capScope: "device",
|
|
33305
|
+
addonId: null,
|
|
33306
|
+
access: "view"
|
|
33307
|
+
},
|
|
33183
33308
|
"pipelineAnalytics.listOpsLog": {
|
|
33184
33309
|
capName: "pipeline-analytics",
|
|
33185
33310
|
capScope: "device",
|
|
@@ -35961,6 +36086,11 @@ Object.freeze({
|
|
|
35961
36086
|
form: "single",
|
|
35962
36087
|
optional: false
|
|
35963
36088
|
}],
|
|
36089
|
+
"deviceManager.getBindingsBatch": [{
|
|
36090
|
+
name: "deviceIds",
|
|
36091
|
+
form: "array",
|
|
36092
|
+
optional: false
|
|
36093
|
+
}],
|
|
35964
36094
|
"deviceManager.getChildren": [{
|
|
35965
36095
|
name: "parentDeviceId",
|
|
35966
36096
|
form: "single",
|
|
@@ -36006,6 +36136,11 @@ Object.freeze({
|
|
|
36006
36136
|
form: "single",
|
|
36007
36137
|
optional: false
|
|
36008
36138
|
}],
|
|
36139
|
+
"deviceManager.getLinkedDevicesBatch": [{
|
|
36140
|
+
name: "deviceIds",
|
|
36141
|
+
form: "array",
|
|
36142
|
+
optional: false
|
|
36143
|
+
}],
|
|
36009
36144
|
"deviceManager.getSettingsSchema": [{
|
|
36010
36145
|
name: "deviceId",
|
|
36011
36146
|
form: "single",
|
|
@@ -36026,6 +36161,11 @@ Object.freeze({
|
|
|
36026
36161
|
form: "single",
|
|
36027
36162
|
optional: false
|
|
36028
36163
|
}],
|
|
36164
|
+
"deviceManager.listAll": [{
|
|
36165
|
+
name: "deviceIds",
|
|
36166
|
+
form: "array",
|
|
36167
|
+
optional: true
|
|
36168
|
+
}],
|
|
36029
36169
|
"deviceManager.loadConfig": [{
|
|
36030
36170
|
name: "deviceId",
|
|
36031
36171
|
form: "single",
|
|
@@ -36599,6 +36739,11 @@ Object.freeze({
|
|
|
36599
36739
|
form: "single",
|
|
36600
36740
|
optional: false
|
|
36601
36741
|
}],
|
|
36742
|
+
"pipelineAnalytics.getGroup": [{
|
|
36743
|
+
name: "deviceId",
|
|
36744
|
+
form: "single",
|
|
36745
|
+
optional: false
|
|
36746
|
+
}],
|
|
36602
36747
|
"pipelineAnalytics.getKeyEvents": [{
|
|
36603
36748
|
name: "deviceId",
|
|
36604
36749
|
form: "single",
|
|
@@ -36654,6 +36799,11 @@ Object.freeze({
|
|
|
36654
36799
|
form: "array",
|
|
36655
36800
|
optional: false
|
|
36656
36801
|
}],
|
|
36802
|
+
"pipelineAnalytics.listGroups": [{
|
|
36803
|
+
name: "deviceIds",
|
|
36804
|
+
form: "array",
|
|
36805
|
+
optional: false
|
|
36806
|
+
}],
|
|
36657
36807
|
"pipelineAnalytics.listOpsLog": [{
|
|
36658
36808
|
name: "deviceId",
|
|
36659
36809
|
form: "single",
|
package/dist/addon.mjs
CHANGED
|
@@ -5800,6 +5800,13 @@ var BaseAddon = class {
|
|
|
5800
5800
|
_readinessGeneration = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2, 14);
|
|
5801
5801
|
/** Capability names this addon registered at init — used to emit matching `down` events on shutdown. */
|
|
5802
5802
|
_registeredCapNames = [];
|
|
5803
|
+
/**
|
|
5804
|
+
* True only after `readAddonStore` actually answered. Constructor
|
|
5805
|
+
* defaults look like stored config when the store is down — a forked
|
|
5806
|
+
* addon that auto-starts from those defaults (cloudflare-tunnel quick
|
|
5807
|
+
* mode, 2026-08-25) is not "the operator chose this".
|
|
5808
|
+
*/
|
|
5809
|
+
settingsStoreReady = false;
|
|
5803
5810
|
/** Default config values. Provided via constructor. */
|
|
5804
5811
|
defaults;
|
|
5805
5812
|
constructor(defaults) {
|
|
@@ -6200,7 +6207,9 @@ var BaseAddon = class {
|
|
|
6200
6207
|
];
|
|
6201
6208
|
let lastErr;
|
|
6202
6209
|
for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
|
|
6203
|
-
|
|
6210
|
+
const stored = await settings.readAddonStore() ?? {};
|
|
6211
|
+
this.settingsStoreReady = true;
|
|
6212
|
+
return stored;
|
|
6204
6213
|
} catch (err) {
|
|
6205
6214
|
lastErr = err;
|
|
6206
6215
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -6208,6 +6217,7 @@ var BaseAddon = class {
|
|
|
6208
6217
|
if (attempt === delaysMs.length) break;
|
|
6209
6218
|
await new Promise((r) => setTimeout(r, delaysMs[attempt]));
|
|
6210
6219
|
}
|
|
6220
|
+
this.settingsStoreReady = false;
|
|
6211
6221
|
this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
|
|
6212
6222
|
return {};
|
|
6213
6223
|
}
|
|
@@ -8111,6 +8121,12 @@ var ModelVariantGroupSchema = object({
|
|
|
8111
8121
|
*/
|
|
8112
8122
|
resolution: number().int().positive().optional()
|
|
8113
8123
|
});
|
|
8124
|
+
var ModelProviderIdSchema = _enum([
|
|
8125
|
+
"camstack",
|
|
8126
|
+
"frigate",
|
|
8127
|
+
"scrypted",
|
|
8128
|
+
"custom"
|
|
8129
|
+
]);
|
|
8114
8130
|
var ModelCatalogEntrySchema = object({
|
|
8115
8131
|
id: string(),
|
|
8116
8132
|
name: string(),
|
|
@@ -8208,6 +8224,12 @@ var ModelCatalogEntrySchema = object({
|
|
|
8208
8224
|
*/
|
|
8209
8225
|
group: ModelVariantGroupSchema.optional(),
|
|
8210
8226
|
/**
|
|
8227
|
+
* Catalog source for the pipeline stepper's provider-first picker. Absent on
|
|
8228
|
+
* built-in CamStack entries (treated as `camstack`) and on registry rows
|
|
8229
|
+
* persisted before this field existed (`inferModelProvider` fills those).
|
|
8230
|
+
*/
|
|
8231
|
+
provider: ModelProviderIdSchema.optional(),
|
|
8232
|
+
/**
|
|
8211
8233
|
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
8212
8234
|
* applies (Frigate / COCO public catalog). Set on a custom model whose raw
|
|
8213
8235
|
* labels already ARE the CamStack macros (Scrypted identity map).
|
|
@@ -11999,6 +12021,27 @@ var LinkedDeviceSchema = object({
|
|
|
11999
12021
|
features: array(string()),
|
|
12000
12022
|
producesTrackedEvents: boolean().optional()
|
|
12001
12023
|
});
|
|
12024
|
+
/** One camera's resolved linked set, tagged with the camera it belongs to.
|
|
12025
|
+
* The batch answer needs the tag; the single-device answer already has it
|
|
12026
|
+
* from the input, which is why `getLinkedDevices` keeps the untagged shape. */
|
|
12027
|
+
var LinkedDevicesForDeviceSchema = object({
|
|
12028
|
+
deviceId: number(),
|
|
12029
|
+
mode: LinkedDevicesModeSchema,
|
|
12030
|
+
devices: array(LinkedDeviceSchema)
|
|
12031
|
+
});
|
|
12032
|
+
/** One device's binding map — the shape `getBindings`, `getBindingsBatch` and
|
|
12033
|
+
* `getAllBindings` all answer in. Declared once: three copies of the same
|
|
12034
|
+
* object literal is exactly how the three drift apart. */
|
|
12035
|
+
var DeviceBindingsForDeviceSchema = object({
|
|
12036
|
+
deviceId: number(),
|
|
12037
|
+
entries: array(object({
|
|
12038
|
+
capName: string(),
|
|
12039
|
+
kind: _enum(["native", "wrapped"]),
|
|
12040
|
+
providerAddonId: string(),
|
|
12041
|
+
providerNodeId: string(),
|
|
12042
|
+
nativeAddonId: string()
|
|
12043
|
+
}))
|
|
12044
|
+
});
|
|
12002
12045
|
var SavedDeviceRowSchema = object({
|
|
12003
12046
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
12004
12047
|
id: number(),
|
|
@@ -12224,11 +12267,25 @@ method(object({
|
|
|
12224
12267
|
projection: _enum(["full", "slim"]).optional(),
|
|
12225
12268
|
/** Return only camera devices. Filtering server-side instead of
|
|
12226
12269
|
* shipping 293 rows to find 12. */
|
|
12227
|
-
isCamera: boolean().optional()
|
|
12270
|
+
isCamera: boolean().optional(),
|
|
12271
|
+
/**
|
|
12272
|
+
* Return only these device ids. For the caller that already KNOWS the
|
|
12273
|
+
* handful it wants and needs a field the id-bearing answer does not
|
|
12274
|
+
* carry — the viewer's linked-devices panel joins `type` and `online`
|
|
12275
|
+
* onto ~8 linked ids and, unfiltered, dragged the fleet across to do
|
|
12276
|
+
* it: 433 KB slim / 958 KB full for 967 devices, on a query that
|
|
12277
|
+
* refetches on the reconcile interval, on a phone.
|
|
12278
|
+
*
|
|
12279
|
+
* Safe to send at a hub that predates it: Zod STRIPS unknown input
|
|
12280
|
+
* keys rather than rejecting them (verified against the live hub
|
|
12281
|
+
* 2026-08-25 — 967 rows came back), so an old hub answers exactly what
|
|
12282
|
+
* it answers today and the caller filters as it already does.
|
|
12283
|
+
*/
|
|
12284
|
+
deviceIds: array(number()).optional()
|
|
12228
12285
|
}), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
12229
12286
|
mode: LinkedDevicesModeSchema,
|
|
12230
12287
|
devices: array(LinkedDeviceSchema)
|
|
12231
|
-
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
12288
|
+
})), 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({
|
|
12232
12289
|
deviceId: number(),
|
|
12233
12290
|
values: record(string(), unknown())
|
|
12234
12291
|
}), object({ success: literal(true) }), {
|
|
@@ -12255,25 +12312,7 @@ method(object({
|
|
|
12255
12312
|
}), method(object({ deviceId: number() }), array(StreamProbeResultSchema), {
|
|
12256
12313
|
kind: "mutation",
|
|
12257
12314
|
auth: "admin"
|
|
12258
|
-
}), method(object({ deviceId: number() }), object({
|
|
12259
|
-
deviceId: number(),
|
|
12260
|
-
entries: array(object({
|
|
12261
|
-
capName: string(),
|
|
12262
|
-
kind: _enum(["native", "wrapped"]),
|
|
12263
|
-
providerAddonId: string(),
|
|
12264
|
-
providerNodeId: string(),
|
|
12265
|
-
nativeAddonId: string()
|
|
12266
|
-
}))
|
|
12267
|
-
})), method(object({}), array(object({
|
|
12268
|
-
deviceId: number(),
|
|
12269
|
-
entries: array(object({
|
|
12270
|
-
capName: string(),
|
|
12271
|
-
kind: _enum(["native", "wrapped"]),
|
|
12272
|
-
providerAddonId: string(),
|
|
12273
|
-
providerNodeId: string(),
|
|
12274
|
-
nativeAddonId: string()
|
|
12275
|
-
}))
|
|
12276
|
-
}))), method(object({
|
|
12315
|
+
}), method(object({ deviceId: number() }), DeviceBindingsForDeviceSchema), method(object({ deviceIds: array(number()) }), array(DeviceBindingsForDeviceSchema)), method(object({}), array(DeviceBindingsForDeviceSchema)), method(object({
|
|
12277
12316
|
deviceId: number(),
|
|
12278
12317
|
capName: string(),
|
|
12279
12318
|
wrapperAddonId: string(),
|
|
@@ -14683,12 +14722,15 @@ var NcOccupancyConditionSchema = object({
|
|
|
14683
14722
|
* there is no second switch that can disagree with the first and every rule
|
|
14684
14723
|
* authored before the decision migrates for free (`audioModeOf`):
|
|
14685
14724
|
*
|
|
14686
|
-
* - **LABEL mode — `labels` present.** The rule fires
|
|
14687
|
-
*
|
|
14688
|
-
* `hitPercent` and `samplingSeconds` are ignored
|
|
14689
|
-
*
|
|
14690
|
-
*
|
|
14691
|
-
*
|
|
14725
|
+
* - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
|
|
14726
|
+
* labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
|
|
14727
|
+
* `hitPercent` and `samplingSeconds` are still ignored — a percentage of
|
|
14728
|
+
* frames is the wrong question for a classifier that labels 1–3 frames
|
|
14729
|
+
* per episode. The count window is the brake that drops a single-frame
|
|
14730
|
+
* false positive; the rule's own `throttle` cooldown is the other. The
|
|
14731
|
+
* per-label confidence floor is the analyzer's (`classificationMinScore`,
|
|
14732
|
+
* per device) — a label only reaches this condition if the classifier was
|
|
14733
|
+
* already confident enough. `confirmHits: 1` restores first-frame fire.
|
|
14692
14734
|
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
14693
14735
|
* the condition: at least `hitPercent`% of the samples over
|
|
14694
14736
|
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
@@ -14715,14 +14757,22 @@ var NcOccupancyConditionSchema = object({
|
|
|
14715
14757
|
* an operator who typed `dog` mean the same thing.
|
|
14716
14758
|
*/
|
|
14717
14759
|
var NcAudioConditionSchema = object({
|
|
14718
|
-
/** LABEL MODE: audio macro labels. Present ⇒
|
|
14760
|
+
/** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
|
|
14719
14761
|
labels: array(string().min(1)).min(1).optional(),
|
|
14720
14762
|
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
14721
14763
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
14722
14764
|
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
14723
14765
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
14724
14766
|
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
14725
|
-
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
14767
|
+
samplingSeconds: number().int().min(1).max(300).default(10),
|
|
14768
|
+
/**
|
|
14769
|
+
* LABEL MODE: how many labelled frames must land inside
|
|
14770
|
+
* {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
|
|
14771
|
+
* Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
|
|
14772
|
+
*/
|
|
14773
|
+
confirmHits: number().int().min(1).max(20).optional(),
|
|
14774
|
+
/** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
|
|
14775
|
+
confirmWindowSec: number().int().min(1).max(60).optional()
|
|
14726
14776
|
});
|
|
14727
14777
|
/**
|
|
14728
14778
|
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
@@ -17096,6 +17146,46 @@ var RecentTracksPageSchema = object({
|
|
|
17096
17146
|
/** Cursor for the next page, or null when this page is the last. */
|
|
17097
17147
|
nextCursor: string().nullable()
|
|
17098
17148
|
});
|
|
17149
|
+
var LIST_GROUPS_DEFAULT_LIMIT = 40;
|
|
17150
|
+
var LIST_GROUPS_MAX_LIMIT = 100;
|
|
17151
|
+
var AnalyticsGroupRecordSchema = object({
|
|
17152
|
+
id: string(),
|
|
17153
|
+
deviceId: number().int(),
|
|
17154
|
+
openedAt: number().int(),
|
|
17155
|
+
closedAt: number().int(),
|
|
17156
|
+
timestamp: number().int(),
|
|
17157
|
+
memberCount: number().int(),
|
|
17158
|
+
memberTrackIds: array(string()).readonly(),
|
|
17159
|
+
className: string(),
|
|
17160
|
+
classes: array(string()).readonly(),
|
|
17161
|
+
/** Relative event-media path, or null when the group has no picture yet. */
|
|
17162
|
+
mediaUrl: string().nullable(),
|
|
17163
|
+
singleton: boolean()
|
|
17164
|
+
});
|
|
17165
|
+
var AnalyticsGroupMemberSchema = object({
|
|
17166
|
+
trackId: string(),
|
|
17167
|
+
deviceId: number().int(),
|
|
17168
|
+
className: string(),
|
|
17169
|
+
firstSeen: number().int(),
|
|
17170
|
+
lastSeen: number().int(),
|
|
17171
|
+
mediaUrl: string().nullable()
|
|
17172
|
+
});
|
|
17173
|
+
var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
|
|
17174
|
+
var ListGroupsQueryInput = object({
|
|
17175
|
+
/** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
|
|
17176
|
+
deviceIds: array(number()),
|
|
17177
|
+
/** Window lower bound on `closedAt` (inclusive). */
|
|
17178
|
+
since: number().optional(),
|
|
17179
|
+
/** Window upper bound on `openedAt` (inclusive). */
|
|
17180
|
+
until: number().optional(),
|
|
17181
|
+
limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
|
|
17182
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
17183
|
+
cursor: string().optional()
|
|
17184
|
+
});
|
|
17185
|
+
var ListGroupsPageSchema = object({
|
|
17186
|
+
groups: array(AnalyticsGroupRecordSchema).readonly(),
|
|
17187
|
+
nextCursor: string().nullable()
|
|
17188
|
+
});
|
|
17099
17189
|
var KeyEventQueryInput = object({
|
|
17100
17190
|
deviceId: number(),
|
|
17101
17191
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -17171,7 +17261,9 @@ var TrackCascadeCountsSchema = object({
|
|
|
17171
17261
|
/** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
|
|
17172
17262
|
plates: number().int(),
|
|
17173
17263
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
17174
|
-
embeddings: number().int()
|
|
17264
|
+
embeddings: number().int(),
|
|
17265
|
+
/** Group membership + group rows removed with their last member (best-effort). */
|
|
17266
|
+
groups: number().int()
|
|
17175
17267
|
});
|
|
17176
17268
|
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
17177
17269
|
var DiskReconcileCountsSchema = object({
|
|
@@ -17317,7 +17409,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17317
17409
|
* stationary registry). Default false: the timeline lists passages,
|
|
17318
17410
|
* not parking records (operator decision, 2026-08-15). */
|
|
17319
17411
|
includeStationary: boolean().optional()
|
|
17320
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
17412
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
|
|
17413
|
+
deviceId: number(),
|
|
17414
|
+
groupId: string().min(1)
|
|
17415
|
+
}), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
17321
17416
|
kind: "mutation",
|
|
17322
17417
|
auth: "admin"
|
|
17323
17418
|
}), 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({
|
|
@@ -17627,7 +17722,8 @@ var PipelineModelOptionSchema = object({
|
|
|
17627
17722
|
sizeMB: number()
|
|
17628
17723
|
})),
|
|
17629
17724
|
group: ModelVariantGroupSchema.optional(),
|
|
17630
|
-
legacy: boolean().optional()
|
|
17725
|
+
legacy: boolean().optional(),
|
|
17726
|
+
provider: ModelProviderIdSchema.optional()
|
|
17631
17727
|
});
|
|
17632
17728
|
var ConfigFieldBridge = custom();
|
|
17633
17729
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -25741,7 +25837,12 @@ var PlateInfoSchema = object({
|
|
|
25741
25837
|
plateBbox: BoundingBoxSchema.optional(),
|
|
25742
25838
|
/** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
|
|
25743
25839
|
keyFrameMediaKey: string().optional(),
|
|
25744
|
-
base64: string().optional()
|
|
25840
|
+
base64: string().optional(),
|
|
25841
|
+
/**
|
|
25842
|
+
* Same crop as a data-plane URL. `getPlateByTrack` returns this and
|
|
25843
|
+
* never inlines JPEG; `listPlates` still inlines for the admin-ui.
|
|
25844
|
+
*/
|
|
25845
|
+
cropUrl: string().optional()
|
|
25745
25846
|
});
|
|
25746
25847
|
var MediaFileLiteSchema = object({
|
|
25747
25848
|
key: string(),
|
|
@@ -31265,6 +31366,12 @@ Object.freeze({
|
|
|
31265
31366
|
addonId: null,
|
|
31266
31367
|
access: "view"
|
|
31267
31368
|
},
|
|
31369
|
+
"deviceManager.getBindingsBatch": {
|
|
31370
|
+
capName: "device-manager",
|
|
31371
|
+
capScope: "system",
|
|
31372
|
+
addonId: null,
|
|
31373
|
+
access: "view"
|
|
31374
|
+
},
|
|
31268
31375
|
"deviceManager.getChildren": {
|
|
31269
31376
|
capName: "device-manager",
|
|
31270
31377
|
capScope: "system",
|
|
@@ -31325,6 +31432,12 @@ Object.freeze({
|
|
|
31325
31432
|
addonId: null,
|
|
31326
31433
|
access: "view"
|
|
31327
31434
|
},
|
|
31435
|
+
"deviceManager.getLinkedDevicesBatch": {
|
|
31436
|
+
capName: "device-manager",
|
|
31437
|
+
capScope: "system",
|
|
31438
|
+
addonId: null,
|
|
31439
|
+
access: "view"
|
|
31440
|
+
},
|
|
31328
31441
|
"deviceManager.getRoleDisplayDefaults": {
|
|
31329
31442
|
capName: "device-manager",
|
|
31330
31443
|
capScope: "system",
|
|
@@ -33095,6 +33208,12 @@ Object.freeze({
|
|
|
33095
33208
|
addonId: null,
|
|
33096
33209
|
access: "view"
|
|
33097
33210
|
},
|
|
33211
|
+
"pipelineAnalytics.getGroup": {
|
|
33212
|
+
capName: "pipeline-analytics",
|
|
33213
|
+
capScope: "device",
|
|
33214
|
+
addonId: null,
|
|
33215
|
+
access: "view"
|
|
33216
|
+
},
|
|
33098
33217
|
"pipelineAnalytics.getKeyEvents": {
|
|
33099
33218
|
capName: "pipeline-analytics",
|
|
33100
33219
|
capScope: "device",
|
|
@@ -33179,6 +33298,12 @@ Object.freeze({
|
|
|
33179
33298
|
addonId: null,
|
|
33180
33299
|
access: "view"
|
|
33181
33300
|
},
|
|
33301
|
+
"pipelineAnalytics.listGroups": {
|
|
33302
|
+
capName: "pipeline-analytics",
|
|
33303
|
+
capScope: "device",
|
|
33304
|
+
addonId: null,
|
|
33305
|
+
access: "view"
|
|
33306
|
+
},
|
|
33182
33307
|
"pipelineAnalytics.listOpsLog": {
|
|
33183
33308
|
capName: "pipeline-analytics",
|
|
33184
33309
|
capScope: "device",
|
|
@@ -35960,6 +36085,11 @@ Object.freeze({
|
|
|
35960
36085
|
form: "single",
|
|
35961
36086
|
optional: false
|
|
35962
36087
|
}],
|
|
36088
|
+
"deviceManager.getBindingsBatch": [{
|
|
36089
|
+
name: "deviceIds",
|
|
36090
|
+
form: "array",
|
|
36091
|
+
optional: false
|
|
36092
|
+
}],
|
|
35963
36093
|
"deviceManager.getChildren": [{
|
|
35964
36094
|
name: "parentDeviceId",
|
|
35965
36095
|
form: "single",
|
|
@@ -36005,6 +36135,11 @@ Object.freeze({
|
|
|
36005
36135
|
form: "single",
|
|
36006
36136
|
optional: false
|
|
36007
36137
|
}],
|
|
36138
|
+
"deviceManager.getLinkedDevicesBatch": [{
|
|
36139
|
+
name: "deviceIds",
|
|
36140
|
+
form: "array",
|
|
36141
|
+
optional: false
|
|
36142
|
+
}],
|
|
36008
36143
|
"deviceManager.getSettingsSchema": [{
|
|
36009
36144
|
name: "deviceId",
|
|
36010
36145
|
form: "single",
|
|
@@ -36025,6 +36160,11 @@ Object.freeze({
|
|
|
36025
36160
|
form: "single",
|
|
36026
36161
|
optional: false
|
|
36027
36162
|
}],
|
|
36163
|
+
"deviceManager.listAll": [{
|
|
36164
|
+
name: "deviceIds",
|
|
36165
|
+
form: "array",
|
|
36166
|
+
optional: true
|
|
36167
|
+
}],
|
|
36028
36168
|
"deviceManager.loadConfig": [{
|
|
36029
36169
|
name: "deviceId",
|
|
36030
36170
|
form: "single",
|
|
@@ -36598,6 +36738,11 @@ Object.freeze({
|
|
|
36598
36738
|
form: "single",
|
|
36599
36739
|
optional: false
|
|
36600
36740
|
}],
|
|
36741
|
+
"pipelineAnalytics.getGroup": [{
|
|
36742
|
+
name: "deviceId",
|
|
36743
|
+
form: "single",
|
|
36744
|
+
optional: false
|
|
36745
|
+
}],
|
|
36601
36746
|
"pipelineAnalytics.getKeyEvents": [{
|
|
36602
36747
|
name: "deviceId",
|
|
36603
36748
|
form: "single",
|
|
@@ -36653,6 +36798,11 @@ Object.freeze({
|
|
|
36653
36798
|
form: "array",
|
|
36654
36799
|
optional: false
|
|
36655
36800
|
}],
|
|
36801
|
+
"pipelineAnalytics.listGroups": [{
|
|
36802
|
+
name: "deviceIds",
|
|
36803
|
+
form: "array",
|
|
36804
|
+
optional: false
|
|
36805
|
+
}],
|
|
36656
36806
|
"pipelineAnalytics.listOpsLog": [{
|
|
36657
36807
|
name: "deviceId",
|
|
36658
36808
|
form: "single",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-unraid",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.28",
|
|
4
4
|
"description": "Unraid device-provider addon for CamStack — one Container per Unraid instance fanning out array, disk, docker and notification entities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|