@camstack/addon-pipeline 1.2.614 → 1.2.616

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.
Files changed (38) hide show
  1. package/THIRD_PARTY_MODELS.md +2 -2
  2. package/dist/audio-analyzer/index.js +3 -3
  3. package/dist/audio-analyzer/index.mjs +3 -3
  4. package/dist/{custom-model-catalog-D_mgggfr.js → custom-model-catalog-D0EZW4Xb.js} +3 -3
  5. package/dist/{custom-model-catalog-CLhfiG1p.mjs → custom-model-catalog-D3NopOC9.mjs} +3 -3
  6. package/dist/detection-pipeline/index.js +114 -6
  7. package/dist/detection-pipeline/index.mjs +114 -6
  8. package/dist/{dist-BGq_y1xM.mjs → dist-BWPVIuD_.mjs} +237 -61
  9. package/dist/{dist-F6F_xjNj.js → dist-D2aJhYm7.js} +237 -61
  10. package/dist/{model-catalogs-DrUv77wD.js → model-catalogs-BDJEmiKm.js} +14 -4
  11. package/dist/{model-catalogs-CF3WVSy_.mjs → model-catalogs-CYoIeMo4.mjs} +14 -4
  12. package/dist/motion-wasm/index.js +1 -1
  13. package/dist/motion-wasm/index.mjs +1 -1
  14. package/dist/{node-D_K-84ig.js → node-BKs5_GlD.js} +1 -1
  15. package/dist/{node-DwTqHnch.mjs → node-D48F38hW.mjs} +1 -1
  16. package/dist/pipeline-runner/index.js +3 -3
  17. package/dist/pipeline-runner/index.mjs +3 -3
  18. package/dist/{process-memory-k316CseF.mjs → process-memory-58pkBnTk.mjs} +1 -1
  19. package/dist/{process-memory-BN3N6YZh.js → process-memory-BY-1p6rF.js} +1 -1
  20. package/dist/recorder/index.js +114 -11
  21. package/dist/recorder/index.mjs +114 -11
  22. package/dist/{segment-demux-js-C4-eYvhD.js → segment-demux-js-DbM8w1dc.js} +1 -1
  23. package/dist/{segment-demux-js-CWJseQHd.mjs → segment-demux-js-VeHvPIJe.mjs} +1 -1
  24. package/dist/stream-broker/_stub.js +2 -2
  25. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DrWysXZj.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-B6vm1OlX.mjs} +3 -3
  26. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-qcb2Czgh.mjs +26 -0
  27. package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BvJiBUdN.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-TnEvW5tZ.mjs} +1 -1
  28. package/dist/stream-broker/demux-worker-child.js +1 -1
  29. package/dist/stream-broker/demux-worker-child.mjs +1 -1
  30. package/dist/stream-broker/{hostInit-D5F0gL07.mjs → hostInit-BnK9Yje5.mjs} +3 -3
  31. package/dist/stream-broker/index.js +38 -5
  32. package/dist/stream-broker/index.mjs +38 -5
  33. package/dist/stream-broker/remoteEntry.js +1 -1
  34. package/package.json +1 -1
  35. package/python/inference_pool.py +33 -0
  36. package/python/openvino_compile_probe.py +245 -0
  37. package/python/test_openvino_compile_probe.py +298 -0
  38. package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-QzO03I5h.mjs +0 -26
@@ -1,5 +1,5 @@
1
1
  import { createHash } from "node:crypto";
2
- //#region ../types/dist/event-category-DOl51-Ij.mjs
2
+ //#region ../types/dist/event-category-BfJwUd2S.mjs
3
3
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4
4
  EventCategory["SystemBoot"] = "system.boot";
5
5
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -316,6 +316,15 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
316
316
  */
317
317
  EventCategory["PipelineDetectionBlind"] = "pipeline.detection-blind";
