@camstack/addon-provider-dreo 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
|
@@ -5837,6 +5837,13 @@ var BaseAddon = class {
|
|
|
5837
5837
|
_readinessGeneration = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2, 14);
|
|
5838
5838
|
/** Capability names this addon registered at init — used to emit matching `down` events on shutdown. */
|
|
5839
5839
|
_registeredCapNames = [];
|
|
5840
|
+
/**
|
|
5841
|
+
* True only after `readAddonStore` actually answered. Constructor
|
|
5842
|
+
* defaults look like stored config when the store is down — a forked
|
|
5843
|
+
* addon that auto-starts from those defaults (cloudflare-tunnel quick
|
|
5844
|
+
* mode, 2026-08-25) is not "the operator chose this".
|
|
5845
|
+
*/
|
|
5846
|
+
settingsStoreReady = false;
|
|
5840
5847
|
/** Default config values. Provided via constructor. */
|
|
5841
5848
|
defaults;
|
|
5842
5849
|
constructor(defaults) {
|
|
@@ -6237,7 +6244,9 @@ var BaseAddon = class {
|
|
|
6237
6244
|
];
|
|
6238
6245
|
let lastErr;
|
|
6239
6246
|
for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
|
|
6240
|
-
|
|
6247
|
+
const stored = await settings.readAddonStore() ?? {};
|
|
6248
|
+
this.settingsStoreReady = true;
|
|
6249
|
+
return stored;
|
|
6241
6250
|
} catch (err) {
|
|
6242
6251
|
lastErr = err;
|
|
6243
6252
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -6245,6 +6254,7 @@ var BaseAddon = class {
|
|
|
6245
6254
|
if (attempt === delaysMs.length) break;
|
|
6246
6255
|
await new Promise((r) => setTimeout(r, delaysMs[attempt]));
|
|
6247
6256
|
}
|
|
6257
|
+
this.settingsStoreReady = false;
|
|
6248
6258
|
this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
|
|
6249
6259
|
return {};
|
|
6250
6260
|
}
|
|
@@ -8148,6 +8158,12 @@ var ModelVariantGroupSchema = object({
|
|
|
8148
8158
|
*/
|
|
8149
8159
|
resolution: number().int().positive().optional()
|
|
8150
8160
|
});
|
|
8161
|
+
var ModelProviderIdSchema = _enum([
|
|
8162
|
+
"camstack",
|
|
8163
|
+
"frigate",
|
|
8164
|
+
"scrypted",
|
|
8165
|
+
"custom"
|
|
8166
|
+
]);
|
|
8151
8167
|
var ModelCatalogEntrySchema = object({
|
|
8152
8168
|
id: string(),
|
|
8153
8169
|
name: string(),
|
|
@@ -8245,6 +8261,12 @@ var ModelCatalogEntrySchema = object({
|
|
|
8245
8261
|
*/
|
|
8246
8262
|
group: ModelVariantGroupSchema.optional(),
|
|
8247
8263
|
/**
|
|
8264
|
+
* Catalog source for the pipeline stepper's provider-first picker. Absent on
|
|
8265
|
+
* built-in CamStack entries (treated as `camstack`) and on registry rows
|
|
8266
|
+
* persisted before this field existed (`inferModelProvider` fills those).
|
|
8267
|
+
*/
|
|
8268
|
+
provider: ModelProviderIdSchema.optional(),
|
|
8269
|
+
/**
|
|
8248
8270
|
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
8249
8271
|
* applies (Frigate / COCO public catalog). Set on a custom model whose raw
|
|
8250
8272
|
* labels already ARE the CamStack macros (Scrypted identity map).
|
|
@@ -12053,6 +12075,27 @@ var LinkedDeviceSchema = object({
|
|
|
12053
12075
|
features: array(string()),
|
|
12054
12076
|
producesTrackedEvents: boolean().optional()
|
|
12055
12077
|
});
|
|
12078
|
+
/** One camera's resolved linked set, tagged with the camera it belongs to.
|
|
12079
|
+
* The batch answer needs the tag; the single-device answer already has it
|
|
12080
|
+
* from the input, which is why `getLinkedDevices` keeps the untagged shape. */
|
|
12081
|
+
var LinkedDevicesForDeviceSchema = object({
|
|
12082
|
+
deviceId: number(),
|
|
12083
|
+
mode: LinkedDevicesModeSchema,
|
|
12084
|
+
devices: array(LinkedDeviceSchema)
|
|
12085
|
+
});
|
|
12086
|
+
/** One device's binding map — the shape `getBindings`, `getBindingsBatch` and
|
|
12087
|
+
* `getAllBindings` all answer in. Declared once: three copies of the same
|
|
12088
|
+
* object literal is exactly how the three drift apart. */
|
|
12089
|
+
var DeviceBindingsForDeviceSchema = object({
|
|
12090
|
+
deviceId: number(),
|
|
12091
|
+
entries: array(object({
|
|
12092
|
+
capName: string(),
|
|
12093
|
+
kind: _enum(["native", "wrapped"]),
|
|
12094
|
+
providerAddonId: string(),
|
|
12095
|
+
providerNodeId: string(),
|
|
12096
|
+
nativeAddonId: string()
|
|
12097
|
+
}))
|
|
12098
|
+
});
|
|
12056
12099
|
var SavedDeviceRowSchema = object({
|
|
12057
12100
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
12058
12101
|
id: number(),
|
|
@@ -12278,11 +12321,25 @@ method(object({
|
|
|
12278
12321
|
projection: _enum(["full", "slim"]).optional(),
|
|
12279
12322
|
/** Return only camera devices. Filtering server-side instead of
|
|
12280
12323
|
* shipping 293 rows to find 12. */
|
|
12281
|
-
isCamera: boolean().optional()
|
|
12324
|
+
isCamera: boolean().optional(),
|
|
12325
|
+
/**
|
|
12326
|
+
* Return only these device ids. For the caller that already KNOWS the
|
|
12327
|
+
* handful it wants and needs a field the id-bearing answer does not
|
|
12328
|
+
* carry — the viewer's linked-devices panel joins `type` and `online`
|
|
12329
|
+
* onto ~8 linked ids and, unfiltered, dragged the fleet across to do
|
|
12330
|
+
* it: 433 KB slim / 958 KB full for 967 devices, on a query that
|
|
12331
|
+
* refetches on the reconcile interval, on a phone.
|
|
12332
|
+
*
|
|
12333
|
+
* Safe to send at a hub that predates it: Zod STRIPS unknown input
|
|
12334
|
+
* keys rather than rejecting them (verified against the live hub
|
|
12335
|
+
* 2026-08-25 — 967 rows came back), so an old hub answers exactly what
|
|
12336
|
+
* it answers today and the caller filters as it already does.
|
|
12337
|
+
*/
|
|
12338
|
+
deviceIds: array(number()).optional()
|
|
12282
12339
|
}), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
12283
12340
|
mode: LinkedDevicesModeSchema,
|
|
12284
12341
|
devices: array(LinkedDeviceSchema)
|
|
12285
|
-
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
12342
|
+
})), 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({
|
|
12286
12343
|
deviceId: number(),
|
|
12287
12344
|
values: record(string(), unknown())
|
|
12288
12345
|
}), object({ success: literal(true) }), {
|
|
@@ -12309,25 +12366,7 @@ method(object({
|
|
|
12309
12366
|
}), method(object({ deviceId: number() }), array(StreamProbeResultSchema), {
|
|
12310
12367
|
kind: "mutation",
|
|
12311
12368
|
auth: "admin"
|
|
12312
|
-
}), method(object({ deviceId: number() }), object({
|
|
12313
|
-
deviceId: number(),
|
|
12314
|
-
entries: array(object({
|
|
12315
|
-
capName: string(),
|
|
12316
|
-
kind: _enum(["native", "wrapped"]),
|
|
12317
|
-
providerAddonId: string(),
|
|
12318
|
-
providerNodeId: string(),
|
|
12319
|
-
nativeAddonId: string()
|
|
12320
|
-
}))
|
|
12321
|
-
})), method(object({}), array(object({
|
|
12322
|
-
deviceId: number(),
|
|
12323
|
-
entries: array(object({
|
|
12324
|
-
capName: string(),
|
|
12325
|
-
kind: _enum(["native", "wrapped"]),
|
|
12326
|
-
providerAddonId: string(),
|
|
12327
|
-
providerNodeId: string(),
|
|
12328
|
-
nativeAddonId: string()
|
|
12329
|
-
}))
|
|
12330
|
-
}))), method(object({
|
|
12369
|
+
}), method(object({ deviceId: number() }), DeviceBindingsForDeviceSchema), method(object({ deviceIds: array(number()) }), array(DeviceBindingsForDeviceSchema)), method(object({}), array(DeviceBindingsForDeviceSchema)), method(object({
|
|
12331
12370
|
deviceId: number(),
|
|
12332
12371
|
capName: string(),
|
|
12333
12372
|
wrapperAddonId: string(),
|
|
@@ -14737,12 +14776,15 @@ var NcOccupancyConditionSchema = object({
|
|
|
14737
14776
|
* there is no second switch that can disagree with the first and every rule
|
|
14738
14777
|
* authored before the decision migrates for free (`audioModeOf`):
|
|
14739
14778
|
*
|
|
14740
|
-
* - **LABEL mode — `labels` present.** The rule fires
|
|
14741
|
-
*
|
|
14742
|
-
* `hitPercent` and `samplingSeconds` are ignored
|
|
14743
|
-
*
|
|
14744
|
-
*
|
|
14745
|
-
*
|
|
14779
|
+
* - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
|
|
14780
|
+
* labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
|
|
14781
|
+
* `hitPercent` and `samplingSeconds` are still ignored — a percentage of
|
|
14782
|
+
* frames is the wrong question for a classifier that labels 1–3 frames
|
|
14783
|
+
* per episode. The count window is the brake that drops a single-frame
|
|
14784
|
+
* false positive; the rule's own `throttle` cooldown is the other. The
|
|
14785
|
+
* per-label confidence floor is the analyzer's (`classificationMinScore`,
|
|
14786
|
+
* per device) — a label only reaches this condition if the classifier was
|
|
14787
|
+
* already confident enough. `confirmHits: 1` restores first-frame fire.
|
|
14746
14788
|
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
14747
14789
|
* the condition: at least `hitPercent`% of the samples over
|
|
14748
14790
|
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
@@ -14769,14 +14811,22 @@ var NcOccupancyConditionSchema = object({
|
|
|
14769
14811
|
* an operator who typed `dog` mean the same thing.
|
|
14770
14812
|
*/
|
|
14771
14813
|
var NcAudioConditionSchema = object({
|
|
14772
|
-
/** LABEL MODE: audio macro labels. Present ⇒
|
|
14814
|
+
/** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
|
|
14773
14815
|
labels: array(string().min(1)).min(1).optional(),
|
|
14774
14816
|
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
14775
14817
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
14776
14818
|
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
14777
14819
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
14778
14820
|
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
14779
|
-
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
14821
|
+
samplingSeconds: number().int().min(1).max(300).default(10),
|
|
14822
|
+
/**
|
|
14823
|
+
* LABEL MODE: how many labelled frames must land inside
|
|
14824
|
+
* {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
|
|
14825
|
+
* Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
|
|
14826
|
+
*/
|
|
14827
|
+
confirmHits: number().int().min(1).max(20).optional(),
|
|
14828
|
+
/** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
|
|
14829
|
+
confirmWindowSec: number().int().min(1).max(60).optional()
|
|
14780
14830
|
});
|
|
14781
14831
|
/**
|
|
14782
14832
|
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
@@ -17150,6 +17200,46 @@ var RecentTracksPageSchema = object({
|
|
|
17150
17200
|
/** Cursor for the next page, or null when this page is the last. */
|
|
17151
17201
|
nextCursor: string().nullable()
|
|
17152
17202
|
});
|
|
17203
|
+
var LIST_GROUPS_DEFAULT_LIMIT = 40;
|
|
17204
|
+
var LIST_GROUPS_MAX_LIMIT = 100;
|
|
17205
|
+
var AnalyticsGroupRecordSchema = object({
|
|
17206
|
+
id: string(),
|
|
17207
|
+
deviceId: number().int(),
|
|
17208
|
+
openedAt: number().int(),
|
|
17209
|
+
closedAt: number().int(),
|
|
17210
|
+
timestamp: number().int(),
|
|
17211
|
+
memberCount: number().int(),
|
|
17212
|
+
memberTrackIds: array(string()).readonly(),
|
|
17213
|
+
className: string(),
|
|
17214
|
+
classes: array(string()).readonly(),
|
|
17215
|
+
/** Relative event-media path, or null when the group has no picture yet. */
|
|
17216
|
+
mediaUrl: string().nullable(),
|
|
17217
|
+
singleton: boolean()
|
|
17218
|
+
});
|
|
17219
|
+
var AnalyticsGroupMemberSchema = object({
|
|
17220
|
+
trackId: string(),
|
|
17221
|
+
deviceId: number().int(),
|
|
17222
|
+
className: string(),
|
|
17223
|
+
firstSeen: number().int(),
|
|
17224
|
+
lastSeen: number().int(),
|
|
17225
|
+
mediaUrl: string().nullable()
|
|
17226
|
+
});
|
|
17227
|
+
var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
|
|
17228
|
+
var ListGroupsQueryInput = object({
|
|
17229
|
+
/** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
|
|
17230
|
+
deviceIds: array(number()),
|
|
17231
|
+
/** Window lower bound on `closedAt` (inclusive). */
|
|
17232
|
+
since: number().optional(),
|
|
17233
|
+
/** Window upper bound on `openedAt` (inclusive). */
|
|
17234
|
+
until: number().optional(),
|
|
17235
|
+
limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
|
|
17236
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
17237
|
+
cursor: string().optional()
|
|
17238
|
+
});
|
|
17239
|
+
var ListGroupsPageSchema = object({
|
|
17240
|
+
groups: array(AnalyticsGroupRecordSchema).readonly(),
|
|
17241
|
+
nextCursor: string().nullable()
|
|
17242
|
+
});
|
|
17153
17243
|
var KeyEventQueryInput = object({
|
|
17154
17244
|
deviceId: number(),
|
|
17155
17245
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -17225,7 +17315,9 @@ var TrackCascadeCountsSchema = object({
|
|
|
17225
17315
|
/** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
|
|
17226
17316
|
plates: number().int(),
|
|
17227
17317
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
17228
|
-
embeddings: number().int()
|
|
17318
|
+
embeddings: number().int(),
|
|
17319
|
+
/** Group membership + group rows removed with their last member (best-effort). */
|
|
17320
|
+
groups: number().int()
|
|
17229
17321
|
});
|
|
17230
17322
|
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
17231
17323
|
var DiskReconcileCountsSchema = object({
|
|
@@ -17371,7 +17463,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17371
17463
|
* stationary registry). Default false: the timeline lists passages,
|
|
17372
17464
|
* not parking records (operator decision, 2026-08-15). */
|
|
17373
17465
|
includeStationary: boolean().optional()
|
|
17374
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
17466
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
|
|
17467
|
+
deviceId: number(),
|
|
17468
|
+
groupId: string().min(1)
|
|
17469
|
+
}), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
17375
17470
|
kind: "mutation",
|
|
17376
17471
|
auth: "admin"
|
|
17377
17472
|
}), 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({
|
|
@@ -17681,7 +17776,8 @@ var PipelineModelOptionSchema = object({
|
|
|
17681
17776
|
sizeMB: number()
|
|
17682
17777
|
})),
|
|
17683
17778
|
group: ModelVariantGroupSchema.optional(),
|
|
17684
|
-
legacy: boolean().optional()
|
|
17779
|
+
legacy: boolean().optional(),
|
|
17780
|
+
provider: ModelProviderIdSchema.optional()
|
|
17685
17781
|
});
|
|
17686
17782
|
var ConfigFieldBridge = custom();
|
|
17687
17783
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -25786,7 +25882,12 @@ var PlateInfoSchema = object({
|
|
|
25786
25882
|
plateBbox: BoundingBoxSchema.optional(),
|
|
25787
25883
|
/** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
|
|
25788
25884
|
keyFrameMediaKey: string().optional(),
|
|
25789
|
-
base64: string().optional()
|
|
25885
|
+
base64: string().optional(),
|
|
25886
|
+
/**
|
|
25887
|
+
* Same crop as a data-plane URL. `getPlateByTrack` returns this and
|
|
25888
|
+
* never inlines JPEG; `listPlates` still inlines for the admin-ui.
|
|
25889
|
+
*/
|
|
25890
|
+
cropUrl: string().optional()
|
|
25790
25891
|
});
|
|
25791
25892
|
var MediaFileLiteSchema = object({
|
|
25792
25893
|
key: string(),
|
|
@@ -31310,6 +31411,12 @@ Object.freeze({
|
|
|
31310
31411
|
addonId: null,
|
|
31311
31412
|
access: "view"
|
|
31312
31413
|
},
|
|
31414
|
+
"deviceManager.getBindingsBatch": {
|
|
31415
|
+
capName: "device-manager",
|
|
31416
|
+
capScope: "system",
|
|
31417
|
+
addonId: null,
|
|
31418
|
+
access: "view"
|
|
31419
|
+
},
|
|
31313
31420
|
"deviceManager.getChildren": {
|
|
31314
31421
|
capName: "device-manager",
|
|
31315
31422
|
capScope: "system",
|
|
@@ -31370,6 +31477,12 @@ Object.freeze({
|
|
|
31370
31477
|
addonId: null,
|
|
31371
31478
|
access: "view"
|
|
31372
31479
|
},
|
|
31480
|
+
"deviceManager.getLinkedDevicesBatch": {
|
|
31481
|
+
capName: "device-manager",
|
|
31482
|
+
capScope: "system",
|
|
31483
|
+
addonId: null,
|
|
31484
|
+
access: "view"
|
|
31485
|
+
},
|
|
31373
31486
|
"deviceManager.getRoleDisplayDefaults": {
|
|
31374
31487
|
capName: "device-manager",
|
|
31375
31488
|
capScope: "system",
|
|
@@ -33140,6 +33253,12 @@ Object.freeze({
|
|
|
33140
33253
|
addonId: null,
|
|
33141
33254
|
access: "view"
|
|
33142
33255
|
},
|
|
33256
|
+
"pipelineAnalytics.getGroup": {
|
|
33257
|
+
capName: "pipeline-analytics",
|
|
33258
|
+
capScope: "device",
|
|
33259
|
+
addonId: null,
|
|
33260
|
+
access: "view"
|
|
33261
|
+
},
|
|
33143
33262
|
"pipelineAnalytics.getKeyEvents": {
|
|
33144
33263
|
capName: "pipeline-analytics",
|
|
33145
33264
|
capScope: "device",
|
|
@@ -33224,6 +33343,12 @@ Object.freeze({
|
|
|
33224
33343
|
addonId: null,
|
|
33225
33344
|
access: "view"
|
|
33226
33345
|
},
|
|
33346
|
+
"pipelineAnalytics.listGroups": {
|
|
33347
|
+
capName: "pipeline-analytics",
|
|
33348
|
+
capScope: "device",
|
|
33349
|
+
addonId: null,
|
|
33350
|
+
access: "view"
|
|
33351
|
+
},
|
|
33227
33352
|
"pipelineAnalytics.listOpsLog": {
|
|
33228
33353
|
capName: "pipeline-analytics",
|
|
33229
33354
|
capScope: "device",
|
|
@@ -36005,6 +36130,11 @@ Object.freeze({
|
|
|
36005
36130
|
form: "single",
|
|
36006
36131
|
optional: false
|
|
36007
36132
|
}],
|
|
36133
|
+
"deviceManager.getBindingsBatch": [{
|
|
36134
|
+
name: "deviceIds",
|
|
36135
|
+
form: "array",
|
|
36136
|
+
optional: false
|
|
36137
|
+
}],
|
|
36008
36138
|
"deviceManager.getChildren": [{
|
|
36009
36139
|
name: "parentDeviceId",
|
|
36010
36140
|
form: "single",
|
|
@@ -36050,6 +36180,11 @@ Object.freeze({
|
|
|
36050
36180
|
form: "single",
|
|
36051
36181
|
optional: false
|
|
36052
36182
|
}],
|
|
36183
|
+
"deviceManager.getLinkedDevicesBatch": [{
|
|
36184
|
+
name: "deviceIds",
|
|
36185
|
+
form: "array",
|
|
36186
|
+
optional: false
|
|
36187
|
+
}],
|
|
36053
36188
|
"deviceManager.getSettingsSchema": [{
|
|
36054
36189
|
name: "deviceId",
|
|
36055
36190
|
form: "single",
|
|
@@ -36070,6 +36205,11 @@ Object.freeze({
|
|
|
36070
36205
|
form: "single",
|
|
36071
36206
|
optional: false
|
|
36072
36207
|
}],
|
|
36208
|
+
"deviceManager.listAll": [{
|
|
36209
|
+
name: "deviceIds",
|
|
36210
|
+
form: "array",
|
|
36211
|
+
optional: true
|
|
36212
|
+
}],
|
|
36073
36213
|
"deviceManager.loadConfig": [{
|
|
36074
36214
|
name: "deviceId",
|
|
36075
36215
|
form: "single",
|
|
@@ -36643,6 +36783,11 @@ Object.freeze({
|
|
|
36643
36783
|
form: "single",
|
|
36644
36784
|
optional: false
|
|
36645
36785
|
}],
|
|
36786
|
+
"pipelineAnalytics.getGroup": [{
|
|
36787
|
+
name: "deviceId",
|
|
36788
|
+
form: "single",
|
|
36789
|
+
optional: false
|
|
36790
|
+
}],
|
|
36646
36791
|
"pipelineAnalytics.getKeyEvents": [{
|
|
36647
36792
|
name: "deviceId",
|
|
36648
36793
|
form: "single",
|
|
@@ -36698,6 +36843,11 @@ Object.freeze({
|
|
|
36698
36843
|
form: "array",
|
|
36699
36844
|
optional: false
|
|
36700
36845
|
}],
|
|
36846
|
+
"pipelineAnalytics.listGroups": [{
|
|
36847
|
+
name: "deviceIds",
|
|
36848
|
+
form: "array",
|
|
36849
|
+
optional: false
|
|
36850
|
+
}],
|
|
36701
36851
|
"pipelineAnalytics.listOpsLog": [{
|
|
36702
36852
|
name: "deviceId",
|
|
36703
36853
|
form: "single",
|
package/dist/addon.mjs
CHANGED
|
@@ -5838,6 +5838,13 @@ var BaseAddon = class {
|
|
|
5838
5838
|
_readinessGeneration = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2, 14);
|
|
5839
5839
|
/** Capability names this addon registered at init — used to emit matching `down` events on shutdown. */
|
|
5840
5840
|
_registeredCapNames = [];
|
|
5841
|
+
/**
|
|
5842
|
+
* True only after `readAddonStore` actually answered. Constructor
|
|
5843
|
+
* defaults look like stored config when the store is down — a forked
|
|
5844
|
+
* addon that auto-starts from those defaults (cloudflare-tunnel quick
|
|
5845
|
+
* mode, 2026-08-25) is not "the operator chose this".
|
|
5846
|
+
*/
|
|
5847
|
+
settingsStoreReady = false;
|
|
5841
5848
|
/** Default config values. Provided via constructor. */
|
|
5842
5849
|
defaults;
|
|
5843
5850
|
constructor(defaults) {
|
|
@@ -6238,7 +6245,9 @@ var BaseAddon = class {
|
|
|
6238
6245
|
];
|
|
6239
6246
|
let lastErr;
|
|
6240
6247
|
for (let attempt = 0; attempt <= delaysMs.length; attempt++) try {
|
|
6241
|
-
|
|
6248
|
+
const stored = await settings.readAddonStore() ?? {};
|
|
6249
|
+
this.settingsStoreReady = true;
|
|
6250
|
+
return stored;
|
|
6242
6251
|
} catch (err) {
|
|
6243
6252
|
lastErr = err;
|
|
6244
6253
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -6246,6 +6255,7 @@ var BaseAddon = class {
|
|
|
6246
6255
|
if (attempt === delaysMs.length) break;
|
|
6247
6256
|
await new Promise((r) => setTimeout(r, delaysMs[attempt]));
|
|
6248
6257
|
}
|
|
6258
|
+
this.settingsStoreReady = false;
|
|
6249
6259
|
this._ctx?.logger?.warn?.("readAddonStore: settings-store unavailable after retries — using defaults", { meta: { error: lastErr instanceof Error ? lastErr.message : String(lastErr) } });
|
|
6250
6260
|
return {};
|
|
6251
6261
|
}
|
|
@@ -8149,6 +8159,12 @@ var ModelVariantGroupSchema = object({
|
|
|
8149
8159
|
*/
|
|
8150
8160
|
resolution: number().int().positive().optional()
|
|
8151
8161
|
});
|
|
8162
|
+
var ModelProviderIdSchema = _enum([
|
|
8163
|
+
"camstack",
|
|
8164
|
+
"frigate",
|
|
8165
|
+
"scrypted",
|
|
8166
|
+
"custom"
|
|
8167
|
+
]);
|
|
8152
8168
|
var ModelCatalogEntrySchema = object({
|
|
8153
8169
|
id: string(),
|
|
8154
8170
|
name: string(),
|
|
@@ -8246,6 +8262,12 @@ var ModelCatalogEntrySchema = object({
|
|
|
8246
8262
|
*/
|
|
8247
8263
|
group: ModelVariantGroupSchema.optional(),
|
|
8248
8264
|
/**
|
|
8265
|
+
* Catalog source for the pipeline stepper's provider-first picker. Absent on
|
|
8266
|
+
* built-in CamStack entries (treated as `camstack`) and on registry rows
|
|
8267
|
+
* persisted before this field existed (`inferModelProvider` fills those).
|
|
8268
|
+
*/
|
|
8269
|
+
provider: ModelProviderIdSchema.optional(),
|
|
8270
|
+
/**
|
|
8249
8271
|
* Per-MODEL class map override. Absent ⇒ the step's `StepDefinition.classMap`
|
|
8250
8272
|
* applies (Frigate / COCO public catalog). Set on a custom model whose raw
|
|
8251
8273
|
* labels already ARE the CamStack macros (Scrypted identity map).
|
|
@@ -12054,6 +12076,27 @@ var LinkedDeviceSchema = object({
|
|
|
12054
12076
|
features: array(string()),
|
|
12055
12077
|
producesTrackedEvents: boolean().optional()
|
|
12056
12078
|
});
|
|
12079
|
+
/** One camera's resolved linked set, tagged with the camera it belongs to.
|
|
12080
|
+
* The batch answer needs the tag; the single-device answer already has it
|
|
12081
|
+
* from the input, which is why `getLinkedDevices` keeps the untagged shape. */
|
|
12082
|
+
var LinkedDevicesForDeviceSchema = object({
|
|
12083
|
+
deviceId: number(),
|
|
12084
|
+
mode: LinkedDevicesModeSchema,
|
|
12085
|
+
devices: array(LinkedDeviceSchema)
|
|
12086
|
+
});
|
|
12087
|
+
/** One device's binding map — the shape `getBindings`, `getBindingsBatch` and
|
|
12088
|
+
* `getAllBindings` all answer in. Declared once: three copies of the same
|
|
12089
|
+
* object literal is exactly how the three drift apart. */
|
|
12090
|
+
var DeviceBindingsForDeviceSchema = object({
|
|
12091
|
+
deviceId: number(),
|
|
12092
|
+
entries: array(object({
|
|
12093
|
+
capName: string(),
|
|
12094
|
+
kind: _enum(["native", "wrapped"]),
|
|
12095
|
+
providerAddonId: string(),
|
|
12096
|
+
providerNodeId: string(),
|
|
12097
|
+
nativeAddonId: string()
|
|
12098
|
+
}))
|
|
12099
|
+
});
|
|
12057
12100
|
var SavedDeviceRowSchema = object({
|
|
12058
12101
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
12059
12102
|
id: number(),
|
|
@@ -12279,11 +12322,25 @@ method(object({
|
|
|
12279
12322
|
projection: _enum(["full", "slim"]).optional(),
|
|
12280
12323
|
/** Return only camera devices. Filtering server-side instead of
|
|
12281
12324
|
* shipping 293 rows to find 12. */
|
|
12282
|
-
isCamera: boolean().optional()
|
|
12325
|
+
isCamera: boolean().optional(),
|
|
12326
|
+
/**
|
|
12327
|
+
* Return only these device ids. For the caller that already KNOWS the
|
|
12328
|
+
* handful it wants and needs a field the id-bearing answer does not
|
|
12329
|
+
* carry — the viewer's linked-devices panel joins `type` and `online`
|
|
12330
|
+
* onto ~8 linked ids and, unfiltered, dragged the fleet across to do
|
|
12331
|
+
* it: 433 KB slim / 958 KB full for 967 devices, on a query that
|
|
12332
|
+
* refetches on the reconcile interval, on a phone.
|
|
12333
|
+
*
|
|
12334
|
+
* Safe to send at a hub that predates it: Zod STRIPS unknown input
|
|
12335
|
+
* keys rather than rejecting them (verified against the live hub
|
|
12336
|
+
* 2026-08-25 — 967 rows came back), so an old hub answers exactly what
|
|
12337
|
+
* it answers today and the caller filters as it already does.
|
|
12338
|
+
*/
|
|
12339
|
+
deviceIds: array(number()).optional()
|
|
12283
12340
|
}), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
12284
12341
|
mode: LinkedDevicesModeSchema,
|
|
12285
12342
|
devices: array(LinkedDeviceSchema)
|
|
12286
|
-
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
12343
|
+
})), 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({
|
|
12287
12344
|
deviceId: number(),
|
|
12288
12345
|
values: record(string(), unknown())
|
|
12289
12346
|
}), object({ success: literal(true) }), {
|
|
@@ -12310,25 +12367,7 @@ method(object({
|
|
|
12310
12367
|
}), method(object({ deviceId: number() }), array(StreamProbeResultSchema), {
|
|
12311
12368
|
kind: "mutation",
|
|
12312
12369
|
auth: "admin"
|
|
12313
|
-
}), method(object({ deviceId: number() }), object({
|
|
12314
|
-
deviceId: number(),
|
|
12315
|
-
entries: array(object({
|
|
12316
|
-
capName: string(),
|
|
12317
|
-
kind: _enum(["native", "wrapped"]),
|
|
12318
|
-
providerAddonId: string(),
|
|
12319
|
-
providerNodeId: string(),
|
|
12320
|
-
nativeAddonId: string()
|
|
12321
|
-
}))
|
|
12322
|
-
})), method(object({}), array(object({
|
|
12323
|
-
deviceId: number(),
|
|
12324
|
-
entries: array(object({
|
|
12325
|
-
capName: string(),
|
|
12326
|
-
kind: _enum(["native", "wrapped"]),
|
|
12327
|
-
providerAddonId: string(),
|
|
12328
|
-
providerNodeId: string(),
|
|
12329
|
-
nativeAddonId: string()
|
|
12330
|
-
}))
|
|
12331
|
-
}))), method(object({
|
|
12370
|
+
}), method(object({ deviceId: number() }), DeviceBindingsForDeviceSchema), method(object({ deviceIds: array(number()) }), array(DeviceBindingsForDeviceSchema)), method(object({}), array(DeviceBindingsForDeviceSchema)), method(object({
|
|
12332
12371
|
deviceId: number(),
|
|
12333
12372
|
capName: string(),
|
|
12334
12373
|
wrapperAddonId: string(),
|
|
@@ -14738,12 +14777,15 @@ var NcOccupancyConditionSchema = object({
|
|
|
14738
14777
|
* there is no second switch that can disagree with the first and every rule
|
|
14739
14778
|
* authored before the decision migrates for free (`audioModeOf`):
|
|
14740
14779
|
*
|
|
14741
|
-
* - **LABEL mode — `labels` present.** The rule fires
|
|
14742
|
-
*
|
|
14743
|
-
* `hitPercent` and `samplingSeconds` are ignored
|
|
14744
|
-
*
|
|
14745
|
-
*
|
|
14746
|
-
*
|
|
14780
|
+
* - **LABEL mode — `labels` present.** The rule fires when `confirmHits`
|
|
14781
|
+
* labelled frames land inside `confirmWindowSec` (default 2 in 5 s).
|
|
14782
|
+
* `hitPercent` and `samplingSeconds` are still ignored — a percentage of
|
|
14783
|
+
* frames is the wrong question for a classifier that labels 1–3 frames
|
|
14784
|
+
* per episode. The count window is the brake that drops a single-frame
|
|
14785
|
+
* false positive; the rule's own `throttle` cooldown is the other. The
|
|
14786
|
+
* per-label confidence floor is the analyzer's (`classificationMinScore`,
|
|
14787
|
+
* per device) — a label only reaches this condition if the classifier was
|
|
14788
|
+
* already confident enough. `confirmHits: 1` restores first-frame fire.
|
|
14747
14789
|
* - **LEVEL mode — `dbThreshold` present, no labels.** The sampling window IS
|
|
14748
14790
|
* the condition: at least `hitPercent`% of the samples over
|
|
14749
14791
|
* `samplingSeconds` must be at or above `dbThreshold` dBFS (see
|
|
@@ -14770,14 +14812,22 @@ var NcOccupancyConditionSchema = object({
|
|
|
14770
14812
|
* an operator who typed `dog` mean the same thing.
|
|
14771
14813
|
*/
|
|
14772
14814
|
var NcAudioConditionSchema = object({
|
|
14773
|
-
/** LABEL MODE: audio macro labels. Present ⇒
|
|
14815
|
+
/** LABEL MODE: audio macro labels. Present ⇒ count-in-window confirm. */
|
|
14774
14816
|
labels: array(string().min(1)).min(1).optional(),
|
|
14775
14817
|
/** LEVEL MODE: floor in dBFS (negative-going, `0` = full scale). */
|
|
14776
14818
|
dbThreshold: number().min(-96).max(0).optional(),
|
|
14777
14819
|
/** LEVEL MODE ONLY: percentage of the window's samples that must be hits (1–100). */
|
|
14778
14820
|
hitPercent: number().int().min(1).max(100).default(60),
|
|
14779
14821
|
/** LEVEL MODE ONLY: length of the sampling window in seconds. */
|
|
14780
|
-
samplingSeconds: number().int().min(1).max(300).default(10)
|
|
14822
|
+
samplingSeconds: number().int().min(1).max(300).default(10),
|
|
14823
|
+
/**
|
|
14824
|
+
* LABEL MODE: how many labelled frames must land inside
|
|
14825
|
+
* {@link NcAudioConditionSchema.shape.confirmWindowSec} before dispatch.
|
|
14826
|
+
* Absent ⇒ 2 (the matcher default). `1` is first-frame fire.
|
|
14827
|
+
*/
|
|
14828
|
+
confirmHits: number().int().min(1).max(20).optional(),
|
|
14829
|
+
/** LABEL MODE: the window those frames must share, in seconds. Absent ⇒ 5. */
|
|
14830
|
+
confirmWindowSec: number().int().min(1).max(60).optional()
|
|
14781
14831
|
});
|
|
14782
14832
|
/**
|
|
14783
14833
|
* Which zone-crossing DIRECTION a rule accepts (`ObjectEvent.zoneCrossing`).
|
|
@@ -17151,6 +17201,46 @@ var RecentTracksPageSchema = object({
|
|
|
17151
17201
|
/** Cursor for the next page, or null when this page is the last. */
|
|
17152
17202
|
nextCursor: string().nullable()
|
|
17153
17203
|
});
|
|
17204
|
+
var LIST_GROUPS_DEFAULT_LIMIT = 40;
|
|
17205
|
+
var LIST_GROUPS_MAX_LIMIT = 100;
|
|
17206
|
+
var AnalyticsGroupRecordSchema = object({
|
|
17207
|
+
id: string(),
|
|
17208
|
+
deviceId: number().int(),
|
|
17209
|
+
openedAt: number().int(),
|
|
17210
|
+
closedAt: number().int(),
|
|
17211
|
+
timestamp: number().int(),
|
|
17212
|
+
memberCount: number().int(),
|
|
17213
|
+
memberTrackIds: array(string()).readonly(),
|
|
17214
|
+
className: string(),
|
|
17215
|
+
classes: array(string()).readonly(),
|
|
17216
|
+
/** Relative event-media path, or null when the group has no picture yet. */
|
|
17217
|
+
mediaUrl: string().nullable(),
|
|
17218
|
+
singleton: boolean()
|
|
17219
|
+
});
|
|
17220
|
+
var AnalyticsGroupMemberSchema = object({
|
|
17221
|
+
trackId: string(),
|
|
17222
|
+
deviceId: number().int(),
|
|
17223
|
+
className: string(),
|
|
17224
|
+
firstSeen: number().int(),
|
|
17225
|
+
lastSeen: number().int(),
|
|
17226
|
+
mediaUrl: string().nullable()
|
|
17227
|
+
});
|
|
17228
|
+
var AnalyticsGroupDetailSchema = AnalyticsGroupRecordSchema.extend({ members: array(AnalyticsGroupMemberSchema).readonly() });
|
|
17229
|
+
var ListGroupsQueryInput = object({
|
|
17230
|
+
/** Devices to merge. An empty array yields `{ groups: [], nextCursor: null }`. */
|
|
17231
|
+
deviceIds: array(number()),
|
|
17232
|
+
/** Window lower bound on `closedAt` (inclusive). */
|
|
17233
|
+
since: number().optional(),
|
|
17234
|
+
/** Window upper bound on `openedAt` (inclusive). */
|
|
17235
|
+
until: number().optional(),
|
|
17236
|
+
limit: number().int().min(1).max(LIST_GROUPS_MAX_LIMIT).default(LIST_GROUPS_DEFAULT_LIMIT),
|
|
17237
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
17238
|
+
cursor: string().optional()
|
|
17239
|
+
});
|
|
17240
|
+
var ListGroupsPageSchema = object({
|
|
17241
|
+
groups: array(AnalyticsGroupRecordSchema).readonly(),
|
|
17242
|
+
nextCursor: string().nullable()
|
|
17243
|
+
});
|
|
17154
17244
|
var KeyEventQueryInput = object({
|
|
17155
17245
|
deviceId: number(),
|
|
17156
17246
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -17226,7 +17316,9 @@ var TrackCascadeCountsSchema = object({
|
|
|
17226
17316
|
/** Unassigned plate reads removed (best-effort; plate leg deferred to plate-intelligence). */
|
|
17227
17317
|
plates: number().int(),
|
|
17228
17318
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
17229
|
-
embeddings: number().int()
|
|
17319
|
+
embeddings: number().int(),
|
|
17320
|
+
/** Group membership + group rows removed with their last member (best-effort). */
|
|
17321
|
+
groups: number().int()
|
|
17230
17322
|
});
|
|
17231
17323
|
/** Disk-wins reconcile: media rows whose blobs are gone, then empty tracks. */
|
|
17232
17324
|
var DiskReconcileCountsSchema = object({
|
|
@@ -17372,7 +17464,10 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
17372
17464
|
* stationary registry). Default false: the timeline lists passages,
|
|
17373
17465
|
* not parking records (operator decision, 2026-08-15). */
|
|
17374
17466
|
includeStationary: boolean().optional()
|
|
17375
|
-
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(
|
|
17467
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(ListGroupsQueryInput, ListGroupsPageSchema), method(object({
|
|
17468
|
+
deviceId: number(),
|
|
17469
|
+
groupId: string().min(1)
|
|
17470
|
+
}), AnalyticsGroupDetailSchema.nullable()), method(object({ deviceId: number() }), _void(), {
|
|
17376
17471
|
kind: "mutation",
|
|
17377
17472
|
auth: "admin"
|
|
17378
17473
|
}), 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({
|
|
@@ -17682,7 +17777,8 @@ var PipelineModelOptionSchema = object({
|
|
|
17682
17777
|
sizeMB: number()
|
|
17683
17778
|
})),
|
|
17684
17779
|
group: ModelVariantGroupSchema.optional(),
|
|
17685
|
-
legacy: boolean().optional()
|
|
17780
|
+
legacy: boolean().optional(),
|
|
17781
|
+
provider: ModelProviderIdSchema.optional()
|
|
17686
17782
|
});
|
|
17687
17783
|
var ConfigFieldBridge = custom();
|
|
17688
17784
|
var PipelineAddonSchemaSchema = object({
|
|
@@ -25787,7 +25883,12 @@ var PlateInfoSchema = object({
|
|
|
25787
25883
|
plateBbox: BoundingBoxSchema.optional(),
|
|
25788
25884
|
/** keyFrame parity: MediaStore key of the track's native-resolution key frame. */
|
|
25789
25885
|
keyFrameMediaKey: string().optional(),
|
|
25790
|
-
base64: string().optional()
|
|
25886
|
+
base64: string().optional(),
|
|
25887
|
+
/**
|
|
25888
|
+
* Same crop as a data-plane URL. `getPlateByTrack` returns this and
|
|
25889
|
+
* never inlines JPEG; `listPlates` still inlines for the admin-ui.
|
|
25890
|
+
*/
|
|
25891
|
+
cropUrl: string().optional()
|
|
25791
25892
|
});
|
|
25792
25893
|
var MediaFileLiteSchema = object({
|
|
25793
25894
|
key: string(),
|
|
@@ -31311,6 +31412,12 @@ Object.freeze({
|
|
|
31311
31412
|
addonId: null,
|
|
31312
31413
|
access: "view"
|
|
31313
31414
|
},
|
|
31415
|
+
"deviceManager.getBindingsBatch": {
|
|
31416
|
+
capName: "device-manager",
|
|
31417
|
+
capScope: "system",
|
|
31418
|
+
addonId: null,
|
|
31419
|
+
access: "view"
|
|
31420
|
+
},
|
|
31314
31421
|
"deviceManager.getChildren": {
|
|
31315
31422
|
capName: "device-manager",
|
|
31316
31423
|
capScope: "system",
|
|
@@ -31371,6 +31478,12 @@ Object.freeze({
|
|
|
31371
31478
|
addonId: null,
|
|
31372
31479
|
access: "view"
|
|
31373
31480
|
},
|
|
31481
|
+
"deviceManager.getLinkedDevicesBatch": {
|
|
31482
|
+
capName: "device-manager",
|
|
31483
|
+
capScope: "system",
|
|
31484
|
+
addonId: null,
|
|
31485
|
+
access: "view"
|
|
31486
|
+
},
|
|
31374
31487
|
"deviceManager.getRoleDisplayDefaults": {
|
|
31375
31488
|
capName: "device-manager",
|
|
31376
31489
|
capScope: "system",
|
|
@@ -33141,6 +33254,12 @@ Object.freeze({
|
|
|
33141
33254
|
addonId: null,
|
|
33142
33255
|
access: "view"
|
|
33143
33256
|
},
|
|
33257
|
+
"pipelineAnalytics.getGroup": {
|
|
33258
|
+
capName: "pipeline-analytics",
|
|
33259
|
+
capScope: "device",
|
|
33260
|
+
addonId: null,
|
|
33261
|
+
access: "view"
|
|
33262
|
+
},
|
|
33144
33263
|
"pipelineAnalytics.getKeyEvents": {
|
|
33145
33264
|
capName: "pipeline-analytics",
|
|
33146
33265
|
capScope: "device",
|
|
@@ -33225,6 +33344,12 @@ Object.freeze({
|
|
|
33225
33344
|
addonId: null,
|
|
33226
33345
|
access: "view"
|
|
33227
33346
|
},
|
|
33347
|
+
"pipelineAnalytics.listGroups": {
|
|
33348
|
+
capName: "pipeline-analytics",
|
|
33349
|
+
capScope: "device",
|
|
33350
|
+
addonId: null,
|
|
33351
|
+
access: "view"
|
|
33352
|
+
},
|
|
33228
33353
|
"pipelineAnalytics.listOpsLog": {
|
|
33229
33354
|
capName: "pipeline-analytics",
|
|
33230
33355
|
capScope: "device",
|
|
@@ -36006,6 +36131,11 @@ Object.freeze({
|
|
|
36006
36131
|
form: "single",
|
|
36007
36132
|
optional: false
|
|
36008
36133
|
}],
|
|
36134
|
+
"deviceManager.getBindingsBatch": [{
|
|
36135
|
+
name: "deviceIds",
|
|
36136
|
+
form: "array",
|
|
36137
|
+
optional: false
|
|
36138
|
+
}],
|
|
36009
36139
|
"deviceManager.getChildren": [{
|
|
36010
36140
|
name: "parentDeviceId",
|
|
36011
36141
|
form: "single",
|
|
@@ -36051,6 +36181,11 @@ Object.freeze({
|
|
|
36051
36181
|
form: "single",
|
|
36052
36182
|
optional: false
|
|
36053
36183
|
}],
|
|
36184
|
+
"deviceManager.getLinkedDevicesBatch": [{
|
|
36185
|
+
name: "deviceIds",
|
|
36186
|
+
form: "array",
|
|
36187
|
+
optional: false
|
|
36188
|
+
}],
|
|
36054
36189
|
"deviceManager.getSettingsSchema": [{
|
|
36055
36190
|
name: "deviceId",
|
|
36056
36191
|
form: "single",
|
|
@@ -36071,6 +36206,11 @@ Object.freeze({
|
|
|
36071
36206
|
form: "single",
|
|
36072
36207
|
optional: false
|
|
36073
36208
|
}],
|
|
36209
|
+
"deviceManager.listAll": [{
|
|
36210
|
+
name: "deviceIds",
|
|
36211
|
+
form: "array",
|
|
36212
|
+
optional: true
|
|
36213
|
+
}],
|
|
36074
36214
|
"deviceManager.loadConfig": [{
|
|
36075
36215
|
name: "deviceId",
|
|
36076
36216
|
form: "single",
|
|
@@ -36644,6 +36784,11 @@ Object.freeze({
|
|
|
36644
36784
|
form: "single",
|
|
36645
36785
|
optional: false
|
|
36646
36786
|
}],
|
|
36787
|
+
"pipelineAnalytics.getGroup": [{
|
|
36788
|
+
name: "deviceId",
|
|
36789
|
+
form: "single",
|
|
36790
|
+
optional: false
|
|
36791
|
+
}],
|
|
36647
36792
|
"pipelineAnalytics.getKeyEvents": [{
|
|
36648
36793
|
name: "deviceId",
|
|
36649
36794
|
form: "single",
|
|
@@ -36699,6 +36844,11 @@ Object.freeze({
|
|
|
36699
36844
|
form: "array",
|
|
36700
36845
|
optional: false
|
|
36701
36846
|
}],
|
|
36847
|
+
"pipelineAnalytics.listGroups": [{
|
|
36848
|
+
name: "deviceIds",
|
|
36849
|
+
form: "array",
|
|
36850
|
+
optional: false
|
|
36851
|
+
}],
|
|
36702
36852
|
"pipelineAnalytics.listOpsLog": [{
|
|
36703
36853
|
name: "deviceId",
|
|
36704
36854
|
form: "single",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-dreo",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.28",
|
|
4
4
|
"description": "Dreo smart-device (fan / air-circulator / purifier / heater / humidifier) device-provider addon for CamStack — wraps the @apocaliss92/nodedreo Dreo cloud client (REST + WebSocket)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|