@camstack/addon-post-analysis 1.2.629 → 1.2.631

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 (15) hide show
  1. package/dist/{clip-model-registry-M_QM7l6j.js → clip-model-registry-BgsEOah6.js} +542 -102
  2. package/dist/{clip-model-registry-SrfKJ0e8.mjs → clip-model-registry-DMmf5o2X.mjs} +533 -99
  3. package/dist/embedding-encoder/index.js +1 -1
  4. package/dist/embedding-encoder/index.mjs +1 -1
  5. package/dist/pipeline-analytics/_stub.js +2 -2
  6. package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-CUsaUp1g.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DkE3t99L.mjs} +2 -2
  7. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CTux2q1V.mjs +26 -0
  8. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DdbV-R1z.mjs +26 -0
  9. package/dist/pipeline-analytics/{hostInit-q1u97PmF.mjs → hostInit-JabXipp8.mjs} +2 -2
  10. package/dist/pipeline-analytics/index.js +8620 -6817
  11. package/dist/pipeline-analytics/index.mjs +8619 -6816
  12. package/dist/pipeline-analytics/remoteEntry.js +1 -1
  13. package/package.json +1 -1
  14. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DxapkUgD.mjs +0 -26
  15. package/dist/pipeline-analytics/_virtual_mf___mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-D7KeW_uB.mjs +0 -26
@@ -30,7 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  }) : target, mod));
31
31
  //#endregion
32
32
  let node_crypto = require("node:crypto");
33
- //#region ../types/dist/event-category-fDPduoeC.mjs
33
+ //#region ../types/dist/event-category-Ceif8n-v.mjs
34
34
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
35
35
  EventCategory["SystemBoot"] = "system.boot";
36
36
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -502,6 +502,10 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
502
502
  * on the device detail page.
503
503
  */
504
504
  EventCategory["DoorbellOnPressed"] = "doorbell.onPressed";
505
+ /** Mirrors `runningStateCapability.events.onStarted`. */
506
+ EventCategory["RunningStarted"] = "running.started";
507
+ /** Mirrors `runningStateCapability.events.onFinished`. */
508
+ EventCategory["RunningFinished"] = "running.finished";
505
509
  /**
506
510
  * Cap event fired by every device that registers the `event-emitter`
507
511
  * capability. Mirrors `eventEmitterCapability.events.onEvent`. Carries
@@ -5659,7 +5663,7 @@ var ZodIssueCode = {
5659
5663
  var ZodFirstPartyTypeKind;
5660
5664
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5661
5665
  //#endregion
5662
- //#region ../types/dist/sleep-CHIEEJkY.mjs
5666
+ //#region ../types/dist/sleep-CYfIZzGv.mjs
5663
5667
  /**
5664
5668
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5665
5669
  * window to float samples (D455).
@@ -5998,7 +6002,7 @@ Object.fromEntries([
5998
6002
  * `hydrateSchema` to skip the `value` injection for structural-only fields.
5999
6003
  */
6000
6004
  function isValuelessField(field) {
6001
- return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button";
6005
+ return field.type === "separator" || field.type === "info" || field.type === "qr-code" || field.type === "button" || field.type === "object-array" || field.type === "widget" || field.type === "addon-action-button" || field.type === "device-action-button" || field.type === "account-sign-in" || field.type === "secret-presence";
6002
6006
  }