318
318
  /**
319
+ * A camera's motion source has fired constantly with no subject for an hour
320
+ * (motion duty or session count over the bar, zero detections) — it is not
321
+ * blind, its motion zones or sensitivity want tuning (D907). Paired with
322
+ * {@link PipelineMotionCalm}.
323
+ */
324
+ EventCategory["PipelineMotionNoisy"] = "pipeline.motion-noisy";
325
+ /** The recovery edge of {@link PipelineMotionNoisy}: the motion fell back, or a detection arrived. */
326
+ EventCategory["PipelineMotionCalm"] = "pipeline.motion-calm";
327
+ /**
319
328
  * Per-camera pipeline config was mutated by the orchestrator
320
329
  * (3-level settings change via `setAgentAddonDefaults` /
321
330
  * `setCameraStepToggle` / `setCameraPipelineForAgent` or a
@@ -687,6 +696,14 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
687
696
  EventCategory["BackupRestored"] = "backup.restored";
688
697
  EventCategory["NotificationDispatched"] = "notification.dispatched";
689
698
  EventCategory["NotificationFailed"] = "notification.failed";
699
+ /**
700
+ * A notification rule that cannot work (D905): its stored row does not load,
701
+ * or it still names a device / delivery target the prune CONFIRMED deleted.
702
+ * One edge per rule per distinct set of reasons; never on an unanswered read.
703
+ */
704
+ EventCategory["NotificationRuleBroken"] = "notification.rule-broken";
705
+ /** The clear of {@link NotificationRuleBroken}: the rule loads and names nothing deleted. */
706
+ EventCategory["NotificationRuleRepaired"] = "notification.rule-repaired";
690
707
  EventCategory["DeviceUpdated"] = "device.updated";
691
708
  /**
692
709
  * Transport-level connectivity. Emitted by the device driver when
@@ -5547,7 +5564,7 @@ var ZodIssueCode = {
5547
5564
  var ZodFirstPartyTypeKind;
5548
5565
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5549
5566
  //#endregion
5550
- //#region ../types/dist/sleep-_sV1BE2f.mjs
5567
+ //#region ../types/dist/sleep-DJFUfKvA.mjs
5551
5568
  /**
5552
5569
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5553
5570
  * window to float samples (D455).
@@ -8187,7 +8204,7 @@ var EntryDescriptorSchema = object({
8187
8204
  /** JSON Schema of the entry body; `secret: true` marks a password field. */
8188
8205
  fields: record(string(), unknown())
8189
8206
  }).strict();
