@camstack/addon-provider-tuya 0.1.9 → 0.1.11
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 +220 -15
- package/dist/addon.mjs +220 -15
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -3,7 +3,7 @@ let crypto$1 = require("crypto");
|
|
|
3
3
|
let net = require("net");
|
|
4
4
|
let events = require("events");
|
|
5
5
|
let dgram = require("dgram");
|
|
6
|
-
//#region ../types/dist/event-category-
|
|
6
|
+
//#region ../types/dist/event-category-H4AVePnn.mjs
|
|
7
7
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
8
8
|
EventCategory["SystemBoot"] = "system.boot";
|
|
9
9
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -153,6 +153,9 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
153
153
|
EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
|
|
154
154
|
EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
|
|
155
155
|
EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
|
|
156
|
+
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
157
|
+
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
158
|
+
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
156
159
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
157
160
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
158
161
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -7252,6 +7255,24 @@ var RecordingRetentionSchema = object({
|
|
|
7252
7255
|
maxSizeGb: number().min(0).optional()
|
|
7253
7256
|
});
|
|
7254
7257
|
/**
|
|
7258
|
+
* Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
|
|
7259
|
+
* sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
|
|
7260
|
+
* previews at. Five graduated steps; absent on a config = `standard` (the
|
|
7261
|
+
* shipped default, matching `sheet-geometry`/`sheet-composer`).
|
|
7262
|
+
*
|
|
7263
|
+
* Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
|
|
7264
|
+
* Each window's index sidecar carries its own tile dims, so a camera whose
|
|
7265
|
+
* preset changed over time renders every historical window at the dims it was
|
|
7266
|
+
* written with.
|
|
7267
|
+
*/
|
|
7268
|
+
var ScrubThumbnailPresetSchema = _enum([
|
|
7269
|
+
"minimal",
|
|
7270
|
+
"low",
|
|
7271
|
+
"standard",
|
|
7272
|
+
"high",
|
|
7273
|
+
"max"
|
|
7274
|
+
]);
|
|
7275
|
+
/**
|
|
7255
7276
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
7256
7277
|
*
|
|
7257
7278
|
* `mode` is the authoritative storage choice; `schedule`/`triggers`/`pre`/`post`
|
|
@@ -7288,7 +7309,14 @@ var RecordingConfigSchema = object({
|
|
|
7288
7309
|
* derived into bands once via `migrateConfigToBands`.
|
|
7289
7310
|
*/
|
|
7290
7311
|
bands: array(RecordingBandSchema).optional(),
|
|
7291
|
-
retention: RecordingRetentionSchema.optional()
|
|
7312
|
+
retention: RecordingRetentionSchema.optional(),
|
|
7313
|
+
/**
|
|
7314
|
+
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
7315
|
+
* timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
|
|
7316
|
+
* windows only — existing sheets are immutable, and each window's index
|
|
7317
|
+
* carries its own tile dims so mixed-preset history renders correctly.
|
|
7318
|
+
*/
|
|
7319
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7292
7320
|
});
|
|
7293
7321
|
/**
|
|
7294
7322
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
@@ -10800,10 +10828,23 @@ var deviceDiscoveryCapability = {
|
|
|
10800
10828
|
}
|
|
10801
10829
|
};
|
|
10802
10830
|
/**
|
|
10803
|
-
* Doorbell button cap.
|
|
10804
|
-
*
|
|
10805
|
-
*
|
|
10806
|
-
*
|
|
10831
|
+
* Doorbell button cap. Two kinds of providers coexist behind this cap
|
|
10832
|
+
* name (same pattern as `snapshot`):
|
|
10833
|
+
*
|
|
10834
|
+
* - **Native** providers: registered per-device by device-driver
|
|
10835
|
+
* addons via `ctx.registerNativeCap` — either on a
|
|
10836
|
+
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
10837
|
+
* or directly on the camera (Reolink registers at camera level).
|
|
10838
|
+
* Emits an `onPressed` event every time the firmware pushes a
|
|
10839
|
+
* ring; status tracks the last press and a pressCount since start
|
|
10840
|
+
* (diagnostic).
|
|
10841
|
+
*
|
|
10842
|
+
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
10843
|
+
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
10844
|
+
* device (contact / switch / event-emitter …) into a doorbell for
|
|
10845
|
+
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
10846
|
+
* it per camera in the device-bindings UI, then picks the source
|
|
10847
|
+
* device + trigger in the per-device settings.
|
|
10807
10848
|
*
|
|
10808
10849
|
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
10809
10850
|
* — subscribers listening at the camera level receive ring events
|
|
@@ -10824,7 +10865,10 @@ var doorbellCapability = {
|
|
|
10824
10865
|
scope: "device",
|
|
10825
10866
|
deviceNative: true,
|
|
10826
10867
|
mode: "singleton",
|
|
10827
|
-
|
|
10868
|
+
kind: "wrapper",
|
|
10869
|
+
defaultActive: false,
|
|
10870
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
10871
|
+
exposesDeviceSettings: true,
|
|
10828
10872
|
methods: {},
|
|
10829
10873
|
events: {
|
|
10830
10874
|
/**
|
|
@@ -17193,6 +17237,14 @@ var ConfigEntrySchema = object({
|
|
|
17193
17237
|
value: unknown(),
|
|
17194
17238
|
description: string().optional()
|
|
17195
17239
|
});
|
|
17240
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
17241
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
17242
|
+
var LinkedDeviceSchema = object({
|
|
17243
|
+
deviceId: number(),
|
|
17244
|
+
name: string(),
|
|
17245
|
+
location: string().nullable(),
|
|
17246
|
+
features: array(string())
|
|
17247
|
+
});
|
|
17196
17248
|
var SavedDeviceRowSchema = object({
|
|
17197
17249
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
17198
17250
|
id: number(),
|
|
@@ -17414,7 +17466,10 @@ method(object({
|
|
|
17414
17466
|
}), _void(), {
|
|
17415
17467
|
kind: "mutation",
|
|
17416
17468
|
auth: "admin"
|
|
17417
|
-
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({ addonId: string().optional() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }),
|
|
17469
|
+
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({ addonId: string().optional() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
17470
|
+
mode: DeviceLinkModeSchema,
|
|
17471
|
+
devices: array(LinkedDeviceSchema)
|
|
17472
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
17418
17473
|
deviceId: number(),
|
|
17419
17474
|
values: record(string(), unknown())
|
|
17420
17475
|
}), object({ success: literal(true) }), {
|
|
@@ -18683,6 +18738,61 @@ var EventKindSchema = _enum([
|
|
|
18683
18738
|
"object",
|
|
18684
18739
|
"audio"
|
|
18685
18740
|
]);
|
|
18741
|
+
/**
|
|
18742
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
18743
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
18744
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
18745
|
+
*/
|
|
18746
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
18747
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
18748
|
+
var EventKindIconSchema = _enum([
|
|
18749
|
+
"motion",
|
|
18750
|
+
"audio",
|
|
18751
|
+
"person",
|
|
18752
|
+
"vehicle",
|
|
18753
|
+
"animal",
|
|
18754
|
+
"door",
|
|
18755
|
+
"pir",
|
|
18756
|
+
"smoke",
|
|
18757
|
+
"water",
|
|
18758
|
+
"button",
|
|
18759
|
+
"generic"
|
|
18760
|
+
]);
|
|
18761
|
+
var EventKindCategorySchema = _enum([
|
|
18762
|
+
"motion",
|
|
18763
|
+
"audio",
|
|
18764
|
+
"detection",
|
|
18765
|
+
"sensor",
|
|
18766
|
+
"custom"
|
|
18767
|
+
]);
|
|
18768
|
+
var EventKindDescriptorSchema = object({
|
|
18769
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
18770
|
+
kind: string(),
|
|
18771
|
+
label: string(),
|
|
18772
|
+
/** Hex color for timeline/legend rendering. */
|
|
18773
|
+
color: string(),
|
|
18774
|
+
icon: EventKindIconSchema,
|
|
18775
|
+
category: EventKindCategorySchema,
|
|
18776
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
18777
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
18778
|
+
source: object({
|
|
18779
|
+
capName: string(),
|
|
18780
|
+
deviceId: number()
|
|
18781
|
+
})
|
|
18782
|
+
});
|
|
18783
|
+
var SensorEventSchema = object({
|
|
18784
|
+
id: string(),
|
|
18785
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
18786
|
+
* yields N rows, one per camera). */
|
|
18787
|
+
deviceId: number(),
|
|
18788
|
+
/** The linked sensor device whose state changed. */
|
|
18789
|
+
sourceDeviceId: number(),
|
|
18790
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
18791
|
+
kind: string(),
|
|
18792
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
18793
|
+
value: record(string(), unknown()).nullable(),
|
|
18794
|
+
timestamp: number()
|
|
18795
|
+
});
|
|
18686
18796
|
var TrackPositionSchema = object({
|
|
18687
18797
|
x: number(),
|
|
18688
18798
|
y: number(),
|
|
@@ -18696,6 +18806,30 @@ var TrackSnapshotSchema = object({
|
|
|
18696
18806
|
mediaKey: string()
|
|
18697
18807
|
});
|
|
18698
18808
|
/**
|
|
18809
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
18810
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
18811
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
18812
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
18813
|
+
*/
|
|
18814
|
+
var TrackEnvelopeSchema = object({
|
|
18815
|
+
minX: number(),
|
|
18816
|
+
minY: number(),
|
|
18817
|
+
maxX: number(),
|
|
18818
|
+
maxY: number()
|
|
18819
|
+
});
|
|
18820
|
+
/**
|
|
18821
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
18822
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
18823
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
18824
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
18825
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
18826
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
18827
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
18828
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
18829
|
+
* (`getObjectEvents` et al.).
|
|
18830
|
+
*/
|
|
18831
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
18832
|
+
/**
|
|
18699
18833
|
* One audio-classification label heard on the track's camera while the
|
|
18700
18834
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
18701
18835
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -18746,7 +18880,11 @@ var TrackSchema = object({
|
|
|
18746
18880
|
/** Audio-classification labels heard on the camera during the track's
|
|
18747
18881
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
18748
18882
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
18749
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
18883
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
18884
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
18885
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
18886
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
18887
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
18750
18888
|
});
|
|
18751
18889
|
var BaseEventFields = {
|
|
18752
18890
|
id: string(),
|
|
@@ -18856,11 +18994,13 @@ var MediaFileSchema = object({
|
|
|
18856
18994
|
sizeBytes: number(),
|
|
18857
18995
|
timestamp: number()
|
|
18858
18996
|
});
|
|
18997
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
18998
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
18859
18999
|
var DeviceEventQueryInput = object({
|
|
18860
19000
|
deviceId: number(),
|
|
18861
19001
|
since: number().optional(),
|
|
18862
19002
|
until: number().optional(),
|
|
18863
|
-
limit: number().int().min(1).max(
|
|
19003
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
18864
19004
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
18865
19005
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
18866
19006
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -18868,6 +19008,27 @@ var DeviceEventQueryInput = object({
|
|
|
18868
19008
|
projection: _enum(["full", "slim"]).optional()
|
|
18869
19009
|
});
|
|
18870
19010
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
19011
|
+
var RecentTracksQueryInput = object({
|
|
19012
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
19013
|
+
deviceIds: array(number()),
|
|
19014
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
19015
|
+
since: number().optional(),
|
|
19016
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
19017
|
+
until: number().optional(),
|
|
19018
|
+
/** Page size. Default 200, max 1000. */
|
|
19019
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
19020
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
19021
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
19022
|
+
cursor: string().optional(),
|
|
19023
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
19024
|
+
projection: TrackProjectionSchema.optional()
|
|
19025
|
+
});
|
|
19026
|
+
var RecentTracksPageSchema = object({
|
|
19027
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
19028
|
+
tracks: array(TrackSchema).readonly(),
|
|
19029
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
19030
|
+
nextCursor: string().nullable()
|
|
19031
|
+
});
|
|
18871
19032
|
var KeyEventQueryInput = object({
|
|
18872
19033
|
deviceId: number(),
|
|
18873
19034
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -18950,11 +19111,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
18950
19111
|
deviceId: number(),
|
|
18951
19112
|
since: number().optional(),
|
|
18952
19113
|
until: number().optional(),
|
|
18953
|
-
limit: number().optional()
|
|
18954
|
-
|
|
19114
|
+
limit: number().optional(),
|
|
19115
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
19116
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
19117
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
19118
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
19119
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
19120
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
19121
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
19122
|
+
projection: TrackProjectionSchema.optional()
|
|
19123
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
18955
19124
|
kind: "mutation",
|
|
18956
19125
|
auth: "admin"
|
|
18957
|
-
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(
|
|
19126
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
19127
|
+
deviceId: number(),
|
|
19128
|
+
since: number().optional(),
|
|
19129
|
+
until: number().optional(),
|
|
19130
|
+
kinds: array(string()).optional(),
|
|
19131
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
19132
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
18958
19133
|
deviceId: number(),
|
|
18959
19134
|
since: number(),
|
|
18960
19135
|
until: number(),
|
|
@@ -22155,7 +22330,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
22155
22330
|
/**
|
|
22156
22331
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
22157
22332
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
22158
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22333
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22334
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
22335
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
22336
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
22337
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
22338
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
22159
22339
|
*/
|
|
22160
22340
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
22161
22341
|
kind: literal("segment"),
|
|
@@ -22164,7 +22344,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
22164
22344
|
bytes: number()
|
|
22165
22345
|
}), object({
|
|
22166
22346
|
kind: literal("gap"),
|
|
22167
|
-
nearestEdgeMs: number().nullable()
|
|
22347
|
+
nearestEdgeMs: number().nullable(),
|
|
22348
|
+
prevEndMs: number().nullable().optional()
|
|
22168
22349
|
})]);
|
|
22169
22350
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
22170
22351
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -23733,6 +23914,12 @@ Object.freeze({
|
|
|
23733
23914
|
addonId: null,
|
|
23734
23915
|
access: "view"
|
|
23735
23916
|
},
|
|
23917
|
+
"deviceManager.getLinkedDevices": {
|
|
23918
|
+
capName: "device-manager",
|
|
23919
|
+
capScope: "system",
|
|
23920
|
+
addonId: null,
|
|
23921
|
+
access: "view"
|
|
23922
|
+
},
|
|
23736
23923
|
"deviceManager.getRoleDisplayDefaults": {
|
|
23737
23924
|
capName: "device-manager",
|
|
23738
23925
|
capScope: "system",
|
|
@@ -25287,6 +25474,12 @@ Object.freeze({
|
|
|
25287
25474
|
addonId: null,
|
|
25288
25475
|
access: "view"
|
|
25289
25476
|
},
|
|
25477
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
25478
|
+
capName: "pipeline-analytics",
|
|
25479
|
+
capScope: "device",
|
|
25480
|
+
addonId: null,
|
|
25481
|
+
access: "view"
|
|
25482
|
+
},
|
|
25290
25483
|
"pipelineAnalytics.getTrack": {
|
|
25291
25484
|
capName: "pipeline-analytics",
|
|
25292
25485
|
capScope: "device",
|
|
@@ -25299,6 +25492,18 @@ Object.freeze({
|
|
|
25299
25492
|
addonId: null,
|
|
25300
25493
|
access: "view"
|
|
25301
25494
|
},
|
|
25495
|
+
"pipelineAnalytics.listEventKinds": {
|
|
25496
|
+
capName: "pipeline-analytics",
|
|
25497
|
+
capScope: "device",
|
|
25498
|
+
addonId: null,
|
|
25499
|
+
access: "view"
|
|
25500
|
+
},
|
|
25501
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
25502
|
+
capName: "pipeline-analytics",
|
|
25503
|
+
capScope: "device",
|
|
25504
|
+
addonId: null,
|
|
25505
|
+
access: "view"
|
|
25506
|
+
},
|
|
25302
25507
|
"pipelineAnalytics.listTracks": {
|
|
25303
25508
|
capName: "pipeline-analytics",
|
|
25304
25509
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createCipheriv, createDecipheriv, createHash, createHmac } from "crypto
|
|
|
2
2
|
import { Socket } from "net";
|
|
3
3
|
import { EventEmitter } from "events";
|
|
4
4
|
import { createSocket } from "dgram";
|
|
5
|
-
//#region ../types/dist/event-category-
|
|
5
|
+
//#region ../types/dist/event-category-H4AVePnn.mjs
|
|
6
6
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
7
7
|
EventCategory["SystemBoot"] = "system.boot";
|
|
8
8
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -152,6 +152,9 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
152
152
|
EventCategory["RecordingSegmentWritten"] = "recording.segment.written";
|
|
153
153
|
EventCategory["RecordingPolicyFallback"] = "recording.policy.fallback";
|
|
154
154
|
EventCategory["RecordingRetentionCompleted"] = "recording.retention.completed";
|
|
155
|
+
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
156
|
+
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
157
|
+
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
155
158
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
156
159
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
157
160
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -7251,6 +7254,24 @@ var RecordingRetentionSchema = object({
|
|
|
7251
7254
|
maxSizeGb: number().min(0).optional()
|
|
7252
7255
|
});
|
|
7253
7256
|
/**
|
|
7257
|
+
* Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
|
|
7258
|
+
* sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
|
|
7259
|
+
* previews at. Five graduated steps; absent on a config = `standard` (the
|
|
7260
|
+
* shipped default, matching `sheet-geometry`/`sheet-composer`).
|
|
7261
|
+
*
|
|
7262
|
+
* Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
|
|
7263
|
+
* Each window's index sidecar carries its own tile dims, so a camera whose
|
|
7264
|
+
* preset changed over time renders every historical window at the dims it was
|
|
7265
|
+
* written with.
|
|
7266
|
+
*/
|
|
7267
|
+
var ScrubThumbnailPresetSchema = _enum([
|
|
7268
|
+
"minimal",
|
|
7269
|
+
"low",
|
|
7270
|
+
"standard",
|
|
7271
|
+
"high",
|
|
7272
|
+
"max"
|
|
7273
|
+
]);
|
|
7274
|
+
/**
|
|
7254
7275
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
7255
7276
|
*
|
|
7256
7277
|
* `mode` is the authoritative storage choice; `schedule`/`triggers`/`pre`/`post`
|
|
@@ -7287,7 +7308,14 @@ var RecordingConfigSchema = object({
|
|
|
7287
7308
|
* derived into bands once via `migrateConfigToBands`.
|
|
7288
7309
|
*/
|
|
7289
7310
|
bands: array(RecordingBandSchema).optional(),
|
|
7290
|
-
retention: RecordingRetentionSchema.optional()
|
|
7311
|
+
retention: RecordingRetentionSchema.optional(),
|
|
7312
|
+
/**
|
|
7313
|
+
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
7314
|
+
* timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
|
|
7315
|
+
* windows only — existing sheets are immutable, and each window's index
|
|
7316
|
+
* carries its own tile dims so mixed-preset history renders correctly.
|
|
7317
|
+
*/
|
|
7318
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7291
7319
|
});
|
|
7292
7320
|
/**
|
|
7293
7321
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
@@ -10799,10 +10827,23 @@ var deviceDiscoveryCapability = {
|
|
|
10799
10827
|
}
|
|
10800
10828
|
};
|
|
10801
10829
|
/**
|
|
10802
|
-
* Doorbell button cap.
|
|
10803
|
-
*
|
|
10804
|
-
*
|
|
10805
|
-
*
|
|
10830
|
+
* Doorbell button cap. Two kinds of providers coexist behind this cap
|
|
10831
|
+
* name (same pattern as `snapshot`):
|
|
10832
|
+
*
|
|
10833
|
+
* - **Native** providers: registered per-device by device-driver
|
|
10834
|
+
* addons via `ctx.registerNativeCap` — either on a
|
|
10835
|
+
* `DeviceType.Button` accessory with `role: DeviceRole.Doorbell`,
|
|
10836
|
+
* or directly on the camera (Reolink registers at camera level).
|
|
10837
|
+
* Emits an `onPressed` event every time the firmware pushes a
|
|
10838
|
+
* ring; status tracks the last press and a pressCount since start
|
|
10839
|
+
* (diagnostic).
|
|
10840
|
+
*
|
|
10841
|
+
* - **Wrapper** provider: the `virtual-doorbell` system builtin
|
|
10842
|
+
* (`@camstack/system/builtins/doorbell`). Turns ANY binary-ish
|
|
10843
|
+
* device (contact / switch / event-emitter …) into a doorbell for
|
|
10844
|
+
* a camera. `defaultActive: false` — the operator explicitly binds
|
|
10845
|
+
* it per camera in the device-bindings UI, then picks the source
|
|
10846
|
+
* device + trigger in the per-device settings.
|
|
10806
10847
|
*
|
|
10807
10848
|
* The DeviceEventPropagator re-emits `onPressed` on the camera parent
|
|
10808
10849
|
* — subscribers listening at the camera level receive ring events
|
|
@@ -10823,7 +10864,10 @@ var doorbellCapability = {
|
|
|
10823
10864
|
scope: "device",
|
|
10824
10865
|
deviceNative: true,
|
|
10825
10866
|
mode: "singleton",
|
|
10826
|
-
|
|
10867
|
+
kind: "wrapper",
|
|
10868
|
+
defaultActive: false,
|
|
10869
|
+
deviceTypes: [DeviceType.Button, DeviceType.Camera],
|
|
10870
|
+
exposesDeviceSettings: true,
|
|
10827
10871
|
methods: {},
|
|
10828
10872
|
events: {
|
|
10829
10873
|
/**
|
|
@@ -17192,6 +17236,14 @@ var ConfigEntrySchema = object({
|
|
|
17192
17236
|
value: unknown(),
|
|
17193
17237
|
description: string().optional()
|
|
17194
17238
|
});
|
|
17239
|
+
var DeviceLinkModeSchema = _enum(["auto", "manual"]);
|
|
17240
|
+
/** One resolved linked device — the compact projection consumers need. */
|
|
17241
|
+
var LinkedDeviceSchema = object({
|
|
17242
|
+
deviceId: number(),
|
|
17243
|
+
name: string(),
|
|
17244
|
+
location: string().nullable(),
|
|
17245
|
+
features: array(string())
|
|
17246
|
+
});
|
|
17195
17247
|
var SavedDeviceRowSchema = object({
|
|
17196
17248
|
/** Numeric id reserved at allocateDeviceId time. */
|
|
17197
17249
|
id: number(),
|
|
@@ -17413,7 +17465,10 @@ method(object({
|
|
|
17413
17465
|
}), _void(), {
|
|
17414
17466
|
kind: "mutation",
|
|
17415
17467
|
auth: "admin"
|
|
17416
|
-
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({ addonId: string().optional() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }),
|
|
17468
|
+
}), method(object({ addonId: string() }), array(SavedDeviceRowSchema)), method(object({ addonId: string().optional() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), DeviceInfoSchema.nullable()), method(object({ parentDeviceId: number() }), array(DeviceInfoSchema)), method(object({ deviceId: number() }), object({
|
|
17469
|
+
mode: DeviceLinkModeSchema,
|
|
17470
|
+
devices: array(LinkedDeviceSchema)
|
|
17471
|
+
})), method(object({ deviceId: number() }), array(StreamSourceEntrySchema$1)), method(object({ deviceId: number() }), array(ConfigEntrySchema)), method(object({ deviceId: number() }), ConfigUISchemaOutput), method(object({
|
|
17417
17472
|
deviceId: number(),
|
|
17418
17473
|
values: record(string(), unknown())
|
|
17419
17474
|
}), object({ success: literal(true) }), {
|
|
@@ -18682,6 +18737,61 @@ var EventKindSchema = _enum([
|
|
|
18682
18737
|
"object",
|
|
18683
18738
|
"audio"
|
|
18684
18739
|
]);
|
|
18740
|
+
/**
|
|
18741
|
+
* Spatial filter for `listTracks` — the rect + polygon variants of the shared
|
|
18742
|
+
* MaskShape vocabulary (see `mask-shape.ts`). Coordinates are NORMALIZED 0..1
|
|
18743
|
+
* of the camera frame (top-left origin), matching the drawing-plane editor.
|
|
18744
|
+
*/
|
|
18745
|
+
var TrackZoneFilterSchema = discriminatedUnion("kind", [MaskRectShapeSchema, MaskPolygonShapeSchema]);
|
|
18746
|
+
/** Closed icon vocabulary so clients render a known glyph per kind. */
|
|
18747
|
+
var EventKindIconSchema = _enum([
|
|
18748
|
+
"motion",
|
|
18749
|
+
"audio",
|
|
18750
|
+
"person",
|
|
18751
|
+
"vehicle",
|
|
18752
|
+
"animal",
|
|
18753
|
+
"door",
|
|
18754
|
+
"pir",
|
|
18755
|
+
"smoke",
|
|
18756
|
+
"water",
|
|
18757
|
+
"button",
|
|
18758
|
+
"generic"
|
|
18759
|
+
]);
|
|
18760
|
+
var EventKindCategorySchema = _enum([
|
|
18761
|
+
"motion",
|
|
18762
|
+
"audio",
|
|
18763
|
+
"detection",
|
|
18764
|
+
"sensor",
|
|
18765
|
+
"custom"
|
|
18766
|
+
]);
|
|
18767
|
+
var EventKindDescriptorSchema = object({
|
|
18768
|
+
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
18769
|
+
kind: string(),
|
|
18770
|
+
label: string(),
|
|
18771
|
+
/** Hex color for timeline/legend rendering. */
|
|
18772
|
+
color: string(),
|
|
18773
|
+
icon: EventKindIconSchema,
|
|
18774
|
+
category: EventKindCategorySchema,
|
|
18775
|
+
/** Which cap + device contributes this kind. For built-ins the camera
|
|
18776
|
+
* itself; for sensor kinds the LINKED source device. */
|
|
18777
|
+
source: object({
|
|
18778
|
+
capName: string(),
|
|
18779
|
+
deviceId: number()
|
|
18780
|
+
})
|
|
18781
|
+
});
|
|
18782
|
+
var SensorEventSchema = object({
|
|
18783
|
+
id: string(),
|
|
18784
|
+
/** The CAMERA the event is attributed to (a sensor linked to N cameras
|
|
18785
|
+
* yields N rows, one per camera). */
|
|
18786
|
+
deviceId: number(),
|
|
18787
|
+
/** The linked sensor device whose state changed. */
|
|
18788
|
+
sourceDeviceId: number(),
|
|
18789
|
+
/** Event kind id — matches an `EventKindDescriptor.kind`. */
|
|
18790
|
+
kind: string(),
|
|
18791
|
+
/** Snapshot of the sensor cap's runtime-state slice at the change. */
|
|
18792
|
+
value: record(string(), unknown()).nullable(),
|
|
18793
|
+
timestamp: number()
|
|
18794
|
+
});
|
|
18685
18795
|
var TrackPositionSchema = object({
|
|
18686
18796
|
x: number(),
|
|
18687
18797
|
y: number(),
|
|
@@ -18695,6 +18805,30 @@ var TrackSnapshotSchema = object({
|
|
|
18695
18805
|
mediaKey: string()
|
|
18696
18806
|
});
|
|
18697
18807
|
/**
|
|
18808
|
+
* Normalized 0..1 trajectory envelope (min/max over every position bbox,
|
|
18809
|
+
* divided by the track's detection-frame dims), computed at persist time.
|
|
18810
|
+
* Absent when the frame dims were unknown when the track was persisted
|
|
18811
|
+
* (legacy rows / dims-less sources) and on active (in-RAM) tracks.
|
|
18812
|
+
*/
|
|
18813
|
+
var TrackEnvelopeSchema = object({
|
|
18814
|
+
minX: number(),
|
|
18815
|
+
minY: number(),
|
|
18816
|
+
maxX: number(),
|
|
18817
|
+
maxY: number()
|
|
18818
|
+
});
|
|
18819
|
+
/**
|
|
18820
|
+
* Row projection for track list queries. `full` (default) returns the
|
|
18821
|
+
* complete Track including the frame-rate `positions[]` history and the
|
|
18822
|
+
* `snapshots[]` references — megabytes across a page of tracks. `slim`
|
|
18823
|
+
* keeps every scalar the list surfaces actually render (ids, class(es),
|
|
18824
|
+
* label / audioLabels / importance enrichment, firstSeen/lastSeen, state,
|
|
18825
|
+
* zonesVisited, bestEventId, envelope) and returns `positions` /
|
|
18826
|
+
* `snapshots` as EMPTY arrays — detail views re-fetch the full row via
|
|
18827
|
+
* `getTrack`. Mirrors the event-store `projection` convention
|
|
18828
|
+
* (`getObjectEvents` et al.).
|
|
18829
|
+
*/
|
|
18830
|
+
var TrackProjectionSchema = _enum(["full", "slim"]);
|
|
18831
|
+
/**
|
|
18698
18832
|
* One audio-classification label heard on the track's camera while the
|
|
18699
18833
|
* track was alive, aggregated per label. An "episode" is one persisted
|
|
18700
18834
|
* audio event (the confident-classification path: score ≥ the device's
|
|
@@ -18745,7 +18879,11 @@ var TrackSchema = object({
|
|
|
18745
18879
|
/** Audio-classification labels heard on the camera during the track's
|
|
18746
18880
|
* life (score ≥ device `classificationMinScore`), aggregated per label.
|
|
18747
18881
|
* Absent on legacy rows / tracks with no confident audio. */
|
|
18748
|
-
audioLabels: array(TrackAudioLabelSchema).readonly().optional()
|
|
18882
|
+
audioLabels: array(TrackAudioLabelSchema).readonly().optional(),
|
|
18883
|
+
/** Normalized 0..1 trajectory envelope (see {@link TrackEnvelopeSchema}).
|
|
18884
|
+
* Populated from the persisted envelope columns on historical reads;
|
|
18885
|
+
* absent on legacy rows, dims-less tracks and active (in-RAM) tracks. */
|
|
18886
|
+
envelope: TrackEnvelopeSchema.optional()
|
|
18749
18887
|
});
|
|
18750
18888
|
var BaseEventFields = {
|
|
18751
18889
|
id: string(),
|
|
@@ -18855,11 +18993,13 @@ var MediaFileSchema = object({
|
|
|
18855
18993
|
sizeBytes: number(),
|
|
18856
18994
|
timestamp: number()
|
|
18857
18995
|
});
|
|
18996
|
+
var DEFAULT_EVENT_QUERY_LIMIT = 1e3;
|
|
18997
|
+
var MAX_EVENT_QUERY_LIMIT = 5e3;
|
|
18858
18998
|
var DeviceEventQueryInput = object({
|
|
18859
18999
|
deviceId: number(),
|
|
18860
19000
|
since: number().optional(),
|
|
18861
19001
|
until: number().optional(),
|
|
18862
|
-
limit: number().int().min(1).max(
|
|
19002
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT),
|
|
18863
19003
|
/** `slim` drops heavy JSON fields (regions/bbox/zones) and carries an
|
|
18864
19004
|
* optional `mediaUrl` (populated by B5). `full` (default) keeps today's
|
|
18865
19005
|
* exact behaviour. Callers may omit this field — the store defaults to
|
|
@@ -18867,6 +19007,27 @@ var DeviceEventQueryInput = object({
|
|
|
18867
19007
|
projection: _enum(["full", "slim"]).optional()
|
|
18868
19008
|
});
|
|
18869
19009
|
var ObjectEventQueryInput = DeviceEventQueryInput.extend({ classFilter: string().optional() });
|
|
19010
|
+
var RecentTracksQueryInput = object({
|
|
19011
|
+
/** Devices to merge. An empty array yields `{ tracks: [], nextCursor: null }`. */
|
|
19012
|
+
deviceIds: array(number()),
|
|
19013
|
+
/** Window lower bound on `lastSeen` (inclusive). */
|
|
19014
|
+
since: number().optional(),
|
|
19015
|
+
/** Window upper bound on `lastSeen` (inclusive). */
|
|
19016
|
+
until: number().optional(),
|
|
19017
|
+
/** Page size. Default 200, max 1000. */
|
|
19018
|
+
limit: number().int().min(1).max(1e3).default(200),
|
|
19019
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`.
|
|
19020
|
+
* Encodes the (lastSeen, trackId) sort position — treat as opaque. */
|
|
19021
|
+
cursor: string().optional(),
|
|
19022
|
+
/** See {@link TrackProjectionSchema}. Default `full`. */
|
|
19023
|
+
projection: TrackProjectionSchema.optional()
|
|
19024
|
+
});
|
|
19025
|
+
var RecentTracksPageSchema = object({
|
|
19026
|
+
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
19027
|
+
tracks: array(TrackSchema).readonly(),
|
|
19028
|
+
/** Cursor for the next page, or null when this page is the last. */
|
|
19029
|
+
nextCursor: string().nullable()
|
|
19030
|
+
});
|
|
18870
19031
|
var KeyEventQueryInput = object({
|
|
18871
19032
|
deviceId: number(),
|
|
18872
19033
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
@@ -18949,11 +19110,25 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
18949
19110
|
deviceId: number(),
|
|
18950
19111
|
since: number().optional(),
|
|
18951
19112
|
until: number().optional(),
|
|
18952
|
-
limit: number().optional()
|
|
18953
|
-
|
|
19113
|
+
limit: number().optional(),
|
|
19114
|
+
/** Spatial filter — only tracks whose trajectory intersects the zone
|
|
19115
|
+
* (normalized 0..1 rect or polygon). SQL-prefiltered on the persisted
|
|
19116
|
+
* envelope columns, then precisely tested per position. Tracks with
|
|
19117
|
+
* an unknown envelope (no frame dims at persist time) always match. */
|
|
19118
|
+
zone: TrackZoneFilterSchema.optional(),
|
|
19119
|
+
/** See {@link TrackProjectionSchema}. Default `full` (backward
|
|
19120
|
+
* compatible — omitting the field keeps today's exact behaviour). */
|
|
19121
|
+
projection: TrackProjectionSchema.optional()
|
|
19122
|
+
}), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
|
|
18954
19123
|
kind: "mutation",
|
|
18955
19124
|
auth: "admin"
|
|
18956
|
-
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(
|
|
19125
|
+
}), method(DeviceEventQueryInput, array(MotionEventSchema).readonly()), method(ObjectEventQueryInput, array(ObjectEventSchema).readonly()), method(DeviceEventQueryInput, array(AudioEventSchema).readonly()), method(object({ deviceId: number() }), array(EventKindDescriptorSchema).readonly()), method(object({
|
|
19126
|
+
deviceId: number(),
|
|
19127
|
+
since: number().optional(),
|
|
19128
|
+
until: number().optional(),
|
|
19129
|
+
kinds: array(string()).optional(),
|
|
19130
|
+
limit: number().int().min(1).max(MAX_EVENT_QUERY_LIMIT).default(DEFAULT_EVENT_QUERY_LIMIT)
|
|
19131
|
+
}), array(SensorEventSchema).readonly()), method(KeyEventQueryInput, array(KeyEventSchema).readonly()), method(object({
|
|
18957
19132
|
deviceId: number(),
|
|
18958
19133
|
since: number(),
|
|
18959
19134
|
until: number(),
|
|
@@ -22154,7 +22329,12 @@ var RecordingStorageUsageSchema = object({
|
|
|
22154
22329
|
/**
|
|
22155
22330
|
* Result of locating footage at a wall-clock instant for one device/profile.
|
|
22156
22331
|
* `segment` carries the covering segment's window; `gap` reports the forward
|
|
22157
|
-
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22332
|
+
* nearest covered edge (`null` past the end of footage / when none exists)
|
|
22333
|
+
* and the backward covered edge `prevEndMs` (exclusive end of the nearest
|
|
22334
|
+
* footage behind the epoch; `null` when none — optional so older providers
|
|
22335
|
+
* that omit it stay valid). `prevEndMs` lets a backward frame-step hop the
|
|
22336
|
+
* small inter-segment cracks (durMs under-covers the span to the next
|
|
22337
|
+
* startMs by ~11-17 ms) instead of no-opping at a segment head.
|
|
22158
22338
|
*/
|
|
22159
22339
|
var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
22160
22340
|
kind: literal("segment"),
|
|
@@ -22163,7 +22343,8 @@ var LocateSegmentResultSchema = discriminatedUnion("kind", [object({
|
|
|
22163
22343
|
bytes: number()
|
|
22164
22344
|
}), object({
|
|
22165
22345
|
kind: literal("gap"),
|
|
22166
|
-
nearestEdgeMs: number().nullable()
|
|
22346
|
+
nearestEdgeMs: number().nullable(),
|
|
22347
|
+
prevEndMs: number().nullable().optional()
|
|
22167
22348
|
})]);
|
|
22168
22349
|
/** Raw bytes of one finalized footage segment (read off disk on the recording node). */
|
|
22169
22350
|
var ReadSegmentBytesResultSchema = object({ data: _instanceof(Uint8Array) });
|
|
@@ -23732,6 +23913,12 @@ Object.freeze({
|
|
|
23732
23913
|
addonId: null,
|
|
23733
23914
|
access: "view"
|
|
23734
23915
|
},
|
|
23916
|
+
"deviceManager.getLinkedDevices": {
|
|
23917
|
+
capName: "device-manager",
|
|
23918
|
+
capScope: "system",
|
|
23919
|
+
addonId: null,
|
|
23920
|
+
access: "view"
|
|
23921
|
+
},
|
|
23735
23922
|
"deviceManager.getRoleDisplayDefaults": {
|
|
23736
23923
|
capName: "device-manager",
|
|
23737
23924
|
capScope: "system",
|
|
@@ -25286,6 +25473,12 @@ Object.freeze({
|
|
|
25286
25473
|
addonId: null,
|
|
25287
25474
|
access: "view"
|
|
25288
25475
|
},
|
|
25476
|
+
"pipelineAnalytics.getSensorEvents": {
|
|
25477
|
+
capName: "pipeline-analytics",
|
|
25478
|
+
capScope: "device",
|
|
25479
|
+
addonId: null,
|
|
25480
|
+
access: "view"
|
|
25481
|
+
},
|
|
25289
25482
|
"pipelineAnalytics.getTrack": {
|
|
25290
25483
|
capName: "pipeline-analytics",
|
|
25291
25484
|
capScope: "device",
|
|
@@ -25298,6 +25491,18 @@ Object.freeze({
|
|
|
25298
25491
|
addonId: null,
|
|
25299
25492
|
access: "view"
|
|
25300
25493
|
},
|
|
25494
|
+
"pipelineAnalytics.listEventKinds": {
|
|
25495
|
+
capName: "pipeline-analytics",
|
|
25496
|
+
capScope: "device",
|
|
25497
|
+
addonId: null,
|
|
25498
|
+
access: "view"
|
|
25499
|
+
},
|
|
25500
|
+
"pipelineAnalytics.listRecentTracks": {
|
|
25501
|
+
capName: "pipeline-analytics",
|
|
25502
|
+
capScope: "device",
|
|
25503
|
+
addonId: null,
|
|
25504
|
+
access: "view"
|
|
25505
|
+
},
|
|
25301
25506
|
"pipelineAnalytics.listTracks": {
|
|
25302
25507
|
capName: "pipeline-analytics",
|
|
25303
25508
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-tuya",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "Tuya / Smart Life device-provider addon for CamStack — account-onboarded (Tuya IoT cloud fetch of device localKeys) + LOCAL DP control via the @apocaliss92/nodetuya encrypted-LAN client, exposing switch / water-heater-family kettle entities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|