@camstack/addon-provider-reolink 1.1.29 → 1.1.31
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 +384 -56
- package/dist/addon.mjs +384 -56
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -7123,6 +7123,17 @@ var ModelCatalogEntrySchema = object({
|
|
|
7123
7123
|
"imagenet",
|
|
7124
7124
|
"none"
|
|
7125
7125
|
]).optional(),
|
|
7126
|
+
/**
|
|
7127
|
+
* The model already applies softmax IN-GRAPH — its raw output is a
|
|
7128
|
+
* probability distribution, not logits. When set, the `softmax`
|
|
7129
|
+
* postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
|
|
7130
|
+
* probability vector collapses it toward uniform (top-1 score craters far
|
|
7131
|
+
* below its true value, making every confidence gate meaningless). Absent ⇒
|
|
7132
|
+
* the output is raw logits and the postprocessor applies softmax (the normal
|
|
7133
|
+
* case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
|
|
7134
|
+
* TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
|
|
7135
|
+
*/
|
|
7136
|
+
outputProbabilities: boolean().optional(),
|
|
7126
7137
|
preprocessMode: _enum(["letterbox", "resize"]).optional(),
|
|
7127
7138
|
/**
|
|
7128
7139
|
* Per-MODEL postprocessor override. Absent ⇒ the step's own
|
|
@@ -7857,6 +7868,160 @@ var EncodeProfileSchema = object({
|
|
|
7857
7868
|
*/
|
|
7858
7869
|
outputArgs: array(string()).optional()
|
|
7859
7870
|
});
|
|
7871
|
+
var COCO_TO_MACRO = {
|
|
7872
|
+
mapping: {
|
|
7873
|
+
person: "person",
|
|
7874
|
+
bicycle: "vehicle",
|
|
7875
|
+
car: "vehicle",
|
|
7876
|
+
motorcycle: "vehicle",
|
|
7877
|
+
airplane: "vehicle",
|
|
7878
|
+
bus: "vehicle",
|
|
7879
|
+
train: "vehicle",
|
|
7880
|
+
truck: "vehicle",
|
|
7881
|
+
boat: "vehicle",
|
|
7882
|
+
bird: "animal",
|
|
7883
|
+
cat: "animal",
|
|
7884
|
+
dog: "animal",
|
|
7885
|
+
horse: "animal",
|
|
7886
|
+
sheep: "animal",
|
|
7887
|
+
cow: "animal",
|
|
7888
|
+
elephant: "animal",
|
|
7889
|
+
bear: "animal",
|
|
7890
|
+
zebra: "animal",
|
|
7891
|
+
giraffe: "animal",
|
|
7892
|
+
suitcase: "package",
|
|
7893
|
+
backpack: "package",
|
|
7894
|
+
handbag: "package"
|
|
7895
|
+
},
|
|
7896
|
+
preserveOriginal: false
|
|
7897
|
+
};
|
|
7898
|
+
var AUDIO_MACRO_LABELS = [
|
|
7899
|
+
{
|
|
7900
|
+
id: "speech",
|
|
7901
|
+
name: "Speech",
|
|
7902
|
+
icon: "🗣️"
|
|
7903
|
+
},
|
|
7904
|
+
{
|
|
7905
|
+
id: "scream",
|
|
7906
|
+
name: "Scream / Shout",
|
|
7907
|
+
icon: "😱"
|
|
7908
|
+
},
|
|
7909
|
+
{
|
|
7910
|
+
id: "crying",
|
|
7911
|
+
name: "Crying / Baby",
|
|
7912
|
+
icon: "😢"
|
|
7913
|
+
},
|
|
7914
|
+
{
|
|
7915
|
+
id: "laughter",
|
|
7916
|
+
name: "Laughter",
|
|
7917
|
+
icon: "😂"
|
|
7918
|
+
},
|
|
7919
|
+
{
|
|
7920
|
+
id: "music",
|
|
7921
|
+
name: "Music",
|
|
7922
|
+
icon: "🎵"
|
|
7923
|
+
},
|
|
7924
|
+
{
|
|
7925
|
+
id: "dog",
|
|
7926
|
+
name: "Dog",
|
|
7927
|
+
icon: "🐕"
|
|
7928
|
+
},
|
|
7929
|
+
{
|
|
7930
|
+
id: "cat",
|
|
7931
|
+
name: "Cat",
|
|
7932
|
+
icon: "🐈"
|
|
7933
|
+
},
|
|
7934
|
+
{
|
|
7935
|
+
id: "bird",
|
|
7936
|
+
name: "Bird",
|
|
7937
|
+
icon: "🐦"
|
|
7938
|
+
},
|
|
7939
|
+
{
|
|
7940
|
+
id: "animal",
|
|
7941
|
+
name: "Animal (other)",
|
|
7942
|
+
icon: "🐾"
|
|
7943
|
+
},
|
|
7944
|
+
{
|
|
7945
|
+
id: "alarm",
|
|
7946
|
+
name: "Alarm / Siren",
|
|
7947
|
+
icon: "🚨"
|
|
7948
|
+
},
|
|
7949
|
+
{
|
|
7950
|
+
id: "doorbell",
|
|
7951
|
+
name: "Doorbell / Knock",
|
|
7952
|
+
icon: "🔔"
|
|
7953
|
+
},
|
|
7954
|
+
{
|
|
7955
|
+
id: "glass_breaking",
|
|
7956
|
+
name: "Glass Breaking",
|
|
7957
|
+
icon: "💥"
|
|
7958
|
+
},
|
|
7959
|
+
{
|
|
7960
|
+
id: "gunshot",
|
|
7961
|
+
name: "Gunshot / Explosion",
|
|
7962
|
+
icon: "💣"
|
|
7963
|
+
},
|
|
7964
|
+
{
|
|
7965
|
+
id: "vehicle",
|
|
7966
|
+
name: "Vehicle",
|
|
7967
|
+
icon: "🚗"
|
|
7968
|
+
},
|
|
7969
|
+
{
|
|
7970
|
+
id: "siren",
|
|
7971
|
+
name: "Emergency Siren",
|
|
7972
|
+
icon: "🚑"
|
|
7973
|
+
},
|
|
7974
|
+
{
|
|
7975
|
+
id: "fire",
|
|
7976
|
+
name: "Fire / Smoke",
|
|
7977
|
+
icon: "🔥"
|
|
7978
|
+
},
|
|
7979
|
+
{
|
|
7980
|
+
id: "water",
|
|
7981
|
+
name: "Water",
|
|
7982
|
+
icon: "💧"
|
|
7983
|
+
},
|
|
7984
|
+
{
|
|
7985
|
+
id: "wind",
|
|
7986
|
+
name: "Wind / Weather",
|
|
7987
|
+
icon: "🌬️"
|
|
7988
|
+
},
|
|
7989
|
+
{
|
|
7990
|
+
id: "door",
|
|
7991
|
+
name: "Door",
|
|
7992
|
+
icon: "🚪"
|
|
7993
|
+
},
|
|
7994
|
+
{
|
|
7995
|
+
id: "footsteps",
|
|
7996
|
+
name: "Footsteps",
|
|
7997
|
+
icon: "👣"
|
|
7998
|
+
},
|
|
7999
|
+
{
|
|
8000
|
+
id: "crowd",
|
|
8001
|
+
name: "Crowd / Chatter",
|
|
8002
|
+
icon: "👥"
|
|
8003
|
+
},
|
|
8004
|
+
{
|
|
8005
|
+
id: "telephone",
|
|
8006
|
+
name: "Telephone",
|
|
8007
|
+
icon: "📞"
|
|
8008
|
+
},
|
|
8009
|
+
{
|
|
8010
|
+
id: "engine",
|
|
8011
|
+
name: "Engine / Motor",
|
|
8012
|
+
icon: "⚙️"
|
|
8013
|
+
},
|
|
8014
|
+
{
|
|
8015
|
+
id: "tools",
|
|
8016
|
+
name: "Tools / Construction",
|
|
8017
|
+
icon: "🔨"
|
|
8018
|
+
},
|
|
8019
|
+
{
|
|
8020
|
+
id: "silence",
|
|
8021
|
+
name: "Silence",
|
|
8022
|
+
icon: "🤫"
|
|
8023
|
+
}
|
|
8024
|
+
];
|
|
7860
8025
|
var YAMNET_TO_MACRO = {
|
|
7861
8026
|
mapping: {
|
|
7862
8027
|
Speech: "speech",
|
|
@@ -8123,6 +8288,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
8123
8288
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8124
8289
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8125
8290
|
/**
|
|
8291
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8292
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8293
|
+
* icon }`.
|
|
8294
|
+
*
|
|
8295
|
+
* This dictionary folds together what used to be scattered across four
|
|
8296
|
+
* copies:
|
|
8297
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8298
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8299
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8300
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8301
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8302
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8303
|
+
*
|
|
8304
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8305
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8306
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8307
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8308
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8309
|
+
*
|
|
8310
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8311
|
+
*/
|
|
8312
|
+
var TAXONOMY_COLORS = {
|
|
8313
|
+
motion: "#f59e0b",
|
|
8314
|
+
audio: "#06b6d4",
|
|
8315
|
+
person: "#22c55e",
|
|
8316
|
+
vehicle: "#3b82f6",
|
|
8317
|
+
animal: "#f97316",
|
|
8318
|
+
package: "#a855f7",
|
|
8319
|
+
sensor: "#8b5cf6",
|
|
8320
|
+
control: "#10b981",
|
|
8321
|
+
genericDetection: "#64748b"
|
|
8322
|
+
};
|
|
8323
|
+
var DETECTION_SUB_COLORS = {
|
|
8324
|
+
car: "#f59e0b",
|
|
8325
|
+
truck: "#d97706",
|
|
8326
|
+
bus: "#b45309",
|
|
8327
|
+
motorcycle: "#eab308",
|
|
8328
|
+
bicycle: "#ca8a04",
|
|
8329
|
+
airplane: "#60a5fa",
|
|
8330
|
+
boat: "#2563eb",
|
|
8331
|
+
train: "#1d4ed8",
|
|
8332
|
+
bird: "#14b8a6",
|
|
8333
|
+
dog: "#84cc16",
|
|
8334
|
+
cat: "#f97316",
|
|
8335
|
+
horse: "#a16207",
|
|
8336
|
+
sheep: "#a3a3a3",
|
|
8337
|
+
cow: "#78716c",
|
|
8338
|
+
elephant: "#6b7280",
|
|
8339
|
+
bear: "#7c2d12",
|
|
8340
|
+
zebra: "#404040",
|
|
8341
|
+
giraffe: "#d4a373"
|
|
8342
|
+
};
|
|
8343
|
+
function titleCase(id) {
|
|
8344
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8345
|
+
}
|
|
8346
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8347
|
+
function macro(kind, category, color, iconId, label) {
|
|
8348
|
+
entries.set(kind, {
|
|
8349
|
+
kind,
|
|
8350
|
+
parentKind: null,
|
|
8351
|
+
level: "macro",
|
|
8352
|
+
category,
|
|
8353
|
+
color,
|
|
8354
|
+
iconId,
|
|
8355
|
+
labelKey: `eventKind.${kind}`,
|
|
8356
|
+
label
|
|
8357
|
+
});
|
|
8358
|
+
}
|
|
8359
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8360
|
+
entries.set(kind, {
|
|
8361
|
+
kind,
|
|
8362
|
+
parentKind,
|
|
8363
|
+
level: "sub",
|
|
8364
|
+
category,
|
|
8365
|
+
color,
|
|
8366
|
+
iconId,
|
|
8367
|
+
labelKey: `eventKind.${kind}`,
|
|
8368
|
+
label
|
|
8369
|
+
});
|
|
8370
|
+
}
|
|
8371
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8372
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8373
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8374
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8375
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8376
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8377
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8378
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8379
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8380
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8381
|
+
if (entries.has(cocoClass)) continue;
|
|
8382
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8383
|
+
}
|
|
8384
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8385
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8386
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8387
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8388
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8389
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8390
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8391
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8392
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8393
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8394
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8395
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8396
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8397
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8398
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8399
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8400
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8401
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8402
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8403
|
+
const kind = `audio-${l.id}`;
|
|
8404
|
+
if (entries.has(kind)) continue;
|
|
8405
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8406
|
+
}
|
|
8407
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8408
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8409
|
+
/**
|
|
8126
8410
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8127
8411
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
8128
8412
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -16000,6 +16284,8 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
16000
16284
|
return toDeviceSummary(device, this.addonId);
|
|
16001
16285
|
}
|
|
16002
16286
|
};
|
|
16287
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
|
|
16288
|
+
new Set(Object.values(DeviceType));
|
|
16003
16289
|
/**
|
|
16004
16290
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
16005
16291
|
* surface that admin-ui consumes through `useAddonPagesListPages()`.
|
|
@@ -19106,17 +19392,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19106
19392
|
"audio",
|
|
19107
19393
|
"detection",
|
|
19108
19394
|
"sensor",
|
|
19395
|
+
"control",
|
|
19109
19396
|
"custom",
|
|
19110
19397
|
"package"
|
|
19111
19398
|
]);
|
|
19399
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19400
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19112
19401
|
var EventKindDescriptorSchema = object({
|
|
19113
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19402
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19114
19403
|
kind: string(),
|
|
19404
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19405
|
+
labelKey: string(),
|
|
19406
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19115
19407
|
label: string(),
|
|
19116
19408
|
/** Hex color for timeline/legend rendering. */
|
|
19117
19409
|
color: string(),
|
|
19410
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19411
|
+
iconId: string(),
|
|
19412
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19118
19413
|
icon: EventKindIconSchema,
|
|
19119
19414
|
category: EventKindCategorySchema,
|
|
19415
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19416
|
+
parentKind: string().nullable(),
|
|
19417
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19418
|
+
level: EventKindLevelSchema,
|
|
19120
19419
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19121
19420
|
* itself; for sensor kinds the LINKED source device. */
|
|
19122
19421
|
source: object({
|
|
@@ -19189,11 +19488,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19189
19488
|
firstAt: number(),
|
|
19190
19489
|
lastAt: number()
|
|
19191
19490
|
});
|
|
19491
|
+
/**
|
|
19492
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19493
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19494
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19495
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19496
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19497
|
+
*/
|
|
19498
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19192
19499
|
var TrackSchema = object({
|
|
19193
19500
|
trackId: string(),
|
|
19194
19501
|
deviceId: number(),
|
|
19195
19502
|
className: string(),
|
|
19196
19503
|
label: string().optional(),
|
|
19504
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19505
|
+
source: TrackSourceSchema.optional(),
|
|
19197
19506
|
firstSeen: number(),
|
|
19198
19507
|
lastSeen: number(),
|
|
19199
19508
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19570,6 +19879,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19570
19879
|
eventId: string(),
|
|
19571
19880
|
timestamp: number()
|
|
19572
19881
|
});
|
|
19882
|
+
/**
|
|
19883
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19884
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19885
|
+
* caps into per-camera event-kind descriptors.
|
|
19886
|
+
*
|
|
19887
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19888
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19889
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19890
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19891
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19892
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19893
|
+
* eventful cap is missing.
|
|
19894
|
+
*/
|
|
19895
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19896
|
+
var LEGACY_ICON = {
|
|
19897
|
+
motion: "motion",
|
|
19898
|
+
audio: "audio",
|
|
19899
|
+
person: "person",
|
|
19900
|
+
vehicle: "vehicle",
|
|
19901
|
+
animal: "animal",
|
|
19902
|
+
package: "package",
|
|
19903
|
+
door: "door",
|
|
19904
|
+
pir: "pir",
|
|
19905
|
+
smoke: "smoke",
|
|
19906
|
+
water: "water",
|
|
19907
|
+
button: "button",
|
|
19908
|
+
generic: "generic",
|
|
19909
|
+
gas: "smoke",
|
|
19910
|
+
vibration: "generic",
|
|
19911
|
+
tamper: "generic",
|
|
19912
|
+
presence: "person",
|
|
19913
|
+
lock: "generic",
|
|
19914
|
+
siren: "generic",
|
|
19915
|
+
switch: "generic",
|
|
19916
|
+
doorbell: "button"
|
|
19917
|
+
};
|
|
19918
|
+
function legacyIcon(iconId) {
|
|
19919
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19920
|
+
}
|
|
19921
|
+
/**
|
|
19922
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19923
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19924
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19925
|
+
*/
|
|
19926
|
+
var CAP_TO_KIND = {
|
|
19927
|
+
contact: "contact",
|
|
19928
|
+
motion: "motion-sensor",
|
|
19929
|
+
smoke: "smoke",
|
|
19930
|
+
flood: "flood",
|
|
19931
|
+
gas: "gas",
|
|
19932
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19933
|
+
vibration: "vibration",
|
|
19934
|
+
tamper: "tamper",
|
|
19935
|
+
presence: "presence",
|
|
19936
|
+
"enum-sensor": "enum-sensor",
|
|
19937
|
+
"event-emitter": "device-event",
|
|
19938
|
+
"lock-control": "lock",
|
|
19939
|
+
switch: "switch",
|
|
19940
|
+
button: "button",
|
|
19941
|
+
doorbell: "doorbell"
|
|
19942
|
+
};
|
|
19943
|
+
function buildDescriptor(capName, kind) {
|
|
19944
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19945
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19946
|
+
return {
|
|
19947
|
+
...t,
|
|
19948
|
+
icon: legacyIcon(t.iconId)
|
|
19949
|
+
};
|
|
19950
|
+
}
|
|
19951
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19573
19952
|
var CameraPipelineConfigSchema = object({
|
|
19574
19953
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19575
19954
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -21195,22 +21574,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
21195
21574
|
var RestartAddonResultSchema = unknown();
|
|
21196
21575
|
var InstallPackageResultSchema = unknown();
|
|
21197
21576
|
var ReloadPackagesResultSchema = unknown();
|
|
21198
|
-
/**
|
|
21199
|
-
* Result of `updateFrameworkPackage`. The cap method returns BEFORE the
|
|
21200
|
-
* server restarts so the admin UI can react to the `restartingAt`
|
|
21201
|
-
* timestamp (shows reconnect overlay). The transition from
|
|
21202
|
-
* `fromVersion` to `toVersion` will be confirmed by a subsequent
|
|
21203
|
-
* `system.restart-completed` event after the new process boots.
|
|
21204
|
-
*
|
|
21205
|
-
* Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
|
|
21206
|
-
*/
|
|
21207
|
-
var UpdateFrameworkPackageResultSchema = object({
|
|
21208
|
-
packageName: string(),
|
|
21209
|
-
fromVersion: string(),
|
|
21210
|
-
toVersion: string(),
|
|
21211
|
-
/** Ms-epoch the server scheduled its self-restart. */
|
|
21212
|
-
restartingAt: number()
|
|
21213
|
-
});
|
|
21214
21577
|
var BulkUpdateItemStatusSchema = _enum([
|
|
21215
21578
|
"queued",
|
|
21216
21579
|
"updating",
|
|
@@ -21338,13 +21701,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
21338
21701
|
}), object({ success: literal(true) }), {
|
|
21339
21702
|
kind: "mutation",
|
|
21340
21703
|
auth: "admin"
|
|
21341
|
-
}), method(object({
|
|
21342
|
-
packageName: string().min(1),
|
|
21343
|
-
version: string().optional(),
|
|
21344
|
-
deferRestart: boolean().optional()
|
|
21345
|
-
}), UpdateFrameworkPackageResultSchema, {
|
|
21346
|
-
kind: "mutation",
|
|
21347
|
-
auth: "admin"
|
|
21348
21704
|
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
21349
21705
|
kind: "mutation",
|
|
21350
21706
|
auth: "admin"
|
|
@@ -23819,12 +24175,6 @@ Object.freeze({
|
|
|
23819
24175
|
addonId: null,
|
|
23820
24176
|
access: "delete"
|
|
23821
24177
|
},
|
|
23822
|
-
"addons.updateFrameworkPackage": {
|
|
23823
|
-
capName: "addons",
|
|
23824
|
-
capScope: "system",
|
|
23825
|
-
addonId: null,
|
|
23826
|
-
access: "create"
|
|
23827
|
-
},
|
|
23828
24178
|
"addons.updatePackage": {
|
|
23829
24179
|
capName: "addons",
|
|
23830
24180
|
capScope: "system",
|
|
@@ -28413,32 +28763,6 @@ Object.freeze({
|
|
|
28413
28763
|
"network-access": "ingress",
|
|
28414
28764
|
"smtp-provider": "email"
|
|
28415
28765
|
});
|
|
28416
|
-
var frameworkSwapPackageSchema = object({
|
|
28417
|
-
name: string(),
|
|
28418
|
-
stagedPath: string(),
|
|
28419
|
-
backupPath: string(),
|
|
28420
|
-
toVersion: string(),
|
|
28421
|
-
fromVersion: string().nullable()
|
|
28422
|
-
});
|
|
28423
|
-
object({
|
|
28424
|
-
jobId: string(),
|
|
28425
|
-
taskId: string(),
|
|
28426
|
-
packages: array(frameworkSwapPackageSchema),
|
|
28427
|
-
requestedAtMs: number(),
|
|
28428
|
-
schemaVersion: literal(1)
|
|
28429
|
-
});
|
|
28430
|
-
object({
|
|
28431
|
-
jobId: string(),
|
|
28432
|
-
taskId: string(),
|
|
28433
|
-
backups: array(object({
|
|
28434
|
-
name: string(),
|
|
28435
|
-
backupPath: string(),
|
|
28436
|
-
livePath: string()
|
|
28437
|
-
})),
|
|
28438
|
-
appliedAtMs: number(),
|
|
28439
|
-
bootAttempts: number(),
|
|
28440
|
-
schemaVersion: literal(1)
|
|
28441
|
-
});
|
|
28442
28766
|
//#endregion
|
|
28443
28767
|
//#region ../../node_modules/undici/lib/core/symbols.js
|
|
28444
28768
|
var require_symbols = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
@@ -222857,6 +223181,10 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
222857
223181
|
emitDoorbellPressed(timestamp) {
|
|
222858
223182
|
this.doorbellLastPressedAt = timestamp;
|
|
222859
223183
|
this.doorbellPressCountSinceStart += 1;
|
|
223184
|
+
this.runtimeState.setCapState(doorbellCapability.name, {
|
|
223185
|
+
lastPressedAt: timestamp,
|
|
223186
|
+
pressCountSinceStart: this.doorbellPressCountSinceStart
|
|
223187
|
+
});
|
|
222860
223188
|
this.ctx.eventBus.emit(createEvent(EventCategory.DoorbellOnPressed, this.eventSource(), {
|
|
222861
223189
|
deviceId: this.id,
|
|
222862
223190
|
timestamp
|
package/dist/addon.mjs
CHANGED
|
@@ -7118,6 +7118,17 @@ var ModelCatalogEntrySchema = object({
|
|
|
7118
7118
|
"imagenet",
|
|
7119
7119
|
"none"
|
|
7120
7120
|
]).optional(),
|
|
7121
|
+
/**
|
|
7122
|
+
* The model already applies softmax IN-GRAPH — its raw output is a
|
|
7123
|
+
* probability distribution, not logits. When set, the `softmax`
|
|
7124
|
+
* postprocessor must NOT re-apply softmax: re-softmaxing an already-normalised
|
|
7125
|
+
* probability vector collapses it toward uniform (top-1 score craters far
|
|
7126
|
+
* below its true value, making every confidence gate meaningless). Absent ⇒
|
|
7127
|
+
* the output is raw logits and the postprocessor applies softmax (the normal
|
|
7128
|
+
* case). Set on the Google AIY Birds `bird-classifier` (softmax baked into the
|
|
7129
|
+
* TF graph). Threaded to the Python pool via `PoolModelConfig.outputProbabilities`.
|
|
7130
|
+
*/
|
|
7131
|
+
outputProbabilities: boolean().optional(),
|
|
7121
7132
|
preprocessMode: _enum(["letterbox", "resize"]).optional(),
|
|
7122
7133
|
/**
|
|
7123
7134
|
* Per-MODEL postprocessor override. Absent ⇒ the step's own
|
|
@@ -7852,6 +7863,160 @@ var EncodeProfileSchema = object({
|
|
|
7852
7863
|
*/
|
|
7853
7864
|
outputArgs: array(string()).optional()
|
|
7854
7865
|
});
|
|
7866
|
+
var COCO_TO_MACRO = {
|
|
7867
|
+
mapping: {
|
|
7868
|
+
person: "person",
|
|
7869
|
+
bicycle: "vehicle",
|
|
7870
|
+
car: "vehicle",
|
|
7871
|
+
motorcycle: "vehicle",
|
|
7872
|
+
airplane: "vehicle",
|
|
7873
|
+
bus: "vehicle",
|
|
7874
|
+
train: "vehicle",
|
|
7875
|
+
truck: "vehicle",
|
|
7876
|
+
boat: "vehicle",
|
|
7877
|
+
bird: "animal",
|
|
7878
|
+
cat: "animal",
|
|
7879
|
+
dog: "animal",
|
|
7880
|
+
horse: "animal",
|
|
7881
|
+
sheep: "animal",
|
|
7882
|
+
cow: "animal",
|
|
7883
|
+
elephant: "animal",
|
|
7884
|
+
bear: "animal",
|
|
7885
|
+
zebra: "animal",
|
|
7886
|
+
giraffe: "animal",
|
|
7887
|
+
suitcase: "package",
|
|
7888
|
+
backpack: "package",
|
|
7889
|
+
handbag: "package"
|
|
7890
|
+
},
|
|
7891
|
+
preserveOriginal: false
|
|
7892
|
+
};
|
|
7893
|
+
var AUDIO_MACRO_LABELS = [
|
|
7894
|
+
{
|
|
7895
|
+
id: "speech",
|
|
7896
|
+
name: "Speech",
|
|
7897
|
+
icon: "🗣️"
|
|
7898
|
+
},
|
|
7899
|
+
{
|
|
7900
|
+
id: "scream",
|
|
7901
|
+
name: "Scream / Shout",
|
|
7902
|
+
icon: "😱"
|
|
7903
|
+
},
|
|
7904
|
+
{
|
|
7905
|
+
id: "crying",
|
|
7906
|
+
name: "Crying / Baby",
|
|
7907
|
+
icon: "😢"
|
|
7908
|
+
},
|
|
7909
|
+
{
|
|
7910
|
+
id: "laughter",
|
|
7911
|
+
name: "Laughter",
|
|
7912
|
+
icon: "😂"
|
|
7913
|
+
},
|
|
7914
|
+
{
|
|
7915
|
+
id: "music",
|
|
7916
|
+
name: "Music",
|
|
7917
|
+
icon: "🎵"
|
|
7918
|
+
},
|
|
7919
|
+
{
|
|
7920
|
+
id: "dog",
|
|
7921
|
+
name: "Dog",
|
|
7922
|
+
icon: "🐕"
|
|
7923
|
+
},
|
|
7924
|
+
{
|
|
7925
|
+
id: "cat",
|
|
7926
|
+
name: "Cat",
|
|
7927
|
+
icon: "🐈"
|
|
7928
|
+
},
|
|
7929
|
+
{
|
|
7930
|
+
id: "bird",
|
|
7931
|
+
name: "Bird",
|
|
7932
|
+
icon: "🐦"
|
|
7933
|
+
},
|
|
7934
|
+
{
|
|
7935
|
+
id: "animal",
|
|
7936
|
+
name: "Animal (other)",
|
|
7937
|
+
icon: "🐾"
|
|
7938
|
+
},
|
|
7939
|
+
{
|
|
7940
|
+
id: "alarm",
|
|
7941
|
+
name: "Alarm / Siren",
|
|
7942
|
+
icon: "🚨"
|
|
7943
|
+
},
|
|
7944
|
+
{
|
|
7945
|
+
id: "doorbell",
|
|
7946
|
+
name: "Doorbell / Knock",
|
|
7947
|
+
icon: "🔔"
|
|
7948
|
+
},
|
|
7949
|
+
{
|
|
7950
|
+
id: "glass_breaking",
|
|
7951
|
+
name: "Glass Breaking",
|
|
7952
|
+
icon: "💥"
|
|
7953
|
+
},
|
|
7954
|
+
{
|
|
7955
|
+
id: "gunshot",
|
|
7956
|
+
name: "Gunshot / Explosion",
|
|
7957
|
+
icon: "💣"
|
|
7958
|
+
},
|
|
7959
|
+
{
|
|
7960
|
+
id: "vehicle",
|
|
7961
|
+
name: "Vehicle",
|
|
7962
|
+
icon: "🚗"
|
|
7963
|
+
},
|
|
7964
|
+
{
|
|
7965
|
+
id: "siren",
|
|
7966
|
+
name: "Emergency Siren",
|
|
7967
|
+
icon: "🚑"
|
|
7968
|
+
},
|
|
7969
|
+
{
|
|
7970
|
+
id: "fire",
|
|
7971
|
+
name: "Fire / Smoke",
|
|
7972
|
+
icon: "🔥"
|
|
7973
|
+
},
|
|
7974
|
+
{
|
|
7975
|
+
id: "water",
|
|
7976
|
+
name: "Water",
|
|
7977
|
+
icon: "💧"
|
|
7978
|
+
},
|
|
7979
|
+
{
|
|
7980
|
+
id: "wind",
|
|
7981
|
+
name: "Wind / Weather",
|
|
7982
|
+
icon: "🌬️"
|
|
7983
|
+
},
|
|
7984
|
+
{
|
|
7985
|
+
id: "door",
|
|
7986
|
+
name: "Door",
|
|
7987
|
+
icon: "🚪"
|
|
7988
|
+
},
|
|
7989
|
+
{
|
|
7990
|
+
id: "footsteps",
|
|
7991
|
+
name: "Footsteps",
|
|
7992
|
+
icon: "👣"
|
|
7993
|
+
},
|
|
7994
|
+
{
|
|
7995
|
+
id: "crowd",
|
|
7996
|
+
name: "Crowd / Chatter",
|
|
7997
|
+
icon: "👥"
|
|
7998
|
+
},
|
|
7999
|
+
{
|
|
8000
|
+
id: "telephone",
|
|
8001
|
+
name: "Telephone",
|
|
8002
|
+
icon: "📞"
|
|
8003
|
+
},
|
|
8004
|
+
{
|
|
8005
|
+
id: "engine",
|
|
8006
|
+
name: "Engine / Motor",
|
|
8007
|
+
icon: "⚙️"
|
|
8008
|
+
},
|
|
8009
|
+
{
|
|
8010
|
+
id: "tools",
|
|
8011
|
+
name: "Tools / Construction",
|
|
8012
|
+
icon: "🔨"
|
|
8013
|
+
},
|
|
8014
|
+
{
|
|
8015
|
+
id: "silence",
|
|
8016
|
+
name: "Silence",
|
|
8017
|
+
icon: "🤫"
|
|
8018
|
+
}
|
|
8019
|
+
];
|
|
7855
8020
|
var YAMNET_TO_MACRO = {
|
|
7856
8021
|
mapping: {
|
|
7857
8022
|
Speech: "speech",
|
|
@@ -8118,6 +8283,125 @@ var _macroLookup = /* @__PURE__ */ new Map();
|
|
|
8118
8283
|
for (const [k, v] of Object.entries(YAMNET_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8119
8284
|
for (const [k, v] of Object.entries(APPLE_SA_TO_MACRO.mapping)) _macroLookup.set(k.toLowerCase(), v);
|
|
8120
8285
|
/**
|
|
8286
|
+
* Unified event-kind taxonomy — THE single source of truth for
|
|
8287
|
+
* `kind → { parentKind, category, level, color, iconId, labelKey, label,
|
|
8288
|
+
* icon }`.
|
|
8289
|
+
*
|
|
8290
|
+
* This dictionary folds together what used to be scattered across four
|
|
8291
|
+
* copies:
|
|
8292
|
+
* - `capabilities/sensor-event-kinds.ts` (sensor cap colors)
|
|
8293
|
+
* - `addon-post-analysis/.../services/event-kinds.ts`
|
|
8294
|
+
* (MOTION/PERSON/VEHICLE… _COLOR constants)
|
|
8295
|
+
* - `ui-library/composites/detection-colors.ts` (CLASS_COLORS)
|
|
8296
|
+
* - `addon-post-analysis/shared/frame/box-drawer.ts` (DEFAULT_COLOR)
|
|
8297
|
+
* - the COCO / audio class maps (macro ↔ sub relationships)
|
|
8298
|
+
*
|
|
8299
|
+
* The DATA (serializable — color/iconId/labelKey/parentKind) lives here in
|
|
8300
|
+
* `@camstack/types`. The UI-side mapping `iconId → lucide component` and
|
|
8301
|
+
* `labelKey → t()` lives in `@camstack/ui-library`. UIs never hardcode a
|
|
8302
|
+
* color or an icon: they read this dictionary (server descriptors carry the
|
|
8303
|
+
* fields inline; the client resolves color/icon/label from `iconId`/`kind`).
|
|
8304
|
+
*
|
|
8305
|
+
* Two levels only (v1 YAGNI): macro → sub. `person` is a leaf macro.
|
|
8306
|
+
*/
|
|
8307
|
+
var TAXONOMY_COLORS = {
|
|
8308
|
+
motion: "#f59e0b",
|
|
8309
|
+
audio: "#06b6d4",
|
|
8310
|
+
person: "#22c55e",
|
|
8311
|
+
vehicle: "#3b82f6",
|
|
8312
|
+
animal: "#f97316",
|
|
8313
|
+
package: "#a855f7",
|
|
8314
|
+
sensor: "#8b5cf6",
|
|
8315
|
+
control: "#10b981",
|
|
8316
|
+
genericDetection: "#64748b"
|
|
8317
|
+
};
|
|
8318
|
+
var DETECTION_SUB_COLORS = {
|
|
8319
|
+
car: "#f59e0b",
|
|
8320
|
+
truck: "#d97706",
|
|
8321
|
+
bus: "#b45309",
|
|
8322
|
+
motorcycle: "#eab308",
|
|
8323
|
+
bicycle: "#ca8a04",
|
|
8324
|
+
airplane: "#60a5fa",
|
|
8325
|
+
boat: "#2563eb",
|
|
8326
|
+
train: "#1d4ed8",
|
|
8327
|
+
bird: "#14b8a6",
|
|
8328
|
+
dog: "#84cc16",
|
|
8329
|
+
cat: "#f97316",
|
|
8330
|
+
horse: "#a16207",
|
|
8331
|
+
sheep: "#a3a3a3",
|
|
8332
|
+
cow: "#78716c",
|
|
8333
|
+
elephant: "#6b7280",
|
|
8334
|
+
bear: "#7c2d12",
|
|
8335
|
+
zebra: "#404040",
|
|
8336
|
+
giraffe: "#d4a373"
|
|
8337
|
+
};
|
|
8338
|
+
function titleCase(id) {
|
|
8339
|
+
return id.split(/[-_ ]/).filter((p) => p.length > 0).map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
8340
|
+
}
|
|
8341
|
+
var entries = /* @__PURE__ */ new Map();
|
|
8342
|
+
function macro(kind, category, color, iconId, label) {
|
|
8343
|
+
entries.set(kind, {
|
|
8344
|
+
kind,
|
|
8345
|
+
parentKind: null,
|
|
8346
|
+
level: "macro",
|
|
8347
|
+
category,
|
|
8348
|
+
color,
|
|
8349
|
+
iconId,
|
|
8350
|
+
labelKey: `eventKind.${kind}`,
|
|
8351
|
+
label
|
|
8352
|
+
});
|
|
8353
|
+
}
|
|
8354
|
+
function sub(kind, parentKind, category, color, iconId, label) {
|
|
8355
|
+
entries.set(kind, {
|
|
8356
|
+
kind,
|
|
8357
|
+
parentKind,
|
|
8358
|
+
level: "sub",
|
|
8359
|
+
category,
|
|
8360
|
+
color,
|
|
8361
|
+
iconId,
|
|
8362
|
+
labelKey: `eventKind.${kind}`,
|
|
8363
|
+
label
|
|
8364
|
+
});
|
|
8365
|
+
}
|
|
8366
|
+
macro("motion", "motion", TAXONOMY_COLORS.motion, "motion", "Motion");
|
|
8367
|
+
macro("audio", "audio", TAXONOMY_COLORS.audio, "audio", "Audio");
|
|
8368
|
+
macro("person", "detection", TAXONOMY_COLORS.person, "person", "Person");
|
|
8369
|
+
macro("vehicle", "detection", TAXONOMY_COLORS.vehicle, "vehicle", "Vehicle");
|
|
8370
|
+
macro("animal", "detection", TAXONOMY_COLORS.animal, "animal", "Animal");
|
|
8371
|
+
macro("package", "package", TAXONOMY_COLORS.package, "package", "Package");
|
|
8372
|
+
macro("sensor", "sensor", TAXONOMY_COLORS.sensor, "sensor", "Sensor");
|
|
8373
|
+
macro("control", "control", TAXONOMY_COLORS.control, "control", "Control");
|
|
8374
|
+
for (const [cocoClass, macroClass] of Object.entries(COCO_TO_MACRO.mapping)) {
|
|
8375
|
+
if (macroClass !== "vehicle" && macroClass !== "animal") continue;
|
|
8376
|
+
if (entries.has(cocoClass)) continue;
|
|
8377
|
+
sub(cocoClass, macroClass, "detection", DETECTION_SUB_COLORS[cocoClass] ?? TAXONOMY_COLORS.genericDetection, cocoClass, titleCase(cocoClass));
|
|
8378
|
+
}
|
|
8379
|
+
sub("package-delivered", "package", "package", TAXONOMY_COLORS.package, "package", "Package delivered");
|
|
8380
|
+
sub("package-picked-up", "package", "package", TAXONOMY_COLORS.package, "package", "Package picked up");
|
|
8381
|
+
sub("contact", "sensor", "sensor", "#f59e0b", "door", "Contact");
|
|
8382
|
+
sub("motion-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "pir", "Motion sensor");
|
|
8383
|
+
sub("smoke", "sensor", "sensor", "#ef4444", "smoke", "Smoke");
|
|
8384
|
+
sub("flood", "sensor", "sensor", "#3b82f6", "water", "Water leak");
|
|
8385
|
+
sub("gas", "sensor", "sensor", "#ef4444", "gas", "Gas");
|
|
8386
|
+
sub("carbon-monoxide", "sensor", "sensor", "#dc2626", "smoke", "Carbon monoxide");
|
|
8387
|
+
sub("vibration", "sensor", "sensor", "#eab308", "vibration", "Vibration");
|
|
8388
|
+
sub("tamper", "sensor", "sensor", "#f97316", "tamper", "Tamper");
|
|
8389
|
+
sub("presence", "sensor", "sensor", "#22c55e", "presence", "Presence");
|
|
8390
|
+
sub("enum-sensor", "sensor", "sensor", TAXONOMY_COLORS.sensor, "generic", "Sensor state");
|
|
8391
|
+
sub("device-event", "sensor", "sensor", "#10b981", "button", "Device event");
|
|
8392
|
+
sub("lock", "control", "control", "#0ea5e9", "lock", "Lock");
|
|
8393
|
+
sub("switch", "control", "control", TAXONOMY_COLORS.control, "switch", "Switch");
|
|
8394
|
+
sub("siren", "control", "control", "#dc2626", "siren", "Siren");
|
|
8395
|
+
sub("button", "control", "control", "#10b981", "button", "Button");
|
|
8396
|
+
sub("doorbell", "control", "control", "#a855f7", "doorbell", "Doorbell");
|
|
8397
|
+
for (const l of AUDIO_MACRO_LABELS) {
|
|
8398
|
+
const kind = `audio-${l.id}`;
|
|
8399
|
+
if (entries.has(kind)) continue;
|
|
8400
|
+
sub(kind, "audio", "audio", TAXONOMY_COLORS.audio, kind, l.name);
|
|
8401
|
+
}
|
|
8402
|
+
/** The complete taxonomy dictionary, keyed by kind. */
|
|
8403
|
+
var EVENT_TAXONOMY = Object.freeze(Object.fromEntries(entries));
|
|
8404
|
+
/**
|
|
8121
8405
|
* Error types for the safe expression engine. Two distinct classes so callers
|
|
8122
8406
|
* can tell a compile-time (grammar) failure from a runtime (evaluation)
|
|
8123
8407
|
* failure — both are non-fatal to the host: read paths degrade to "skip link".
|
|
@@ -15995,6 +16279,8 @@ var BaseDeviceProvider = class extends BaseAddon {
|
|
|
15995
16279
|
return toDeviceSummary(device, this.addonId);
|
|
15996
16280
|
}
|
|
15997
16281
|
};
|
|
16282
|
+
DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Camera, DeviceType.Hub, DeviceType.Switch, DeviceType.Siren, DeviceType.Light, DeviceType.Fan, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder;
|
|
16283
|
+
new Set(Object.values(DeviceType));
|
|
15998
16284
|
/**
|
|
15999
16285
|
* `addon-pages` — system-scoped singleton aggregator cap. Public-facing
|
|
16000
16286
|
* surface that admin-ui consumes through `useAddonPagesListPages()`.
|
|
@@ -19101,17 +19387,30 @@ var EventKindCategorySchema = _enum([
|
|
|
19101
19387
|
"audio",
|
|
19102
19388
|
"detection",
|
|
19103
19389
|
"sensor",
|
|
19390
|
+
"control",
|
|
19104
19391
|
"custom",
|
|
19105
19392
|
"package"
|
|
19106
19393
|
]);
|
|
19394
|
+
/** Taxonomy level — macro (timeline lane) vs sub (events-page leaf). */
|
|
19395
|
+
var EventKindLevelSchema = _enum(["macro", "sub"]);
|
|
19107
19396
|
var EventKindDescriptorSchema = object({
|
|
19108
|
-
/** Stable kind id (e.g. 'motion', '
|
|
19397
|
+
/** Stable kind id (e.g. 'motion', 'vehicle', 'car', 'lock'). */
|
|
19109
19398
|
kind: string(),
|
|
19399
|
+
/** i18n key resolved on the UI side; `label` is the English fallback. */
|
|
19400
|
+
labelKey: string(),
|
|
19401
|
+
/** English fallback label (kept for clients that don't translate). */
|
|
19110
19402
|
label: string(),
|
|
19111
19403
|
/** Hex color for timeline/legend rendering. */
|
|
19112
19404
|
color: string(),
|
|
19405
|
+
/** Dictionary id → lucide component on the UI side. */
|
|
19406
|
+
iconId: string(),
|
|
19407
|
+
/** Legacy closed-vocab glyph — fallback for `iconId`. */
|
|
19113
19408
|
icon: EventKindIconSchema,
|
|
19114
19409
|
category: EventKindCategorySchema,
|
|
19410
|
+
/** Macro parent for this kind ('car' → 'vehicle'); null for a macro. */
|
|
19411
|
+
parentKind: string().nullable(),
|
|
19412
|
+
/** Derived from `parentKind`, explicit for the client tree. */
|
|
19413
|
+
level: EventKindLevelSchema,
|
|
19115
19414
|
/** Which cap + device contributes this kind. For built-ins the camera
|
|
19116
19415
|
* itself; for sensor kinds the LINKED source device. */
|
|
19117
19416
|
source: object({
|
|
@@ -19184,11 +19483,21 @@ var TrackAudioLabelSchema = object({
|
|
|
19184
19483
|
firstAt: number(),
|
|
19185
19484
|
lastAt: number()
|
|
19186
19485
|
});
|
|
19486
|
+
/**
|
|
19487
|
+
* How a track was produced. `pipeline` (default / absent) = the spatial
|
|
19488
|
+
* detection+tracking pipeline. `sensor` = a SYNTHETIC track projected from a
|
|
19489
|
+
* linked sensor/control state change (no positions; carries a snapshot). The
|
|
19490
|
+
* spatial subsystems (tracker association, occupancy count, re-id/embedding,
|
|
19491
|
+
* resurrection) MUST skip `sensor` tracks — they have no bbox trajectory.
|
|
19492
|
+
*/
|
|
19493
|
+
var TrackSourceSchema = _enum(["pipeline", "sensor"]);
|
|
19187
19494
|
var TrackSchema = object({
|
|
19188
19495
|
trackId: string(),
|
|
19189
19496
|
deviceId: number(),
|
|
19190
19497
|
className: string(),
|
|
19191
19498
|
label: string().optional(),
|
|
19499
|
+
/** Track provenance. Absent ⇒ `pipeline` (legacy rows). */
|
|
19500
|
+
source: TrackSourceSchema.optional(),
|
|
19192
19501
|
firstSeen: number(),
|
|
19193
19502
|
lastSeen: number(),
|
|
19194
19503
|
/** Frame-rate position history (subject to maxPositionHistory cap). */
|
|
@@ -19565,6 +19874,76 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19565
19874
|
eventId: string(),
|
|
19566
19875
|
timestamp: number()
|
|
19567
19876
|
});
|
|
19877
|
+
/**
|
|
19878
|
+
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
19879
|
+
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
19880
|
+
* caps into per-camera event-kind descriptors.
|
|
19881
|
+
*
|
|
19882
|
+
* The descriptor DATA (color / iconId / labelKey / parentKind / category)
|
|
19883
|
+
* is NOT duplicated here — every entry is derived from the single
|
|
19884
|
+
* `EVENT_TAXONOMY` dictionary (`catalogs/event-taxonomy.ts`). This file owns
|
|
19885
|
+
* ONLY the cap-name → taxonomy-kind mapping. Adding a new eventful sensor /
|
|
19886
|
+
* control cap means adding one line here (and a taxonomy entry); the anti-
|
|
19887
|
+
* drift guard `scripts/check-event-kind-coverage.ts` fails the build if an
|
|
19888
|
+
* eventful cap is missing.
|
|
19889
|
+
*/
|
|
19890
|
+
/** Map a taxonomy `iconId` onto the legacy closed `EventKindIcon` enum. */
|
|
19891
|
+
var LEGACY_ICON = {
|
|
19892
|
+
motion: "motion",
|
|
19893
|
+
audio: "audio",
|
|
19894
|
+
person: "person",
|
|
19895
|
+
vehicle: "vehicle",
|
|
19896
|
+
animal: "animal",
|
|
19897
|
+
package: "package",
|
|
19898
|
+
door: "door",
|
|
19899
|
+
pir: "pir",
|
|
19900
|
+
smoke: "smoke",
|
|
19901
|
+
water: "water",
|
|
19902
|
+
button: "button",
|
|
19903
|
+
generic: "generic",
|
|
19904
|
+
gas: "smoke",
|
|
19905
|
+
vibration: "generic",
|
|
19906
|
+
tamper: "generic",
|
|
19907
|
+
presence: "person",
|
|
19908
|
+
lock: "generic",
|
|
19909
|
+
siren: "generic",
|
|
19910
|
+
switch: "generic",
|
|
19911
|
+
doorbell: "button"
|
|
19912
|
+
};
|
|
19913
|
+
function legacyIcon(iconId) {
|
|
19914
|
+
return LEGACY_ICON[iconId] ?? "generic";
|
|
19915
|
+
}
|
|
19916
|
+
/**
|
|
19917
|
+
* Cap name → taxonomy kind id. Covers EVERY eventful sensor / control cap.
|
|
19918
|
+
* The anti-drift guard cross-checks this against the eventful caps declared
|
|
19919
|
+
* in `packages/types/src/capabilities/*.cap.ts`.
|
|
19920
|
+
*/
|
|
19921
|
+
var CAP_TO_KIND = {
|
|
19922
|
+
contact: "contact",
|
|
19923
|
+
motion: "motion-sensor",
|
|
19924
|
+
smoke: "smoke",
|
|
19925
|
+
flood: "flood",
|
|
19926
|
+
gas: "gas",
|
|
19927
|
+
"carbon-monoxide": "carbon-monoxide",
|
|
19928
|
+
vibration: "vibration",
|
|
19929
|
+
tamper: "tamper",
|
|
19930
|
+
presence: "presence",
|
|
19931
|
+
"enum-sensor": "enum-sensor",
|
|
19932
|
+
"event-emitter": "device-event",
|
|
19933
|
+
"lock-control": "lock",
|
|
19934
|
+
switch: "switch",
|
|
19935
|
+
button: "button",
|
|
19936
|
+
doorbell: "doorbell"
|
|
19937
|
+
};
|
|
19938
|
+
function buildDescriptor(capName, kind) {
|
|
19939
|
+
const t = EVENT_TAXONOMY[kind];
|
|
19940
|
+
if (t === void 0) throw new Error(`EVENT_KIND_BY_CAP: cap '${capName}' maps to unknown taxonomy kind '${kind}'`);
|
|
19941
|
+
return {
|
|
19942
|
+
...t,
|
|
19943
|
+
icon: legacyIcon(t.iconId)
|
|
19944
|
+
};
|
|
19945
|
+
}
|
|
19946
|
+
Object.freeze(Object.fromEntries(Object.entries(CAP_TO_KIND).map(([capName, kind]) => [capName, buildDescriptor(capName, kind)])));
|
|
19568
19947
|
var CameraPipelineConfigSchema = object({
|
|
19569
19948
|
engine: PipelineEngineChoiceSchema.optional(),
|
|
19570
19949
|
steps: array(PipelineStepInputSchema).readonly(),
|
|
@@ -21190,22 +21569,6 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
21190
21569
|
var RestartAddonResultSchema = unknown();
|
|
21191
21570
|
var InstallPackageResultSchema = unknown();
|
|
21192
21571
|
var ReloadPackagesResultSchema = unknown();
|
|
21193
|
-
/**
|
|
21194
|
-
* Result of `updateFrameworkPackage`. The cap method returns BEFORE the
|
|
21195
|
-
* server restarts so the admin UI can react to the `restartingAt`
|
|
21196
|
-
* timestamp (shows reconnect overlay). The transition from
|
|
21197
|
-
* `fromVersion` to `toVersion` will be confirmed by a subsequent
|
|
21198
|
-
* `system.restart-completed` event after the new process boots.
|
|
21199
|
-
*
|
|
21200
|
-
* Spec: docs/superpowers/specs/2026-05-14-framework-live-update-design.md
|
|
21201
|
-
*/
|
|
21202
|
-
var UpdateFrameworkPackageResultSchema = object({
|
|
21203
|
-
packageName: string(),
|
|
21204
|
-
fromVersion: string(),
|
|
21205
|
-
toVersion: string(),
|
|
21206
|
-
/** Ms-epoch the server scheduled its self-restart. */
|
|
21207
|
-
restartingAt: number()
|
|
21208
|
-
});
|
|
21209
21572
|
var BulkUpdateItemStatusSchema = _enum([
|
|
21210
21573
|
"queued",
|
|
21211
21574
|
"updating",
|
|
@@ -21333,13 +21696,6 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
21333
21696
|
}), object({ success: literal(true) }), {
|
|
21334
21697
|
kind: "mutation",
|
|
21335
21698
|
auth: "admin"
|
|
21336
|
-
}), method(object({
|
|
21337
|
-
packageName: string().min(1),
|
|
21338
|
-
version: string().optional(),
|
|
21339
|
-
deferRestart: boolean().optional()
|
|
21340
|
-
}), UpdateFrameworkPackageResultSchema, {
|
|
21341
|
-
kind: "mutation",
|
|
21342
|
-
auth: "admin"
|
|
21343
21699
|
}), method(object({ name: string() }), array(PackageVersionInfoSchema).readonly()), method(object({ addonId: string() }), RestartAddonResultSchema, {
|
|
21344
21700
|
kind: "mutation",
|
|
21345
21701
|
auth: "admin"
|
|
@@ -23814,12 +24170,6 @@ Object.freeze({
|
|
|
23814
24170
|
addonId: null,
|
|
23815
24171
|
access: "delete"
|
|
23816
24172
|
},
|
|
23817
|
-
"addons.updateFrameworkPackage": {
|
|
23818
|
-
capName: "addons",
|
|
23819
|
-
capScope: "system",
|
|
23820
|
-
addonId: null,
|
|
23821
|
-
access: "create"
|
|
23822
|
-
},
|
|
23823
24173
|
"addons.updatePackage": {
|
|
23824
24174
|
capName: "addons",
|
|
23825
24175
|
capScope: "system",
|
|
@@ -28408,32 +28758,6 @@ Object.freeze({
|
|
|
28408
28758
|
"network-access": "ingress",
|
|
28409
28759
|
"smtp-provider": "email"
|
|
28410
28760
|
});
|
|
28411
|
-
var frameworkSwapPackageSchema = object({
|
|
28412
|
-
name: string(),
|
|
28413
|
-
stagedPath: string(),
|
|
28414
|
-
backupPath: string(),
|
|
28415
|
-
toVersion: string(),
|
|
28416
|
-
fromVersion: string().nullable()
|
|
28417
|
-
});
|
|
28418
|
-
object({
|
|
28419
|
-
jobId: string(),
|
|
28420
|
-
taskId: string(),
|
|
28421
|
-
packages: array(frameworkSwapPackageSchema),
|
|
28422
|
-
requestedAtMs: number(),
|
|
28423
|
-
schemaVersion: literal(1)
|
|
28424
|
-
});
|
|
28425
|
-
object({
|
|
28426
|
-
jobId: string(),
|
|
28427
|
-
taskId: string(),
|
|
28428
|
-
backups: array(object({
|
|
28429
|
-
name: string(),
|
|
28430
|
-
backupPath: string(),
|
|
28431
|
-
livePath: string()
|
|
28432
|
-
})),
|
|
28433
|
-
appliedAtMs: number(),
|
|
28434
|
-
bootAttempts: number(),
|
|
28435
|
-
schemaVersion: literal(1)
|
|
28436
|
-
});
|
|
28437
28761
|
//#endregion
|
|
28438
28762
|
//#region ../../node_modules/undici/lib/core/symbols.js
|
|
28439
28763
|
var require_symbols = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -222837,6 +223161,10 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
222837
223161
|
emitDoorbellPressed(timestamp) {
|
|
222838
223162
|
this.doorbellLastPressedAt = timestamp;
|
|
222839
223163
|
this.doorbellPressCountSinceStart += 1;
|
|
223164
|
+
this.runtimeState.setCapState(doorbellCapability.name, {
|
|
223165
|
+
lastPressedAt: timestamp,
|
|
223166
|
+
pressCountSinceStart: this.doorbellPressCountSinceStart
|
|
223167
|
+
});
|
|
222840
223168
|
this.ctx.eventBus.emit(createEvent(EventCategory.DoorbellOnPressed, this.eventSource(), {
|
|
222841
223169
|
deviceId: this.id,
|
|
222842
223170
|
timestamp
|