8190
- /** What crosses the wire and sits in the engine's catalog: JSON only, no Zod. */
8207
+ /** What crosses the wire from an addon: JSON only, no Zod. An unknown key is refused. */
8191
8208
  var RecordKindDeclarationSchema = object({
8192
8209
  database: _enum(RECORD_DATABASES).default("settings"),
8193
8210
  class: _enum(RECORD_CLASSES),
@@ -8206,14 +8223,6 @@ var RecordKindDeclarationSchema = object({
8206
8223
  secretPaths: array(string().min(1)).default([]),
8207
8224
  /** The id key of each array that carries a secret (`{ headers: 'name' }`). */
8208
8225
  secretArrayKeys: record(string(), string()).default({}),
8209
- /**
8210
- * RETIRED (D900): the legacy table a kind adopted from during the records
8211
- * migration. Nothing declares it any more and nothing reads it; the schema
8212
- * still ACCEPTS it because the catalog rows the migration wrote carry it
8213
- * (an orphaned kind is never redeclared) and an addon built before the
8214
- * removal still sends it. Never set it.
8215
- */
8216
- adoptsFrom: string().min(1).optional(),
8217
8226
  /** Kinds that must agree through `transact` sit in one file under one family name. */
8218
8227
  transactFamily: string().min(1).optional(),
8219
8228
  entry: EntryDescriptorSchema.optional()
@@ -15463,17 +15472,6 @@ object({
15463
15472
  createdAt: number(),
15464
15473
  updatedAt: number()
15465
15474
  });
15466
- object({
15467
- id: string(),
15468
- label: string(),
15469
- isAdmin: boolean().default(false),
15470
- allowedProviders: AllowedProviderSchema,
15471
- allowedDevices: AllowedDevicesSchema,
15472
- tokenHash: string(),
15473
- tokenPrefix: string(),
15474
- createdAt: number(),
15475
- lastUsedAt: number().optional()
15476
- });
15477
15475
  object({
15478
15476
  id: string(),
15479
15477
  userId: string(),
@@ -19821,16 +19819,36 @@ var RecordKindStateSchema = _enum([
19821
19819
  var DeclareKindResultSchema = object({
19822
19820
  kindId: number().int(),
19823
19821
  state: RecordKindStateSchema,
19824
- createdIndexes: array(string()),
19825
- /**
19826
- * RETIRED (D900): always `null`. It carried the records-migration boot guard;
19827
- * it stays on the wire, null, because an addon built before the removal reads
19828
- * an ABSENT field as "adoption pending" and refuses to start.
19829
- */
19830
- adoptionPending: _null()
19822
+ createdIndexes: array(string())
19831
19823
  });
19832
19824
  /** Keychain refs a write released (the old marker is gone from the row): the owner deletes the values. */
19833
19825
  var SecretRefsList = array(string());
19826
+ /**
19827
+ * One op of a `transact`: the single-row writes, each on a kind of the caller.
19828
+ * All ops of one call share ONE database file and ONE `transactFamily`.
19829
+ */
19830
+ var RecordTransactOpSchema = discriminatedUnion("op", [
19831
+ object({
19832
+ op: literal("put"),
19833
+ kind: RecordKindNameSchema,
19834
+ record: RecordInputSchema,
19835
+ ifRev: number().int().min(0).optional()
19836
+ }),
19837
+ object({
19838
+ op: literal("patch"),
19839
+ kind: RecordKindNameSchema,
19840
+ id: RecordIdSchema,
19841
+ data: RecordBodySchema,
19842
+ at: number().int().nullable().optional(),
19843
+ expiresAt: number().int().nullable().optional(),
19844
+ ifRev: number().int().min(1).optional()
19845
+ }),
19846
+ object({
19847
+ op: literal("delete"),
19848
+ kind: RecordKindNameSchema,
19849
+ id: RecordIdSchema
19850
+ })
19851
+ ]);
19834
19852
  var RecordSecretRefsSchema = record(string(), record(string(), string()));
19835
19853
  method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema) }), object({ kinds: record(string(), DeclareKindResultSchema) }), {
19836
19854
  kind: "mutation",
@@ -19937,6 +19955,16 @@ method(object({ kinds: record(RecordKindNameSchema, RecordKindDeclarationSchema)
19937
19955
  }), {
19938
19956
  kind: "mutation",
19939
19957
  auth: "admin"
19958
+ }), method(object({ ops: array(RecordTransactOpSchema).min(1).max(RECORD_BATCH_MAX) }), object({
19959
+ results: array(object({
19960
+ rev: number().int().nullable(),
19961
+ deleted: boolean()
19962
+ })),
19963
+ releasedRefs: SecretRefsList,
19964
+ secretRefs: SecretRefsList
19965
+ }), {
19966
+ kind: "mutation",
19967
+ auth: "admin"
19940
19968
  }), method(object({
19941
19969
  deviceId: number().int(),
19942
19970
  kinds: array(RecordKindNameSchema).optional()
@@ -45740,9 +45768,13 @@ var NcSystemEventKindSchema = _enum([
45740
45768
  "node-updating",
45741
45769
  "node-inference-unavailable",
45742
45770
  "detection-blind",
45771
+ "motion-noisy",
45772
+ "motion-calm",
45743
45773
  "recording-stalled",
45744
45774
  "recording-healthy",
45745
45775
  "recording-degraded",
45776
+ "device-attention-required",
45777
+ "device-attention-resolved",
45746
45778
  "storage-location-low",
45747
45779
  "storage-location-critical",
45748
45780
  "storage-location-ok",
@@ -45766,6 +45798,8 @@ var NcSystemEventKindSchema = _enum([
45766
45798
  "alert-critical",
45767
45799
  "alert-error",
45768
45800
  "alert-critical-resolved",
45801
+ "rule-broken",
45802
+ "rule-repaired",
45769
45803
  "camera-online",
45770
45804
  "camera-offline",
45771
45805
  "camera-disabled",
@@ -59156,6 +59190,16 @@ object({
59156
59190
  powerState: string().nullable(),
59157
59191
  saltLevel: DishwasherConsumableLevelSchema.nullable(),
59158
59192
  rinseAidLevel: DishwasherConsumableLevelSchema.nullable(),
59193
+ /**
59194
+ * True while the appliance asks for its filter to be cleaned (smart-filter, filter-system or
59195
+ * combined care-and-filter reminder raised); false when every such reminder reads clear; null
59196
+ * when none is reported. A cleared reminder is not an unknown one.
59197
+ */
59198
+ filterCleaningDue: boolean().nullable(),
59199
+ /** True while the machine-care (descaling / cleaning-program) reminder is raised; false when clear; null when not reported. */
59200
+ machineCareDue: boolean().nullable(),
59201
+ /** Program runs left before the machine-care reminder is due; null when the appliance does not say. */
59202
+ machineCareRemainingRuns: number().int().nonnegative().nullable(),
59159
59203
  /** Option states: null when the appliance does not expose the option or has not said. */
59160
59204
  halfLoad: boolean().nullable(),
59161
59205
  hygienePlus: boolean().nullable(),
@@ -66297,16 +66341,6 @@ var UpdateUserInputSchema = object({
66297
66341
  allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
66298
66342
  scopes: array(TokenScopeSchema).optional()
66299
66343
  });
66300
- var ApiKeySummarySchema = object({
66301
- id: string(),
66302
- label: string(),
66303
- isAdmin: boolean().default(false),
66304
- allowedProviders: union([array(string()), literal("*")]).optional(),
66305
- allowedDevices: record(string(), union([array(string()), literal("*")])).optional(),
66306
- tokenPrefix: string(),
66307
- createdAt: number(),
66308
- lastUsedAt: number().optional()
66309
- });
66310
66344
  var OauthSessionSummarySchema = object({
66311
66345
  id: string(),
66312
66346
  userId: string(),
@@ -66328,8 +66362,7 @@ var TotpStatusSchema = object({
66328
66362
  confirmedAt: number().nullable()
66329
66363
  });
66330
66364
  /**
66331
- * user-management — singleton capability for user accounts and the
66332
- * legacy API-key rows.
66365
+ * user-management — singleton capability for user accounts.
66333
66366
  *
66334
66367
  * v2 model: every method gated by `auth: 'admin'`. Admin-only delegation
66335
66368
  * — the subset check on `setUserScopes` is moot
@@ -66385,10 +66418,6 @@ method(_void(), array(UserSummarySchema), { auth: "admin" }), method(CreateUserI
66385
66418
  }), UserSummarySchema.extend({ passwordHash: string() }).nullable(), {
66386
66419
  kind: "mutation",
66387
66420
  access: "view"
66388
- }), method(_void(), array(ApiKeySummarySchema), { auth: "admin" }), method(object({ id: string() }), object({ success: literal(true) }), {
66389
- kind: "mutation",
66390
- auth: "admin",
66391
- access: "delete"
66392
66421
  }), method(object({ userId: string() }), TotpSetupResultSchema, {
66393
66422
  kind: "mutation",
66394
66423
  auth: "admin",
@@ -73919,6 +73948,12 @@ Object.freeze({
73919
73948
  addonId: null,
73920
73949
  access: "view"
73921
73950
  },
73951
+ "records.transact": {
73952
+ capName: "records",
73953
+ capScope: "system",
73954
+ addonId: null,
73955
+ access: "create"
73956
+ },
73922
73957
  "sceneMonitor.captureReference": {
73923
73958
  capName: "scene-monitor",
73924
73959
  capScope: "device",
@@ -75251,12 +75286,6 @@ Object.freeze({
75251
75286
  addonId: null,
75252
75287
  access: "view"
75253
75288
  },
75254
- "userManagement.listApiKeys": {
75255
- capName: "user-management",
75256
- capScope: "system",
75257
- addonId: null,
75258
- access: "view"
75259
- },
75260
75289
  "userManagement.listExternalIdentities": {
75261
75290
  capName: "user-management",
75262
75291
  capScope: "system",
@@ -75311,12 +75340,6 @@ Object.freeze({
75311
75340
  addonId: null,
75312
75341
  access: "create"
75313
75342
  },
75314
- "userManagement.revokeApiKey": {
75315
- capName: "user-management",
75316
- capScope: "system",
75317
- addonId: null,
75318
- access: "delete"
75319
- },
75320
75343
  "userManagement.revokeOauthSession": {
75321
75344
  capName: "user-management",
75322
75345
  capScope: "system",
@@ -78731,9 +78754,13 @@ new Map(Object.entries({
78731
78754
  "stream-online": "device-events",
78732
78755
  "stream-offline": "device-events",
78733
78756
  "detection-blind": "device-events",
78757
+ "motion-noisy": "device-events",
78758
+ "motion-calm": "device-events",
78734
78759
  "recording-stalled": "device-events",
78735
78760
  "recording-healthy": "device-events",
78736
78761
  "recording-degraded": "device-events",
78762
+ "device-attention-required": "device-events",
78763
+ "device-attention-resolved": "device-events",
78737
78764
  "node-online": "system",
78738
78765
  "node-offline": "system",
78739
78766
  "node-restarting": "system",
@@ -78750,6 +78777,8 @@ new Map(Object.entries({
78750
78777
  "alert-critical": "system",
78751
78778
  "alert-error": "system",
78752
78779
  "alert-critical-resolved": "system",
78780
+ "rule-broken": "system",
78781
+ "rule-repaired": "system",
78753
78782
  "storage-location-low": "system",
78754
78783
  "storage-location-critical": "system",
78755
78784
  "storage-location-ok": "system",
@@ -78814,6 +78843,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
78814
78843
  label: "Detecting nothing",
78815
78844
  kinds: ["detection-blind"]
78816
78845
  },
78846
+ {
78847
+ id: "motion-noise",
78848
+ family: "device-events",
78849
+ label: "Motion without a subject",
78850
+ kinds: ["motion-noisy", "motion-calm"]
78851
+ },
78817
78852
  {
78818
78853
  id: "recording",
78819
78854
  family: "device-events",
@@ -78824,6 +78859,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
78824
78859
  "recording-degraded"
78825
78860
  ]
78826
78861
  },
78862
+ {
78863
+ id: "device-attention",
78864
+ family: "device-events",
78865
+ label: "Needs attention",
78866
+ kinds: ["device-attention-required", "device-attention-resolved"]
78867
+ },
78827
78868
  {
78828
78869
  id: "nodes",
78829
78870
  family: "system",
@@ -78884,6 +78925,12 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
78884
78925
  "alert-critical-resolved"
78885
78926
  ]
78886
78927
  },
78928
+ {
78929
+ id: "rule-health",
78930
+ family: "system",
78931
+ label: "Notification rules",
78932
+ kinds: ["rule-broken", "rule-repaired"]
78933
+ },
78887
78934
  {
78888
78935
  id: "alarm",
78889
78936
  family: "alarm",
@@ -78957,6 +79004,7 @@ var ALERT_EPISODE = [
78957
79004
  "alert-error",
78958
79005
  "alert-critical-resolved"
78959
79006
  ];
79007
+ var DEVICE_ATTENTION = ["device-attention-required", "device-attention-resolved"];
78960
79008
  var UPDATES = [
78961
79009
  "addon-update-available",
78962
79010
  "server-update-available",
@@ -78986,9 +79034,12 @@ var DEVICE_EVENTS = [
78986
79034
  "stream-online",
78987
79035
  "stream-offline",
78988
79036
  "detection-blind",
79037
+ "motion-noisy",
79038
+ "motion-calm",
78989
79039
  "recording-stalled",
78990
79040
  "recording-healthy",
78991
79041
  "recording-degraded",
79042
+ ...DEVICE_ATTENTION,
78992
79043
  ...ALARM
78993
79044
  ];
78994
79045
  /** Every kind a summary may speak about — the two summarisable families. */
@@ -79156,7 +79207,13 @@ var STATE_SUMMARY_VARS = [
79156
79207
  [...RULE_TEXT],
79157
79208
  [...RULE_TEXT],
79158
79209
  [...RULE_TEXT],
79159
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79210
+ [...RULE_TEXT],
79211
+ [...RULE_TEXT],
79212
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79213
+ [...RULE_TEXT],
79214
+ [...RULE_TEXT],
79215
+ [...RULE_TEXT],
79216
+ [...RULE_TEXT],
79160
79217
  [...RULE_TEXT],
79161
79218
  [...RULE_TEXT],
79162
79219
  [...RULE_TEXT],
@@ -79174,11 +79231,11 @@ var STATE_SUMMARY_VARS = [
79174
79231
  [...RULE_TEXT],
79175
79232
  [...RULE_TEXT],
79176
79233
  [...RULE_TEXT],
79234
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79177
79235
  ([...RULE_TEXT], [...ALERT_EPISODE]),
79236
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79178
79237
  ([...RULE_TEXT], [...ALERT_EPISODE]),
79179
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79180
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79181
- ([...RULE_TEXT], [...ALERT_EPISODE]),
79238
+ ([...RULE_TEXT], [...DEVICE_ATTENTION, ...ALERT_EPISODE]),
79182
79239
  [...RULE_TEXT],
79183
79240
  [...RULE_TEXT],
79184
79241
  [...RULE_TEXT],
@@ -79199,6 +79256,125 @@ var STATE_SUMMARY_VARS = [
79199
79256
  [...RULE_TEXT],
79200
79257
  ...STATE_SUMMARY_VARS
79201
79258
  ];
79259
+ new Map([
79260
+ {
79261
+ id: "device-connectivity",
79262
+ family: "device-events",
79263
+ label: "Device connectivity (offline / back online)",
79264
+ bad: ["device-offline"],
79265
+ recovery: ["device-online"],
79266
+ snapshotLabel: "Devices offline now",
79267
+ snapshotSection: "device-state"
79268
+ },
79269
+ {
79270
+ id: "device-switch",
79271
+ family: "device-events",
79272
+ label: "Device switched off / back on",
79273
+ bad: ["device-disabled"],
79274
+ recovery: ["device-enabled"],
79275
+ snapshotLabel: "Devices switched off now",
79276
+ snapshotSection: "device-state"
79277
+ },
79278
+ {
79279
+ id: "stream-connectivity",
79280
+ family: "device-events",
79281
+ label: "Stream connectivity (offline / back online)",
79282
+ bad: ["stream-offline"],
79283
+ recovery: ["stream-online"],
79284
+ snapshotLabel: "Streams offline now",
79285
+ snapshotSection: "streams"
79286
+ },
79287
+ {
79288
+ id: "battery",
79289
+ family: "device-events",
79290
+ label: "Battery (low / back to normal)",
79291
+ bad: ["device-battery-low"],
79292
+ recovery: ["device-battery-normal"],
79293
+ snapshotLabel: "Batteries low now",
79294
+ snapshotSection: "battery"
79295
+ },
79296
+ {
79297
+ id: "consumables",
79298
+ family: "device-events",
79299
+ label: "Consumables (low / replaced)",
79300
+ bad: ["device-consumable-low"],
79301
+ recovery: ["device-consumable-normal"],
79302
+ snapshotLabel: "Consumables low now",
79303
+ snapshotSection: "consumables"
79304
+ },
79305
+ {
79306
+ id: "tanks",
79307
+ family: "device-events",
79308
+ label: "Tanks (low or full / back to normal)",
79309
+ bad: ["device-tank-low", "device-tank-full"],
79310
+ recovery: ["device-tank-normal"],
79311
+ snapshotLabel: "Tanks low or full now",
79312
+ snapshotSection: "tanks"
79313
+ },
79314
+ {
79315
+ id: "motion-noise",
79316
+ family: "device-events",
79317
+ label: "Motion without a subject (constant / calm again)",
79318
+ bad: ["motion-noisy"],
79319
+ recovery: ["motion-calm"],
79320
+ snapshotLabel: "Cameras with constant motion now",
79321
+ snapshotSection: null
79322
+ },
79323
+ {
79324
+ id: "recording-health",
79325
+ family: "device-events",
79326
+ label: "Recording health (stalled or degraded / recording again)",
79327
+ bad: ["recording-stalled", "recording-degraded"],
79328
+ recovery: ["recording-healthy"],
79329
+ snapshotLabel: "Recordings stalled now",
79330
+ snapshotSection: null
79331
+ },
79332
+ {
79333
+ id: "device-attention",
79334
+ family: "device-events",
79335
+ label: "Device needs attention (raised / resolved)",
79336
+ bad: ["device-attention-required"],
79337
+ recovery: ["device-attention-resolved"],
79338
+ snapshotLabel: "Devices needing attention now",
79339
+ snapshotSection: null
79340
+ },
79341
+ {
79342
+ id: "node-connectivity",
79343
+ family: "system",
79344
+ label: "Node connectivity (offline / back online)",
79345
+ bad: ["node-offline"],
79346
+ recovery: ["node-online"],
79347
+ snapshotLabel: "Nodes offline now",
79348
+ snapshotSection: "nodes"
79349
+ },
79350
+ {
79351
+ id: "storage-space",
79352
+ family: "system",
79353
+ label: "Storage space (low or critical / ok again)",
79354
+ bad: ["storage-location-low", "storage-location-critical"],
79355
+ recovery: ["storage-location-ok"],
79356
+ snapshotLabel: "Storage locations low now",
79357
+ snapshotSection: null
79358
+ },
79359
+ {
79360
+ id: "critical-alerts",
79361
+ family: "system",
79362
+ label: "Critical alerts (raised / resolved)",
79363
+ bad: ["alert-critical"],
79364
+ recovery: ["alert-critical-resolved"],
79365
+ snapshotLabel: "Critical alerts open now",
79366
+ snapshotSection: null
79367
+ },
79368
+ {
79369
+ id: "rule-health",
79370
+ family: "system",
79371
+ label: "Rule health (broken / repaired)",
79372
+ bad: ["rule-broken"],
79373
+ recovery: ["rule-repaired"],
79374
+ snapshotLabel: "Notification rules broken now",
79375
+ snapshotSection: null
79376
+ }
79377
+ ].flatMap((spec) => [...spec.bad, ...spec.recovery].map((kind) => [kind, spec])));
79202
79378
  new Set([
79203
79379
  "disarmed",
79204
79380
  "armed_home",