6003
6007
  function hydrateSchema(schema, values, options = {}) {
6004
6008
  return {
@@ -8916,7 +8920,7 @@ method(object({ deviceId: number() }), array(StreamSourceEntrySchema)), method(o
8916
8920
  * can answer "may a rule actuate this?" without importing the schema barrel
8917
8921
  * (~144MB RSS per runner, D28).
8918
8922
  *
8919
- * Coverage: 90 device-scoped capabilities.
8923
+ * Coverage: 91 device-scoped capabilities.
8920
8924
  */
8921
8925
  var DEVICE_SCOPED_CAPS = new Set([
8922
8926
  "accessories",
@@ -8988,6 +8992,7 @@ var DEVICE_SCOPED_CAPS = new Set([
8988
8992
  "recording",
8989
8993
  "recording-onboard",
8990
8994
  "recording-signal",
8995
+ "running-state",
8991
8996
  "scene-monitor",
8992
8997
  "script-runner",
8993
8998
  "smoke",
@@ -9407,7 +9412,7 @@ function errMsg(err) {
9407
9412
  return String(err);
9408
9413
  }
9409
9414
  //#endregion
9410
- //#region ../types/dist/composition-CB6PMT9p.mjs
9415
+ //#region ../types/dist/composition-BJ8iAZb3.mjs
9411
9416
  /**
9412
9417
  * Deterministic SHA-256 hash of an arbitrary serialisable value. The
9413
9418
  * canonical form sorts object keys alphabetically at every depth so two
@@ -9498,7 +9503,7 @@ portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac
9498
9503
  * ONE table for everyone who asks "is this device HIGH?": the
9499
9504
  * recorder's `RecordingTriggers.sensorDeviceIds` trigger, the post-analysis
9500
9505
  * sensor markers, the orchestrator's camera-sensors bridge and
9501
- * the sources of a composite doorbell (`doorbellFeatureSources`, D671).
9506
+ * the sources of a pulse (`compilePulseOverride`, D936).
9502
9507
  * A second copy would diverge at the first cap added, and the symptom — "the
9503
9508
  * sensor rings the doorbell but does not record" — is exactly D62.
9504
9509
  *
@@ -9868,6 +9873,20 @@ var table = {
9868
9873
  apply: () => {
9869
9874
  throw new ExpressionEvalError("count: stateful evaluation context is required");
9870
9875
  }
9876
+ },
9877
+ dwell: {
9878
+ minArgs: 3,
9879
+ maxArgs: 3,
9880
+ apply: () => {
9881
+ throw new ExpressionEvalError("dwell: stateful evaluation context is required");
9882
+ }
9883
+ },
9884
+ latchedAt: {
9885
+ minArgs: 1,
9886
+ maxArgs: 1,
9887
+ apply: () => {
9888
+ throw new ExpressionEvalError("latchedAt: stateful evaluation context is required");
9889
+ }
9871
9890
  }
9872
9891
  };
9873
9892
  Object.freeze(Object.assign(Object.create(null), table));
@@ -17600,7 +17619,15 @@ Object.freeze({
17600
17619
  kind: "fixed",
17601
17620
  result: ["number", "null"]
17602
17621
  },
17603
- count: NUMBER
17622
+ count: NUMBER,
17623
+ dwell: {
17624
+ kind: "fixed",
17625
+ result: ["boolean", "null"]
17626
+ },
17627
+ latchedAt: {
17628
+ kind: "fixed",
17629
+ result: ["number", "null"]
17630
+ }
17604
17631
  });
17605
17632
  `${COMPOSED_DEVICE_STABLE_ID_PREFIX}`;
17606
17633
  /**
@@ -44184,9 +44211,6 @@ var NcSystemEventKindSchema = _enum([
44184
44211
  "device-battery-normal",
44185
44212
  "device-consumable-low",
44186
44213
  "device-consumable-normal",
44187
- "device-tank-low",
44188
- "device-tank-full",
44189
- "device-tank-normal",
44190
44214
  "stream-online",
44191
44215
  "stream-offline",
44192
44216
  "node-online",
@@ -44233,13 +44257,14 @@ var NcSystemEventKindSchema = _enum([
44233
44257
  "camera-enabled"
44234
44258
  ]);
44235
44259
  /** The legacy tail of {@link NcSystemEventKindSchema} — see its docblock. */
44236
- var NC_LEGACY_SYSTEM_EVENT_KINDS = new Set([
44260
+ var NC_LEGACY_SYSTEM_EVENT_KINDS = [
44237
44261
  "camera-online",
44238
44262
  "camera-offline",
44239
44263
  "camera-disabled",
44240
44264
  "camera-enabled"
44241
- ]);
44242
- NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KINDS.has(kind));
44265
+ ];
44266
+ var NC_LEGACY_SYSTEM_EVENT_KIND_SET = new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
44267
+ NcSystemEventKindSchema.options.filter((kind) => !NC_LEGACY_SYSTEM_EVENT_KIND_SET.has(kind));
44243
44268
  /**
44244
44269
  * The panel's transitions, as ONE list.
44245
44270
  *
@@ -44269,12 +44294,6 @@ var NC_ALARM_SYSTEM_EVENT_KINDS = [
44269
44294
  * and both editors read it.
44270
44295
  */
44271
44296
  var NC_CONSUMABLE_SYSTEM_EVENT_KINDS = ["device-consumable-low", "device-consumable-normal"];
44272
- /** A vacuum's tank alerts (D642) — raised on the provider's own verdict. */
44273
- var NC_TANK_SYSTEM_EVENT_KINDS = [
44274
- "device-tank-low",
44275
- "device-tank-full",
44276
- "device-tank-normal"
44277
- ];
44278
44297
  /**
44279
44298
  * The consumable threshold a rule that does not state one judges at (D642).
44280
44299
  * The operator's number ("default 15 %, configurable on the rule"), and the
@@ -45450,18 +45469,18 @@ var NcRuleSchema = NcRuleInputSchema.extend({
45450
45469
  * `addon-updates` the addons that are behind (D708 split them). `backups-exports` and `alarm` are not sections — a completed
45451
45470
  * job is not an open state, and the alarm stays instant.
45452
45471
  */
45453
- var NcStateSummarySectionIdSchema = _enum([
45472
+ var NC_STATE_SUMMARY_SECTION_IDS = [
45454
45473
  "device-state",
45455
45474
  "streams",
45456
45475
  "battery",
45457
45476
  "consumables",
45458
- "tanks",
45459
45477
  "detection-blind",
45460
45478
  "nodes",
45461
45479
  "addons",
45462
45480
  "addon-updates",
45463
45481
  "updates"
45464
- ]);
45482
+ ];
45483
+ var NcStateSummarySectionIdSchema = _enum(NC_STATE_SUMMARY_SECTION_IDS);
45465
45484
  /** One section of a previewed state summary. `unavailable` = its state could not be read. */
45466
45485
  var NcStateSummaryPreviewSectionSchema = object({
45467
45486
  id: NcStateSummarySectionIdSchema,
@@ -45836,18 +45855,6 @@ var NC_CONDITION_CATALOG = [
45836
45855
  value: "device-consumable-normal",
45837
45856
  label: "Consumable replaced"
45838
45857
  },
45839
- {
45840
- value: "device-tank-low",
45841
- label: "Tank low (water, detergent)"
45842
- },
45843
- {
45844
- value: "device-tank-full",
45845
- label: "Tank full (dirty water, dust)"
45846
- },
45847
- {
45848
- value: "device-tank-normal",
45849
- label: "Tank back to normal"
45850
- },
45851
45858
  {
45852
45859
  value: "export-completed",
45853
45860
  label: "Export completed"
@@ -57846,20 +57853,68 @@ var BatteryStatusSchema = object({
57846
57853
  */
57847
57854
  binary: boolean().optional()
57848
57855
  });
57856
+ var BATTERY_DEVICE_TYPES = [
57857
+ DeviceType.Camera,
57858
+ DeviceType.Sensor,
57859
+ DeviceType.Button,
57860
+ DeviceType.Switch,
57861
+ DeviceType.PetFeeder,
57862
+ DeviceType.Container,
57863
+ DeviceType.Thermostat
57864
+ ];
57865
+ /** Generic Customize target for the percentage reading (D936). */
57866
+ var batteryCustomize = {
57867
+ version: 1,
57868
+ targets: [{
57869
+ id: "percentage",
57870
+ cardinality: "scalar",
57871
+ vocabulary: {
57872
+ cap: "battery",
57873
+ stateField: "percentage"
57874
+ },
57875
+ deviceTypes: BATTERY_DEVICE_TYPES,
57876
+ apply: "add-or-replace",
57877
+ path: "percentage",
57878
+ sources: [{
57879
+ kind: "field",
57880
+ valueKinds: ["number", "string"],
57881
+ transforms: [{ kind: "identity" }, {
57882
+ kind: "linear",
57883
+ defaultScale: 1,
57884
+ defaultOffset: 0,
57885
+ clampMin: 0,
57886
+ clampMax: 100
57887
+ }]
57888
+ }],
57889
+ companions: [
57890
+ {
57891
+ kind: "constant",
57892
+ path: "charging",
57893
+ value: "unknown",
57894
+ when: "add"
57895
+ },
57896
+ {
57897
+ kind: "constant",
57898
+ path: "sleeping",
57899
+ value: false,
57900
+ when: "add"
57901
+ },
57902
+ {
57903
+ kind: "clock",
57904
+ path: "lastUpdated",
57905
+ when: "add"
57906
+ }
57907
+ ],
57908
+ sourceReport: { status: "assignment-status" },
57909
+ advancedExpression: true
57910
+ }]
57911
+ };
57849
57912
  var batteryCapability = {
57850
57913
  name: "battery",
57851
57914
  scope: "device",
57852
57915
  deviceNative: true,
57853
57916
  mode: "singleton",
57854
- deviceTypes: [
57855
- DeviceType.Camera,
57856
- DeviceType.Sensor,
57857
- DeviceType.Button,
57858
- DeviceType.Switch,
57859
- DeviceType.PetFeeder,
57860
- DeviceType.Container,
57861
- DeviceType.Thermostat
57862
- ],
57917
+ deviceTypes: BATTERY_DEVICE_TYPES,
57863
57918
  methods: {
57864
57919
  /**
57865
57920
  * Explicitly wake the camera from low-power sleep ahead of a
@@ -57943,6 +57998,7 @@ onStatusChanged: { data: object({
57943
57998
  kind: "gauge",
57944
57999
  unit: "%"
57945
58000
  } } },
58001
+ customize: batteryCustomize,
57946
58002
  /** Clock fields: written, but excluded from the compare that decides
57947
58003
  * whether persisting is worth a SQLite commit. */
57948
58004
  volatileStateFields: ["lastUpdated"]
@@ -58887,6 +58943,20 @@ _enum([
58887
58943
  "empty",
58888
58944
  "full"
58889
58945
  ]);
58946
+ /** The kind of an item, with the documented default for an absent one. */
58947
+ function consumableKindOf(item) {
58948
+ return item.kind ?? "wear";
58949
+ }
58950
+ /** The kind's default form: wear → part, waste → bin, supply → product. */
58951
+ var FORM_OF_KIND = {
58952
+ wear: "part",
58953
+ waste: "bin",
58954
+ supply: "product"
58955
+ };
58956
+ /** The form of an item: its own when the provider names one, else its kind's default. */
58957
+ function consumableFormOf(item) {
58958
+ return item.form ?? FORM_OF_KIND[consumableKindOf(item)];
58959
+ }
58890
58960
  /** Units a remaining-life counter is reported in. Closed: the panel renders
58891
58961
  * each. */
58892
58962
  var ConsumableRemainingUnitSchema = _enum([
@@ -58930,6 +59000,106 @@ var ConsumablesStatusSchema = object({
58930
59000
  items: array(ConsumableItemSchema),
58931
59001
  lastChangedAt: number()
58932
59002
  });
59003
+ /** Synthesize seed for a link-built status (no native provider).
59004
+ *
59005
+ * ⚠ NO LIVE CALLER since 2026-08-08 (device-links deleted; see
59006
+ * `CapabilityStatusSchema.empty`). The wiring guidance below was written for
59007
+ * exactly the case the operator is asking about again — a Dreame's HA
59008
+ * consumable-life sensors — so it is kept for that conversation, not because
59009
+ * anything reads it today. */
59010
+ var EMPTY_STATUS = {
59011
+ items: [],
59012
+ lastChangedAt: 0
59013
+ };
59014
+ /** Seed for a NEW link-built consumable item. `key`/`label` are overwritten
59015
+ * with the link's `itemKey` (see `status.itemArray`), so the placeholder
59016
+ * empty strings never survive into a validated item. Link-built items are
59017
+ * not resettable — there is no native provider to receive `reset()`.
59018
+ *
59019
+ * Wiring guidance (HA vacuum consumable-life sensors):
59020
+ * - a percent-remaining source (`numeric-sensor`, unit '%') → `level` via
59021
+ * `identity` (or `linear` scale 1 offset 0 clamp [0,100] to be safe);
59022
+ * - an hours-remaining source (e.g. Dreame 'Main Brush Time Left', unit 'h')
59023
+ * → `level` via `linear` with scale = 100 / max-hours for that item
59024
+ * (e.g. main brush 300 h → scale 0.3333) + clamp [0,100];
59025
+ * - a discrete source (`enum-sensor`, e.g. mop pad 'installed') → `status`
59026
+ * via `enum-map` (e.g. { installed: 'ok', missing: 'replace' }).
59027
+ * A numeric→'replace' THRESHOLD (level < 10 → 'replace') is NOT expressible
59028
+ * with the current transform kinds — leave `status` null (valid) until the
59029
+ * expression transform lands. */
59030
+ /** Generic Customize target for one consumable item (D936). Native rows stay read-only. */
59031
+ var consumablesCustomize = {
59032
+ version: 1,
59033
+ targets: [{
59034
+ id: "items",
59035
+ cardinality: "keyedArray",
59036
+ vocabulary: { cap: "consumables" },
59037
+ deviceTypes: Object.values(DeviceType),
59038
+ apply: "add",
59039
+ path: "items",
59040
+ keyField: "key",
59041
+ labelField: "label",
59042
+ itemSchema: ConsumableItemSchema,
59043
+ nativeItems: "read-only",
59044
+ sourceReport: { status: "assignment-status" },
59045
+ fields: [
59046
+ {
59047
+ path: "level",
59048
+ sources: [{
59049
+ kind: "numeric",
59050
+ transforms: [{ kind: "identity" }, {
59051
+ kind: "linear",
59052
+ defaultScale: 1,
59053
+ defaultOffset: 0,
59054
+ clampMin: 0,
59055
+ clampMax: 100
59056
+ }]
59057
+ }]
59058
+ },
59059
+ {
59060
+ path: "remaining.value",
59061
+ sources: [{
59062
+ kind: "numeric",
59063
+ transforms: [{ kind: "identity" }]
59064
+ }],
59065
+ literals: [{
59066
+ path: "remaining.unit",
59067
+ values: [...ConsumableRemainingUnitSchema.options]
59068
+ }]
59069
+ },
59070
+ {
59071
+ path: "status",
59072
+ sources: [{
59073
+ kind: "enum",
59074
+ transforms: [{
59075
+ kind: "enum-map",
59076
+ outputValues: [...ConsumableStatusSchema.options],
59077
+ unmapped: null
59078
+ }]
59079
+ }]
59080
+ }
59081
+ ],
59082
+ traits: [{
59083
+ path: "kind",
59084
+ values: [...ConsumableKindSchema.options],
59085
+ defaultValue: "wear"
59086
+ }, {
59087
+ path: "form",
59088
+ values: [...ConsumableFormSchema.options],
59089
+ defaultValue: "part"
59090
+ }],
59091
+ companions: [{
59092
+ kind: "clock",
59093
+ path: "lastChangedAt",
59094
+ when: "add"
59095
+ }, {
59096
+ kind: "clock",
59097
+ path: "lastFetchedAt",
59098
+ when: "add"
59099
+ }],
59100
+ advancedExpression: true
59101
+ }]
59102
+ };
58933
59103
  var consumablesCapability = {
58934
59104
  name: "consumables",
58935
59105
  scope: "device",
@@ -58967,10 +59137,7 @@ reset: method(object({
58967
59137
  status: {
58968
59138
  schema: ConsumablesStatusSchema,
58969
59139
  kind: "push",
58970
- empty: {
58971
- items: [],
58972
- lastChangedAt: 0
58973
- },
59140
+ empty: EMPTY_STATUS,
58974
59141
  itemArray: {
58975
59142
  path: "items",
58976
59143
  keyField: "key",
@@ -59006,6 +59173,7 @@ reset: method(object({
59006
59173
  * brush's remaining life and a dishwasher's salt are each recorded the moment
59007
59174
  * their provider reports them; an item that appears later gets its series.
59008
59175
  */
59176
+ customize: consumablesCustomize,
59009
59177
  history: {
59010
59178
  fields: {},
59011
59179
  items: {
@@ -59770,6 +59938,36 @@ var dishwasherCapability = {
59770
59938
  powerOn: { kind: "boolean" }
59771
59939
  } }
59772
59940
  };
59941
+ /** Pulse override: a rising edge advances `lastPressedAt` and the press count. */
59942
+ var doorbellCustomize = {
59943
+ version: 1,
59944
+ targets: [{
59945
+ id: "pressed",
59946
+ cardinality: "event",
59947
+ shape: "pulse",
59948
+ vocabulary: {
59949
+ cap: "doorbell",
59950
+ eventName: "onPressed"
59951
+ },
59952
+ deviceTypes: [DeviceType.Camera],
59953
+ apply: "add",
59954
+ applyAuthority: { kind: "composition-claim" },
59955
+ eventName: "onPressed",
59956
+ edges: ["rising"],
59957
+ timestampPath: "lastPressedAt",
59958
+ counterPath: "pressCountSinceStart",
59959
+ highWater: "composer-advance",
59960
+ combine: "any",
59961
+ debounce: {
59962
+ kind: "rising-edge",
59963
+ defaultDebounceMs: 2e3,
59964
+ changedAtRequired: true
59965
+ },
59966
+ sources: [{ kind: "binary" }, { kind: "switch" }],
59967
+ sourceReport: { status: "assignment-status" },
59968
+ advancedExpression: true
59969
+ }]
59970
+ };
59773
59971
  var DoorbellStatusSchema = object({
59774
59972
  /** Ms epoch of the last press. null = never observed since this provider started. */
59775
59973
  lastPressedAt: number().nullable(),
@@ -59836,7 +60034,8 @@ onPressed: {
59836
60034
  /**
59837
60035
  * History (D850): none — `pressCountSinceStart` resets with the addon, so it is not a monotonic meter; presses live in the events ledger.
59838
60036
  */
59839
- history: "none"
60037
+ history: "none",
60038
+ customize: doorbellCustomize
59840
60039
  };
59841
60040
  /**
59842
60041
  * Enum-state sensor — a string value picked from a finite option set.
@@ -62293,6 +62492,38 @@ authKey: string().optional() }), object({
62293
62492
  /** Human-readable error when `ok: false`. */
62294
62493
  error: string().optional()
62295
62494
  }), { kind: "mutation" });
62495
+ /** Span override: start on a rising edge, end on a fall or this timeout. */
62496
+ var motionCustomize = {
62497
+ version: 1,
62498
+ targets: [{
62499
+ id: "detected",
62500
+ cardinality: "event",
62501
+ shape: "span",
62502
+ vocabulary: {
62503
+ cap: "motion",
62504
+ eventName: "onMotionChanged"
62505
+ },
62506
+ deviceTypes: [DeviceType.Camera],
62507
+ apply: "replace",
62508
+ applyAuthority: {
62509
+ kind: "camera-sensors",
62510
+ timeoutField: "motionCooldownMs"
62511
+ },
62512
+ eventName: "onMotionChanged",
62513
+ start: "rising-edge",
62514
+ end: "falling-edge-or-timeout",
62515
+ timeoutMs: 3e4,
62516
+ combine: "any",
62517
+ sourceModes: [
62518
+ "in-addition",
62519
+ "confirm",
62520
+ "replace"
62521
+ ],
62522
+ sources: [{ kind: "binary" }, { kind: "switch" }],
62523
+ sourceReport: { status: "assignment-status" },
62524
+ advancedExpression: false
62525
+ }]
62526
+ };
62296
62527
  /**
62297
62528
  * Hardware / firmware motion sensor cap — binary detected state plus
62298
62529
  * a timestamp of the last observation. Distinct from
@@ -62457,7 +62688,8 @@ onMotionChanged: { data: MotionOnMotionChangedDataSchema } },
62457
62688
  history: { fields: { detected: {
62458
62689
  kind: "boolean",
62459
62690
  excludeDeviceTypes: [DeviceType.Camera]
62460
- } } }
62691
+ } } },
62692
+ customize: motionCustomize
62461
62693
  };
62462
62694
  /**
62463
62695
  * Motion-trigger toggle for accessory devices.
@@ -65218,6 +65450,125 @@ var ptzAutotrackCapability = {
65218
65450
  */
65219
65451
  history: "none"
65220
65452
  };
65453
+ var RUNNING_POWER_START_DELAY_MS = 3e4;
65454
+ var RUNNING_POWER_STOP_DELAY_MS = 18e4;
65455
+ var RunningStateSourceSchema = _enum(["native", "assigned"]);
65456
+ var RunningStateStatusSchema = object({
65457
+ /** null = unknown — never coerced to false (D393). */
65458
+ running: boolean().nullable(),
65459
+ /** Epoch ms the current boolean began; null while `running` is null. */
65460
+ since: number().nullable(),
65461
+ source: RunningStateSourceSchema,
65462
+ phase: string().nullable(),
65463
+ /** null until a reading has been published (D393). */
65464
+ lastFetchedAt: number().nullable()
65465
+ });
65466
+ var RunningFlipEventDataSchema = object({
65467
+ deviceId: number(),
65468
+ since: number().nullable(),
65469
+ phase: string().nullable()
65470
+ });
65471
+ var RUNNING_DEVICE_TYPES = Object.values(DeviceType);
65472
+ /** Generic Customize target for the running boolean (D936). */
65473
+ var runningCustomize = {
65474
+ version: 1,
65475
+ targets: [{
65476
+ id: "running",
65477
+ cardinality: "scalar",
65478
+ vocabulary: {
65479
+ cap: "running-state",
65480
+ stateField: "running"
65481
+ },
65482
+ deviceTypes: [
65483
+ DeviceType.Dishwasher,
65484
+ DeviceType.Vacuum,
65485
+ DeviceType.LawnMower,
65486
+ DeviceType.MediaPlayer,
65487
+ DeviceType.WaterHeater,
65488
+ DeviceType.Humidifier,
65489
+ DeviceType.Fan,
65490
+ DeviceType.Climate,
65491
+ DeviceType.Thermostat,
65492
+ DeviceType.PetFeeder
65493
+ ],
65494
+ apply: "add-or-replace",
65495
+ path: "running",
65496
+ sources: [
65497
+ {
65498
+ kind: "switch",
65499
+ transforms: [{ kind: "identity" }]
65500
+ },
65501
+ {
65502
+ kind: "binary",
65503
+ transforms: [{ kind: "identity" }, { kind: "invert" }]
65504
+ },
65505
+ {
65506
+ kind: "numeric",
65507
+ requiredUnit: "W",
65508
+ transforms: [{
65509
+ kind: "threshold",
65510
+ comparison: "gte",
65511
+ defaultThreshold: 5,
65512
+ defaultStartDwellMs: RUNNING_POWER_START_DELAY_MS,
65513
+ defaultStopDwellMs: RUNNING_POWER_STOP_DELAY_MS,
65514
+ thresholdUnit: "W"
65515
+ }]
65516
+ }
65517
+ ],
65518
+ companions: [
65519
+ {
65520
+ kind: "constant",
65521
+ path: "source",
65522
+ value: "assigned",
65523
+ when: "always"
65524
+ },
65525
+ {
65526
+ kind: "constant",
65527
+ path: "phase",
65528
+ value: null,
65529
+ when: "always"
65530
+ },
65531
+ {
65532
+ kind: "clock",
65533
+ path: "lastFetchedAt",
65534
+ when: "always"
65535
+ },
65536
+ {
65537
+ kind: "transition-time",
65538
+ path: "since",
65539
+ sourceChangedAt: "prefer"
65540
+ }
65541
+ ],
65542
+ sourceReport: {
65543
+ status: "assignment-status",
65544
+ runtimeField: "source",
65545
+ nativeValue: "native",
65546
+ assignedValue: "assigned"
65547
+ },
65548
+ advancedExpression: true
65549
+ }]
65550
+ };
65551
+ var runningStateCapability = {
65552
+ name: "running-state",
65553
+ scope: "device",
65554
+ deviceNative: true,
65555
+ mode: "singleton",
65556
+ deviceTypes: RUNNING_DEVICE_TYPES,
65557
+ methods: {},
65558
+ events: {
65559
+ onStarted: { data: RunningFlipEventDataSchema },
65560
+ onFinished: { data: RunningFlipEventDataSchema }
65561
+ },
65562
+ status: {
65563
+ schema: RunningStateStatusSchema,
65564
+ kind: "push"
65565
+ },
65566
+ runtimeState: RunningStateStatusSchema,
65567
+ durability: "restored",
65568
+ history: { fields: { running: { kind: "boolean" } } },
65569
+ volatileStateFields: ["lastFetchedAt"],
65570
+ customize: runningCustomize
65571
+ };
65221
65572
  DeviceType.Camera, DeviceType.Sensor, DeviceType.Switch, method(object({ deviceId: number().int().nonnegative() }), object({ success: literal(true) }), {
65222
65573
  kind: "mutation",
65223
65574
  auth: "admin"
@@ -70302,6 +70653,7 @@ var DEVICE_LOCAL_STATE_CAPS = {
70302
70653
  ptzAutotrack: ptzAutotrackCapability,
70303
70654
  recordingOnboard: recordingOnboardCapability,
70304
70655
  recordingSignal: recordingSignalCapability,
70656
+ runningState: runningStateCapability,
70305
70657
  sceneMonitor: sceneMonitorCapability,
70306
70658
  scriptRunner: scriptRunnerCapability,
70307
70659
  smoke: smokeCapability,
@@ -78561,6 +78913,13 @@ Object.freeze({
78561
78913
  access: "create",
78562
78914
  role: "admin"
78563
78915
  },
78916
+ "runningState.getStatus": {
78917
+ capName: "running-state",
78918
+ capScope: "device",
78919
+ addonId: null,
78920
+ access: "view",
78921
+ role: "viewer"
78922
+ },
78564
78923
  "sceneMonitor.captureReference": {
78565
78924
  capName: "scene-monitor",
78566
78925
  capScope: "device",
@@ -83275,6 +83634,32 @@ var APPLIANCE_CAP_VOCABULARY = {
83275
83634
  }],
83276
83635
  events: { onSent: { notOperatorFacing: "a delivery receipt of a send this system made — not a fact about the world" } }
83277
83636
  },
83637
+ "running-state": {
83638
+ scope: "device",
83639
+ noun: t("Running", "In funzione"),
83640
+ state: [{
83641
+ kind: "boolean",
83642
+ field: "running",
83643
+ label: t("Running", "In funzione"),
83644
+ whenTrue: t("When {device} starts", "Quando {device} inizia"),
83645
+ whenFalse: t("When {device} finishes", "Quando {device} finisce"),
83646
+ icon: "play"
83647
+ }],
83648
+ events: {
83649
+ onStarted: {
83650
+ category: EventCategory.RunningStarted,
83651
+ label: t("Started running", "Ha iniziato a funzionare"),
83652
+ phrase: t("When {device} starts running", "Quando {device} inizia a funzionare"),
83653
+ icon: "play"
83654
+ },
83655
+ onFinished: {
83656
+ category: EventCategory.RunningFinished,
83657
+ label: t("Finished", "Ha finito"),
83658
+ phrase: t("When {device} finishes", "Quando {device} finisce"),
83659
+ icon: "square"
83660
+ }
83661
+ }
83662
+ },
83278
83663
  update: {
83279
83664
  scope: "device",
83280
83665
  noun: t("Firmware update", "Aggiornamento firmware"),
@@ -86815,6 +87200,11 @@ Object.freeze({
86815
87200
  form: "single",
86816
87201
  optional: true
86817
87202
  }],
87203
+ "runningState.getStatus": [{
87204
+ name: "deviceId",
87205
+ form: "single",
87206
+ optional: false
87207
+ }],
86818
87208
  "sceneMonitor.captureReference": [{
86819
87209
  name: "deviceId",
86820
87210
  form: "single",
@@ -87410,6 +87800,96 @@ var BucketAccumulator = class {
87410
87800
  }
87411
87801
  };
87412
87802
  DeviceType.Camera;
87803
+ DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat, DeviceType.Camera, DeviceType.Hub, DeviceType.Light, DeviceType.Siren, DeviceType.Switch, DeviceType.Sensor, DeviceType.Thermostat, DeviceType.Climate, DeviceType.Button, DeviceType.EventEmitter, DeviceType.Update, DeviceType.Generic, DeviceType.Notifier, DeviceType.Script, DeviceType.Automation, DeviceType.Lock, DeviceType.Cover, DeviceType.Valve, DeviceType.Humidifier, DeviceType.WaterHeater, DeviceType.Fan, DeviceType.MediaPlayer, DeviceType.AlarmPanel, DeviceType.Control, DeviceType.Presence, DeviceType.Weather, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.Container, DeviceType.Image, DeviceType.PetFeeder, DeviceType.Dishwasher, DeviceType.Camera, DeviceType.Camera, DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder;
87804
+ /**
87805
+ * A saved Customize assignment (D936). The schema is the type: callers use
87806
+ * `z.infer`, they do not restate the shape.
87807
+ */
87808
+ var OverrideSourceSchema = object({
87809
+ addonId: string().min(1),
87810
+ stableId: string().min(1),
87811
+ cap: string().min(1),
87812
+ fieldPath: string().min(1)
87813
+ });
87814
+ var CustomizeTransformDraftSchema = discriminatedUnion("kind", [
87815
+ object({ kind: literal("identity") }),
87816
+ object({ kind: literal("invert") }),
87817
+ object({
87818
+ kind: literal("threshold"),
87819
+ comparison: _enum(["gte", "lte"]),
87820
+ threshold: number(),
87821
+ startDwellMs: number().nonnegative(),
87822
+ stopDwellMs: number().nonnegative()
87823
+ }),
87824
+ object({
87825
+ kind: literal("linear"),
87826
+ scale: number(),
87827
+ offset: number(),
87828
+ clampMin: number().optional(),
87829
+ clampMax: number().optional()
87830
+ }),
87831
+ object({
87832
+ kind: literal("enum-map"),
87833
+ mapping: record(string(), string().nullable())
87834
+ }),
87835
+ object({ kind: literal("number") })
87836
+ ]);
87837
+ var ScalarOverrideDraftSchema = object({
87838
+ kind: literal("scalar"),
87839
+ cap: string().min(1),
87840
+ targetId: string().min(1),
87841
+ source: OverrideSourceSchema,
87842
+ transform: CustomizeTransformDraftSchema
87843
+ });
87844
+ var KeyedArrayOverrideDraftSchema = object({
87845
+ kind: literal("keyedArray"),
87846
+ cap: string().min(1),
87847
+ targetId: string().min(1),
87848
+ key: string().min(1),
87849
+ label: string().min(1),
87850
+ fieldPath: string().min(1),
87851
+ source: OverrideSourceSchema,
87852
+ transform: CustomizeTransformDraftSchema
87853
+ });
87854
+ var PulseOverrideDraftSchema = object({
87855
+ kind: literal("pulse"),
87856
+ cap: string().min(1),
87857
+ targetId: string().min(1),
87858
+ enabled: boolean(),
87859
+ debounceMs: number().nonnegative(),
87860
+ sources: array(OverrideSourceSchema).min(1)
87861
+ });
87862
+ var SpanSourceDraftSchema = OverrideSourceSchema.extend({ mode: _enum([
87863
+ "in-addition",
87864
+ "confirm",
87865
+ "replace"
87866
+ ]).optional() });
87867
+ discriminatedUnion("kind", [
87868
+ ScalarOverrideDraftSchema,
87869
+ KeyedArrayOverrideDraftSchema,
87870
+ PulseOverrideDraftSchema,
87871
+ object({
87872
+ kind: literal("span"),
87873
+ cap: string().min(1),
87874
+ targetId: string().min(1),
87875
+ timeoutMs: number().nonnegative(),
87876
+ cooldownMs: number().nonnegative().optional(),
87877
+ sources: array(SpanSourceDraftSchema)
87878
+ })
87879
+ ]);
87880
+ object({
87881
+ targetId: string().min(1),
87882
+ configured: boolean(),
87883
+ source: _enum(["native", "assigned"]),
87884
+ state: _enum([
87885
+ "active",
87886
+ "stale",
87887
+ "released",
87888
+ "unavailable"
87889
+ ]),
87890
+ reason: string().nullable()
87891
+ });
87892
+ String.raw`rose\(active(\d+), changed(\d+), (\d+(?:\.\d+)?)\)`;
87413
87893
  var G711_SCALE_CORRECTION_DB = {
87414
87894
  PCMU: 20 * Math.log10(4),
87415
87895
  PCMA: 20 * Math.log10(8)
@@ -87531,6 +88011,7 @@ new Set(["devices", "classes"]);
87531
88011
  * narrows, and still fails CLOSED on a subject that cannot produce the identity
87532
88012
  * it tests (a device the mirror cannot name is not evidence of a camera).
87533
88013
  */
88014
+ var LEGACY_KINDS_WITHOUT_FILTERS = new Set(NC_LEGACY_SYSTEM_EVENT_KINDS);
87534
88015
  /**
87535
88016
  * Every filter, for the callers that must cover all of them (guards, tests).
87536
88017
  *
@@ -87554,6 +88035,7 @@ var NC_SYSTEM_EVENT_FILTER_KEYS = [
87554
88035
  * ignores it and an editor hides its input. It never means "excluded".
87555
88036
  */
87556
88037
  function systemEventFilterApplies(kind, filter) {
88038
+ if (LEGACY_KINDS_WITHOUT_FILTERS.has(kind)) return false;
87557
88039
  switch (filter) {
87558
88040
  case "deviceIds": return kind.startsWith("device-") || kind.startsWith("stream-") || kind === "detection-blind" || kind.startsWith("motion-") || kind.startsWith("recording-") || kind === "alarm-triggered";
87559
88041
  case "deviceTypes": return kind.startsWith("device-") || kind === "detection-blind" || kind.startsWith("motion-");
@@ -87595,9 +88077,6 @@ var NC_SYSTEM_EVENT_FAMILY = {
87595
88077
  "device-battery-normal": "device-events",
87596
88078
  "device-consumable-low": "device-events",
87597
88079
  "device-consumable-normal": "device-events",
87598
- "device-tank-low": "device-events",
87599
- "device-tank-full": "device-events",
87600
- "device-tank-normal": "device-events",
87601
88080
  "stream-online": "device-events",
87602
88081
  "stream-offline": "device-events",
87603
88082
  "detection-blind": "device-events",
@@ -87692,16 +88171,6 @@ var NC_SYSTEM_EVENT_KIND_GROUP_SPECS = [
87692
88171
  label: "Consumables",
87693
88172
  kinds: ["device-consumable-low", "device-consumable-normal"]
87694
88173
  },
87695
- {
87696
- id: "tanks",
87697
- family: "device-events",
87698
- label: "Tanks",
87699
- kinds: [
87700
- "device-tank-low",
87701
- "device-tank-full",
87702
- "device-tank-normal"
87703
- ]
87704
- },
87705
88174
  {
87706
88175
  id: "detection-blind",
87707
88176
  family: "device-events",
@@ -89110,11 +89579,6 @@ var RULE_BODY_ONLY = ["body"];
89110
89579
  var RULE_TEXT = ["title", "body"];
89111
89580
  var BATTERY = ["device-battery-low", "device-battery-normal"];
89112
89581
  var CONSUMABLE = ["device-consumable-low", "device-consumable-normal"];
89113
- var TANK = [
89114
- "device-tank-low",
89115
- "device-tank-full",
89116
- "device-tank-normal"
89117
- ];
89118
89582
  var ALERT_EPISODE = [
89119
89583
  "alert-critical",
89120
89584
  "alert-error",
@@ -89146,7 +89610,6 @@ var DEVICE_EVENTS = [
89146
89610
  "device-enabled",
89147
89611
  ...BATTERY,
89148
89612
  ...CONSUMABLE,
89149
- ...TANK,
89150
89613
  "stream-online",
89151
89614
  "stream-offline",
89152
89615
  "detection-blind",
@@ -89192,12 +89655,6 @@ var STATE_SUMMARY_SECTION_VARS = [
89192
89655
  example: "Robot — filter 10 %",
89193
89656
  kinds: CONSUMABLE
89194
89657
  },
89195
- {
89196
- name: "summaryTanks",
89197
- label: "Summary: tanks",
89198
- example: "Robot — clean water low",
89199
- kinds: TANK
89200
- },
89201
89658
  {
89202
89659
  name: "summaryDetection",
89203
89660
  label: "Summary: cameras detecting nothing",
@@ -89606,18 +90063,7 @@ var NC_TEMPLATE_VARS = [
89606
90063
  families: ["rule"],
89607
90064
  fields: [...RULE_TEXT],
89608
90065
  kinds: ["system"],
89609
- systemEventKinds: [...CONSUMABLE, ...TANK]
89610
- },
89611
- {
89612
- name: "tank",
89613
- label: "Tank",
89614
- description: "Which tank, as a stable token: cleanWater, dirtyWater, detergent, dustBin, or the device key of any other supply (salt, rinse aid).",
89615
- example: "clean water",
89616
- group: "system",
89617
- families: ["rule"],
89618
- fields: [...RULE_TEXT],
89619
- kinds: ["system"],
89620
- systemEventKinds: [...TANK]
90066
+ systemEventKinds: [...CONSUMABLE]
89621
90067
  },
89622
90068
  {
89623
90069
  name: "profile",
@@ -90268,9 +90714,6 @@ var NC_TEMPLATE_VARS = [
90268
90714
  * delete it from here then, and the served catalog names it again.
90269
90715
  */
90270
90716
  var NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS = [
90271
- "device-tank-low",
90272
- "device-tank-full",
90273
- "device-tank-normal",
90274
90717
  "node-restarting",
90275
90718
  "node-updating",
90276
90719
  "alert-critical",
@@ -90430,15 +90873,6 @@ var CLASS_BY_KIND = new Map([
90430
90873
  snapshotLabel: "Consumables low now",
90431
90874
  snapshotSection: "consumables"
90432
90875
  },
90433
- {
90434
- id: "tanks",
90435
- family: "device-events",
90436
- label: "Tanks (low or full / back to normal)",
90437
- bad: ["device-tank-low", "device-tank-full"],
90438
- recovery: ["device-tank-normal"],
90439
- snapshotLabel: "Tanks low or full now",
90440
- snapshotSection: "tanks"
90441
- },
90442
90876
  {
90443
90877
  id: "motion-noise",
90444
90878
  family: "device-events",
@@ -92842,16 +93276,16 @@ Object.defineProperty(exports, "NC_SNOOZE_MAX_MINUTES", {
92842
93276
  return NC_SNOOZE_MAX_MINUTES;
92843
93277
  }
92844
93278
  });
92845
- Object.defineProperty(exports, "NC_SYSTEM_EVENT_KIND_GROUP_SPECS", {
93279
+ Object.defineProperty(exports, "NC_STATE_SUMMARY_SECTION_IDS", {
92846
93280
  enumerable: true,
92847
93281
  get: function() {
92848
- return NC_SYSTEM_EVENT_KIND_GROUP_SPECS;
93282
+ return NC_STATE_SUMMARY_SECTION_IDS;
92849
93283
  }
92850
93284
  });
92851
- Object.defineProperty(exports, "NC_TANK_SYSTEM_EVENT_KINDS", {
93285
+ Object.defineProperty(exports, "NC_SYSTEM_EVENT_KIND_GROUP_SPECS", {
92852
93286
  enumerable: true,
92853
93287
  get: function() {
92854
- return NC_TANK_SYSTEM_EVENT_KINDS;
93288
+ return NC_SYSTEM_EVENT_KIND_GROUP_SPECS;
92855
93289
  }
92856
93290
  });
92857
93291
  Object.defineProperty(exports, "NC_TAXONOMY", {
@@ -93394,6 +93828,12 @@ Object.defineProperty(exports, "cloneAlarmSettings", {
93394
93828
  return cloneAlarmSettings;
93395
93829
  }
93396
93830
  });
93831
+ Object.defineProperty(exports, "consumableFormOf", {
93832
+ enumerable: true,
93833
+ get: function() {
93834
+ return consumableFormOf;
93835
+ }
93836
+ });
93397
93837
  Object.defineProperty(exports, "consumableLowPercentOf", {
93398
93838
  enumerable: true,
93399
93839
  get: function() {