@camstack/addon-provider-homematic 1.2.160 → 1.2.161

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.mjs CHANGED
@@ -9,7 +9,7 @@ import { join } from "path";
9
9
  var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
10
10
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
11
11
  //#endregion
12
- //#region ../types/dist/event-category-CT-hz5Rb.mjs
12
+ //#region ../types/dist/event-category-DmZDPDf_.mjs
13
13
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
14
14
  EventCategory["SystemBoot"] = "system.boot";
15
15
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -636,7 +636,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
636
636
  * (a track was promoted to a stationary-registry entry) or departs (the
637
637
  * object moved / was removed). Telemetry (D8): lossy, drives a UI refresh of
638
638
  * the dedicated "Stationary" section — never the live event feed. Payload:
639
- * `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp }`.
639
+ * `{ deviceId, entryId, className, phase:'appeared'|'departed', timestamp, observedAt, zones }`.
640
640
  */
641
641
  EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
642
642
  /**
@@ -774,6 +774,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
774
774
  */
775
775
  EventCategory["AccessoriesChanged"] = "accessories.onAccessoriesChanged";
776
776
  /**
777
+ * An action run started or ended. Emitted by the `actions` surface.
778
+ * Payload: `ActionRunChanged` (`{ actionId, runId, isRunning, outcome?, lastRunAt, lastError }`).
779
+ */
780
+ EventCategory["ActionsRunChanged"] = "actions.onRunChanged";
781
+ /**
777
782
  * Progress update from a running model conversion job.
778
783
  * Payload: `{ kind: 'model-convert', phase, sessionId?, pct?, detail? }`.
779
784
  * Emitted by `addon-model-studio` on the converting node.
@@ -5585,7 +5590,7 @@ var ZodIssueCode = {
5585
5590
  var ZodFirstPartyTypeKind;
5586
5591
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5587
5592
  //#endregion
5588
- //#region ../types/dist/sleep--jXS9hWo.mjs
5593
+ //#region ../types/dist/sleep-Crlmu_tO.mjs
5589
5594
  /**
5590
5595
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5591
5596
  * window to float samples (D455).
@@ -8893,6 +8898,8 @@ Object.freeze({ "doorbell": "lastPressedAt" });
8893
8898
  /** Every capability name, so addon code can check a name without the schema graph. */
8894
8899
  var CAP_NAMES = Object.freeze([
8895
8900
  "accessories",
8901
+ "action-source",
8902
+ "actions",
8896
8903
  "addon-pages",
8897
8904
  "addon-pages-source",
8898
8905
  "addon-routes",
@@ -9081,11 +9088,11 @@ var CAP_NAMES = Object.freeze([
9081
9088
  Object.freeze({
9082
9089
  "air-quality-sensor": [
9083
9090
  {
9084
- "path": "co2Ppm",
9091
+ "path": "co2",
9085
9092
  "valueType": "number"
9086
9093
  },
9087
9094
  {
9088
- "path": "vocPpb",
9095
+ "path": "voc",
9089
9096
  "valueType": "number"
9090
9097
  },
9091
9098
  {
@@ -9135,7 +9142,7 @@ Object.freeze({
9135
9142
  }
9136
9143
  ],
9137
9144
  "ambient-light-sensor": [{
9138
- "path": "lux",
9145
+ "path": "illuminance",
9139
9146
  "valueType": "number"
9140
9147
  }],
9141
9148
  "audio-metrics": [
@@ -9196,7 +9203,7 @@ Object.freeze({
9196
9203
  ],
9197
9204
  "battery": [
9198
9205
  {
9199
- "path": "percentage",
9206
+ "path": "level",
9200
9207
  "valueType": "number"
9201
9208
  },
9202
9209
  {
@@ -9218,7 +9225,7 @@ Object.freeze({
9218
9225
  "valueType": "number"
9219
9226
  },
9220
9227
  {
9221
- "path": "volts",
9228
+ "path": "voltage",
9222
9229
  "valueType": "number"
9223
9230
  },
9224
9231
  {
@@ -9239,7 +9246,7 @@ Object.freeze({
9239
9246
  "valueType": "boolean"
9240
9247
  }],
9241
9248
  "brightness": [{
9242
- "path": "percentage",
9249
+ "path": "level",
9243
9250
  "valueType": "number"
9244
9251
  }],
9245
9252
  "broker": [{
@@ -9440,7 +9447,7 @@ Object.freeze({
9440
9447
  "valueType": "number"
9441
9448
  },
9442
9449
  {
9443
- "path": "mireds",
9450
+ "path": "colorTemperature",
9444
9451
  "valueType": "number"
9445
9452
  }
9446
9453
  ],
@@ -9619,15 +9626,15 @@ Object.freeze({
9619
9626
  "valueType": "string"
9620
9627
  },
9621
9628
  {
9622
- "path": "remainingSeconds",
9629
+ "path": "remaining",
9623
9630
  "valueType": "number"
9624
9631
  },
9625
9632
  {
9626
- "path": "delayedStartSeconds",
9633
+ "path": "delayedStart",
9627
9634
  "valueType": "number"
9628
9635
  },
9629
9636
  {
9630
- "path": "progressPercent",
9637
+ "path": "progress",
9631
9638
  "valueType": "number"
9632
9639
  },
9633
9640
  {
@@ -9741,7 +9748,7 @@ Object.freeze({
9741
9748
  ],
9742
9749
  "fan-control": [
9743
9750
  {
9744
- "path": "percentage",
9751
+ "path": "speed",
9745
9752
  "valueType": "number"
9746
9753
  },
9747
9754
  {
@@ -9841,7 +9848,7 @@ Object.freeze({
9841
9848
  }
9842
9849
  ],
9843
9850
  "humidity-sensor": [{
9844
- "path": "percent",
9851
+ "path": "humidity",
9845
9852
  "valueType": "number"
9846
9853
  }],
9847
9854
  "image": [{
@@ -9951,7 +9958,7 @@ Object.freeze({
9951
9958
  "valueType": "number"
9952
9959
  },
9953
9960
  {
9954
- "path": "progressPercent",
9961
+ "path": "progress",
9955
9962
  "valueType": "number"
9956
9963
  },
9957
9964
  {
@@ -10030,11 +10037,11 @@ Object.freeze({
10030
10037
  "valueType": "string"
10031
10038
  },
10032
10039
  {
10033
- "path": "positionMs",
10040
+ "path": "position",
10034
10041
  "valueType": "number"
10035
10042
  },
10036
10043
  {
10037
- "path": "durationMs",
10044
+ "path": "duration",
10038
10045
  "valueType": "number"
10039
10046
  },
10040
10047
  {
@@ -10136,11 +10143,11 @@ Object.freeze({
10136
10143
  ]
10137
10144
  },
10138
10145
  {
10139
- "path": "signalPercent",
10146
+ "path": "signal",
10140
10147
  "valueType": "number"
10141
10148
  },
10142
10149
  {
10143
- "path": "rssiDbm",
10150
+ "path": "rssi",
10144
10151
  "valueType": "number"
10145
10152
  },
10146
10153
  {
@@ -10195,6 +10202,18 @@ Object.freeze({
10195
10202
  "path": "foodLevel",
10196
10203
  "valueType": "number"
10197
10204
  },
10205
+ {
10206
+ "path": "bowlFood",
10207
+ "valueType": "number"
10208
+ },
10209
+ {
10210
+ "path": "eating",
10211
+ "valueType": "boolean"
10212
+ },
10213
+ {
10214
+ "path": "supportsMarkRefilled",
10215
+ "valueType": "boolean"
10216
+ },
10198
10217
  {
10199
10218
  "path": "food1",
10200
10219
  "valueType": "number"
@@ -10259,23 +10278,23 @@ Object.freeze({
10259
10278
  ],
10260
10279
  "power-meter": [
10261
10280
  {
10262
- "path": "watts",
10281
+ "path": "power",
10263
10282
  "valueType": "number"
10264
10283
  },
10265
10284
  {
10266
- "path": "kwhTotal",
10285
+ "path": "energy",
10267
10286
  "valueType": "number"
10268
10287
  },
10269
10288
  {
10270
- "path": "volts",
10289
+ "path": "voltage",
10271
10290
  "valueType": "number"
10272
10291
  },
10273
10292
  {
10274
- "path": "amps",
10293
+ "path": "current",
10275
10294
  "valueType": "number"
10276
10295
  },
10277
10296
  {
10278
- "path": "va",
10297
+ "path": "apparentPower",
10279
10298
  "valueType": "number"
10280
10299
  },
10281
10300
  {
@@ -10303,14 +10322,10 @@ Object.freeze({
10303
10322
  {
10304
10323
  "path": "gps.accuracyMeters",
10305
10324
  "valueType": "number"
10306
- },
10307
- {
10308
- "path": "batteryPercent",
10309
- "valueType": "number"
10310
10325
  }
10311
10326
  ],
10312
10327
  "pressure-sensor": [{
10313
- "path": "hpa",
10328
+ "path": "pressure",
10314
10329
  "valueType": "number"
10315
10330
  }],
10316
10331
  "privacy-mask": [{
@@ -10624,7 +10639,7 @@ Object.freeze({
10624
10639
  "valueType": "boolean"
10625
10640
  }],
10626
10641
  "temperature-sensor": [{
10627
- "path": "celsius",
10642
+ "path": "temperature",
10628
10643
  "valueType": "number"
10629
10644
  }],
10630
10645
  "update": [
@@ -10672,7 +10687,7 @@ Object.freeze({
10672
10687
  "valueType": "string"
10673
10688
  },
10674
10689
  {
10675
- "path": "progressPercent",
10690
+ "path": "progress",
10676
10691
  "valueType": "number"
10677
10692
  },
10678
10693
  {
@@ -11157,7 +11172,7 @@ function errMsg(err) {
11157
11172
  return String(err);
11158
11173
  }
11159
11174
  //#endregion
11160
- //#region ../types/dist/composition-Bb8iwHEJ.mjs
11175
+ //#region ../types/dist/composition-CZImLpOI.mjs
11161
11176
  /**
11162
11177
  * The ffmpeg build every CamStack node downloads, per platform and arch.
11163
11178
  *
@@ -15677,6 +15692,14 @@ var AutomationConditionLeafSchema = object({
15677
15692
  array(union([string(), number()]))
15678
15693
  ])
15679
15694
  });
15695
+ var AutomationConditionStationaryPresentSchema = object({
15696
+ kind: literal("stationary-present"),
15697
+ deviceId: number().int().nonnegative(),
15698
+ /** Class names; a macro class matches every raw class that maps to it. */
15699
+ classes: array(string().min(1)).min(1).optional(),
15700
+ /** The parked object must be in at least one of these zones. */
15701
+ zones: array(string().min(1)).min(1).optional()
15702
+ });
15680
15703
  /**
15681
15704
  * The expression leaf, declared as a plain object rather than an intersection
15682
15705
  * with {@link ExpressionSourceSchema}: a discriminated union has to be able to
@@ -15710,7 +15733,8 @@ var AutomationConditionSchema = lazy(() => discriminatedUnion("kind", [
15710
15733
  child: AutomationConditionSchema
15711
15734
  }),
15712
15735
  AutomationConditionLeafSchema,
15713
- AutomationConditionExpressionSchema
15736
+ AutomationConditionExpressionSchema,
15737
+ AutomationConditionStationaryPresentSchema
15714
15738
  ]));
15715
15739
  /**
15716
15740
  * What starts a run.
@@ -15751,7 +15775,34 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
15751
15775
  kind: literal("schedule"),
15752
15776
  cron: string().min(1).max(120)
15753
15777
  }),
15754
- object({ kind: literal("manual") })
15778
+ object({ kind: literal("manual") }),
15779
+ object({
15780
+ kind: literal("detection"),
15781
+ /** Class names. A macro class (`animal`, `vehicle`, `person`, `package`)
15782
+ * matches every raw class that maps to it; any other name matches
15783
+ * exactly. */
15784
+ classes: array(string().min(1)).min(1),
15785
+ deviceIds: array(number().int().nonnegative()).min(1),
15786
+ /** The track must have visited at least one of these zones. */
15787
+ zones: array(string().min(1)).min(1).optional(),
15788
+ /** Best-so-far confidence the track must reach. */
15789
+ minScore: number().min(0).max(1).optional()
15790
+ }),
15791
+ object({
15792
+ kind: literal("stationary"),
15793
+ deviceIds: array(number().int().nonnegative()).min(1),
15794
+ /** Class names; a macro class matches like the detection trigger. */
15795
+ classes: array(string().min(1)).min(1).optional(),
15796
+ /** The parked object must be in at least one of these zones. */
15797
+ zones: array(string().min(1)).min(1).optional(),
15798
+ /** `appeared`: it became parked. `departed`: the registry retired it.
15799
+ * The vocabulary of `PipelineAnalyticsStationaryChanged`. */
15800
+ phase: _enum(["appeared", "departed"])
15801
+ }),
15802
+ object({
15803
+ kind: literal("interval"),
15804
+ minutes: number().int().min(1).max(1440)
15805
+ })
15755
15806
  ]);
15756
15807
  /**
15757
15808
  * One action step.
@@ -15771,28 +15822,47 @@ var AutomationTriggerSchema = discriminatedUnion("kind", [
15771
15822
  * is called. The runner still receives a number and is untouched; the
15772
15823
  * resolution is the recipe's job, not the runner's.
15773
15824
  */
15825
+ var AutomationWaitStepSchema = object({
15826
+ kind: literal("wait"),
15827
+ seconds: number().min(0).max(300)
15828
+ });
15829
+ var AutomationCapStepSchema = object({
15830
+ kind: literal("cap"),
15831
+ /**
15832
+ * One device, several same-family devices (locks / climate family / …),
15833
+ * or `{ $var }` for the device that triggered the run. An array is
15834
+ * fan-out at codegen — each id gets the same cap.method call.
15835
+ */
15836
+ deviceId: union([
15837
+ number().int(),
15838
+ array(number().int()).min(1),
15839
+ object({ $var: string().min(1) })
15840
+ ]),
15841
+ cap: string().min(1),
15842
+ method: string().min(1),
15843
+ /** Values may carry `{{vars.x}}` slots, or be exactly `{ $var: 'name' }`, which
15844
+ * SUBSTITUTE and do not evaluate (§3.2.3). Anything beyond substitution is
15845
+ * the expression leaf. */
15846
+ args: record(string(), unknown()).optional()
15847
+ });
15848
+ /**
15849
+ * The steps an internal Action may contain: cap and wait, and nothing that can
15850
+ * call back into an Action — so an Action can never reach itself (no cycles).
15851
+ */
15852
+ var ActionStepSchema = discriminatedUnion("kind", [AutomationWaitStepSchema, AutomationCapStepSchema]);
15774
15853
  var AutomationActionSchema = discriminatedUnion("kind", [
15854
+ AutomationWaitStepSchema,
15855
+ AutomationCapStepSchema,
15775
15856
  object({
15776
- kind: literal("wait"),
15777
- seconds: number().min(0).max(300)
15778
- }),
15779
- object({
15780
- kind: literal("cap"),
15781
- /**
15782
- * One device, several same-family devices (locks / climate family / …),
15783
- * or `{ $var }` for the device that triggered the run. An array is
15784
- * fan-out at codegen — each id gets the same cap.method call.
15785
- */
15786
- deviceId: union([
15787
- number().int(),
15788
- array(number().int()).min(1),
15789
- object({ $var: string().min(1) })
15790
- ]),
15791
- cap: string().min(1),
15792
- method: string().min(1),
15793
- /** Values may carry `{{vars.x}}` slots, which SUBSTITUTE and do not
15794
- * evaluate (§3.2.3). Anything beyond substitution is the expression leaf. */
15795
- args: record(string(), unknown()).optional()
15857
+ kind: literal("action"),
15858
+ /** An entry of the `actions` surface (`internal:<uuid>` or `<addonId>:<localId>`). */
15859
+ actionId: string().min(1),
15860
+ /** Values for the action's declared variables; the others take their default. */
15861
+ variables: record(string(), union([
15862
+ string(),
15863
+ number(),
15864
+ boolean()
15865
+ ])).optional()
15796
15866
  }),
15797
15867
  object({
15798
15868
  kind: literal("code"),
@@ -15801,10 +15871,357 @@ var AutomationActionSchema = discriminatedUnion("kind", [
15801
15871
  code: string().min(1).max(2e4)
15802
15872
  })
15803
15873
  ]);
15874
+ /**
15875
+ * How a trigger that arrives while the automation is busy (or cooling down) is
15876
+ * handled. One of the automation's execution modes, never a property of its
15877
+ * actions. Absent means `single`.
15878
+ *
15879
+ * - `single` — drop the trigger while a run is in progress (traced + logged).
15880
+ * - `restart` — abort the run in progress (at its next step boundary), start fresh.
15881
+ * - `queued` — queue up to `max` triggers, drop the rest (traced).
15882
+ * - `parallel` — up to `max` runs at once, drop the rest (traced).
15883
+ * - `cooldown` — `single`, and no new run until `minutes` after the last run
15884
+ * STARTED; persisted across a restart. A manual trigger bypasses only this
15885
+ * wait, never the single/queued limits.
15886
+ */
15887
+ var AutomationRunModeSchema = discriminatedUnion("mode", [
15888
+ object({ mode: literal("single") }),
15889
+ object({ mode: literal("restart") }),
15890
+ object({
15891
+ mode: literal("queued"),
15892
+ max: number().int().min(1).max(10)
15893
+ }),
15894
+ object({
15895
+ mode: literal("parallel"),
15896
+ max: number().int().min(1).max(10)
15897
+ }),
15898
+ object({
15899
+ mode: literal("cooldown"),
15900
+ minutes: number().int().min(1).max(1440)
15901
+ })
15902
+ ]);
15804
15903
  var AutomationRecipeSchema = object({
15805
15904
  triggers: array(AutomationTriggerSchema),
15806
15905
  conditions: AutomationConditionSchema.optional(),
15807
- actions: array(AutomationActionSchema)
15906
+ actions: array(AutomationActionSchema),
15907
+ runMode: AutomationRunModeSchema.optional(),
15908
+ /** How many run traces the automation keeps (default {@link DEFAULT_TRACE_KEEP}). */
15909
+ keepTraces: number().int().min(1).max(100).optional()
15910
+ });
15911
+ new Set([
15912
+ {
15913
+ id: "person",
15914
+ name: "Person"
15915
+ },
15916
+ {
15917
+ id: "vehicle",
15918
+ name: "Vehicle"
15919
+ },
15920
+ {
15921
+ id: "animal",
15922
+ name: "Animal"
15923
+ },
15924
+ {
15925
+ id: "package",
15926
+ name: "Package"
15927
+ }
15928
+ ].map((l) => l.id));
15929
+ var COCO_TO_MACRO = {
15930
+ mapping: {
15931
+ person: "person",
15932
+ bicycle: "vehicle",
15933
+ car: "vehicle",
15934
+ motorcycle: "vehicle",
15935
+ airplane: "vehicle",
15936
+ bus: "vehicle",
15937
+ train: "vehicle",
15938
+ truck: "vehicle",
15939
+ boat: "vehicle",
15940
+ bird: "animal",
15941
+ cat: "animal",
15942
+ dog: "animal",
15943
+ horse: "animal",
15944
+ sheep: "animal",
15945
+ cow: "animal",
15946
+ elephant: "animal",
15947
+ bear: "animal",
15948
+ zebra: "animal",
15949
+ giraffe: "animal",
15950
+ suitcase: "package",
15951
+ backpack: "package",
15952
+ handbag: "package"
15953
+ },
15954
+ preserveOriginal: false
15955
+ };
15956
+ new Set(Object.values(COCO_TO_MACRO.mapping));
15957
+ /**
15958
+ * Run traces — what an automation (or, later, an Action run) DID, node by node,
15959
+ * so the editor can paint every block green or red with its reason.
15960
+ *
15961
+ * A trace is data, not a log: it covers the WHOLE tree — the trigger stage,
15962
+ * every condition node (containers and leaves, including the ones a
15963
+ * short-circuit never reached), the run-mode verdict and every action step —
15964
+ * each addressed by a stable path (`conditions.0.1`, `actions.2`, or `steps.N`
15965
+ * for an Action run). Skipped
15966
+ * evaluations are traced too, and identical consecutive skips collapse into a
15967
+ * repeat count so a trigger that fails every 5 minutes cannot flush real runs.
15968
+ *
15969
+ * {@link AutomationStepTraceSchema} is deliberately free of automation
15970
+ * vocabulary so an Action run records the same step shape.
15971
+ */
15972
+ /** A value a trace may show: JSON primitives and short lists, nothing deeper. */
15973
+ var TraceValueSchema = union([
15974
+ string(),
15975
+ number(),
15976
+ boolean(),
15977
+ _null(),
15978
+ array(union([string(), number()]))
15979
+ ]);
15980
+ var AutomationRunOutcomeSchema = _enum([
15981
+ "ran",
15982
+ "skipped-trigger",
15983
+ "skipped-conditions",
15984
+ "skipped-cooldown",
15985
+ "skipped-overlap",
15986
+ "failed",
15987
+ "aborted"
15988
+ ]);
15989
+ /** `not-evaluated` = a short-circuit never reached the node. */
15990
+ var TraceNodeOutcomeSchema = _enum([
15991
+ "pass",
15992
+ "fail",
15993
+ "not-evaluated"
15994
+ ]);
15995
+ var AutomationTriggerTraceSchema = object({
15996
+ kind: string().min(1),
15997
+ outcome: _enum(["pass", "fail"]),
15998
+ /** Why an event was rejected ("class person not in [dog]") or what fired. */
15999
+ reason: string(),
16000
+ /** deviceId, className, trackId, score … — only what the trigger exposes. */
16001
+ vars: record(string(), TraceValueSchema)
16002
+ });
16003
+ var AutomationConditionTraceNodeSchema = object({
16004
+ /** `conditions` for the root, `conditions.<i>` for its i-th child, … */
16005
+ path: string().min(1),
16006
+ kind: _enum([
16007
+ "all",
16008
+ "any",
16009
+ "not",
16010
+ "condition",
16011
+ "expression",
16012
+ "stationary-present"
16013
+ ]),
16014
+ outcome: TraceNodeOutcomeSchema,
16015
+ reason: string(),
16016
+ deviceId: number().int().optional(),
16017
+ cap: string().optional(),
16018
+ fieldPath: string().optional(),
16019
+ operator: string().optional(),
16020
+ expected: TraceValueSchema.optional(),
16021
+ /** What the mirror held; `null` when it held nothing (unknown). */
16022
+ observed: TraceValueSchema.optional()
16023
+ });
16024
+ var AutomationRunVerdictSchema = object({
16025
+ mode: AutomationRunModeSchema,
16026
+ decision: _enum([
16027
+ "run",
16028
+ "queued",
16029
+ "restart",
16030
+ "drop",
16031
+ "cooldown",
16032
+ "bypass"
16033
+ ]),
16034
+ reason: string()
16035
+ });
16036
+ /** One executed (or not-run) step — shared by automations and Action runs. */
16037
+ var AutomationStepTraceSchema = object({
16038
+ /** `actions.<i>` */
16039
+ path: string().min(1),
16040
+ kind: string().min(1),
16041
+ cap: string().optional(),
16042
+ method: string().optional(),
16043
+ deviceId: number().int().optional(),
16044
+ startedAt: number().optional(),
16045
+ endedAt: number().optional(),
16046
+ outcome: _enum([
16047
+ "ok",
16048
+ "error",
16049
+ "not-run"
16050
+ ]),
16051
+ message: string().optional()
16052
+ });
16053
+ var AutomationRunTraceSchema = object({
16054
+ runId: string().min(1),
16055
+ startedAt: number(),
16056
+ endedAt: number(),
16057
+ trigger: AutomationTriggerTraceSchema,
16058
+ conditions: array(AutomationConditionTraceNodeSchema),
16059
+ verdict: AutomationRunVerdictSchema.optional(),
16060
+ steps: array(AutomationStepTraceSchema),
16061
+ outcome: AutomationRunOutcomeSchema,
16062
+ /** How many identical consecutive skips this trace stands for (>= 1). */
16063
+ repeat: number().int().min(1),
16064
+ /** When the latest of those repeats happened. */
16065
+ lastAt: number()
16066
+ });
16067
+ /**
16068
+ * What the hub's `runs` ledger holds for one owner (`automation:<blockId>` or
16069
+ * `action:<actionId>`): the cooldown stamp and the trace ring.
16070
+ */
16071
+ var AutomationStateDocSchema = object({
16072
+ version: literal(1),
16073
+ lastRunStartedAt: number().nullable(),
16074
+ traces: array(AutomationRunTraceSchema)
16075
+ });
16076
+ /**
16077
+ * Actions — named, runnable things an operator (or an automation) can start,
16078
+ * declared as LIST ENTRIES, never as devices.
16079
+ *
16080
+ * An entry is either **internal** (a short list of cap/wait steps kept in the
16081
+ * hub's `actions` record kind) or declared by an addon through the
16082
+ * `action-source` collection (a Home Assistant script, a scene …). The one
16083
+ * surface the UI and automations talk to is the `actions` cap; it keeps no
16084
+ * catalog of its own (D3) — every `list` asks the providers live.
16085
+ *
16086
+ * This file is the data half: the entry schema, the variables an entry may
16087
+ * declare, and the pure resolution of the values a run was given. It holds no
16088
+ * runtime.
16089
+ */
16090
+ /** What a variable's value is. `select` takes one of `options`. */
16091
+ var ActionVariableTypeSchema = _enum([
16092
+ "string",
16093
+ "number",
16094
+ "boolean",
16095
+ "select"
16096
+ ]);
16097
+ var ACTION_VARIABLE_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
16098
+ var ActionVariableValueSchema = union([
16099
+ string(),
16100
+ number(),
16101
+ boolean()
16102
+ ]);
16103
+ /**
16104
+ * One declared variable. Steps reference it as `{ $var: 'name' }` (the whole
16105
+ * value) or `{{vars.name}}` (inside a string) in their args.
16106
+ */
16107
+ var ActionVariableSchema = object({
16108
+ name: string().regex(ACTION_VARIABLE_NAME_RE),
16109
+ label: string().min(1).max(120).optional(),
16110
+ type: ActionVariableTypeSchema,
16111
+ required: boolean().optional(),
16112
+ default: ActionVariableValueSchema.optional(),
16113
+ /** The allowed values of a `select`. */
16114
+ options: array(string().min(1)).min(1).optional()
16115
+ }).superRefine((v, ctx) => {
16116
+ if (v.type === "select" && v.options === void 0) ctx.addIssue({
16117
+ code: "custom",
16118
+ message: "a select variable needs options",
16119
+ path: ["options"]
16120
+ });
16121
+ if (v.default !== void 0 && variableValueError(v, v.default) !== null) ctx.addIssue({
16122
+ code: "custom",
16123
+ message: variableValueError(v, v.default) ?? "invalid default",
16124
+ path: ["default"]
16125
+ });
16126
+ });
16127
+ /** Why `value` is not a legal value for the variable, or null when it is. */
16128
+ function variableValueError(variable, value) {
16129
+ switch (variable.type) {
16130
+ case "string": return typeof value === "string" ? null : `variable "${variable.name}" must be a string`;
16131
+ case "number": return typeof value === "number" && Number.isFinite(value) ? null : `variable "${variable.name}" must be a number`;
16132
+ case "boolean": return typeof value === "boolean" ? null : `variable "${variable.name}" must be true or false`;
16133
+ case "select": return typeof value === "string" && (variable.options ?? []).includes(value) ? null : `variable "${variable.name}" must be one of ${(variable.options ?? []).join(", ")}`;
16134
+ }
16135
+ }
16136
+ var ActionSourceKindSchema = _enum(["internal", "addon"]);
16137
+ function isInternalActionId(actionId) {
16138
+ return actionId.startsWith("internal:") && actionId.length > 9;
16139
+ }
16140
+ /** The addon behind a `<addonId>:<localId>` id, or null for anything else (internal included). */
16141
+ function addonIdOfActionId(actionId) {
16142
+ if (isInternalActionId(actionId)) return null;
16143
+ const at = actionId.indexOf(":");
16144
+ return at > 0 && at < actionId.length - 1 ? actionId.slice(0, at) : null;
16145
+ }
16146
+ var ActionStatusSchema = object({
16147
+ isRunning: boolean(),
16148
+ /** Ms epoch the latest run STARTED; null when it never ran. */
16149
+ lastRunAt: number().nullable(),
16150
+ /** The latest run's failure; null on success or when it never ran. */
16151
+ lastError: string().nullable()
16152
+ });
16153
+ var ActionEntrySchema = object({
16154
+ /** `internal:<uuid>` or `<addonId>:<localId>`. */
16155
+ id: string().min(3),
16156
+ name: string().min(1).max(120),
16157
+ /** The addon that declared it; `core-blocks` for an internal one. */
16158
+ addonId: string().min(1),
16159
+ source: ActionSourceKindSchema,
16160
+ /** An addon-declared entry is edited where it was declared. */
16161
+ readOnly: boolean(),
16162
+ /** Internal only: cap and wait steps. No action-in-action, so no cycles. */
16163
+ steps: array(ActionStepSchema).min(1).max(50).optional(),
16164
+ variables: array(ActionVariableSchema).max(20).optional(),
16165
+ status: ActionStatusSchema
16166
+ }).superRefine((entry, ctx) => {
16167
+ if (entry.source === "internal") {
16168
+ if (!isInternalActionId(entry.id)) ctx.addIssue({
16169
+ code: "custom",
16170
+ message: "an internal action id is internal:<uuid>",
16171
+ path: ["id"]
16172
+ });
16173
+ return;
16174
+ }
16175
+ if (entry.steps !== void 0) ctx.addIssue({
16176
+ code: "custom",
16177
+ message: "only an internal action carries steps",
16178
+ path: ["steps"]
16179
+ });
16180
+ if (!entry.readOnly) ctx.addIssue({
16181
+ code: "custom",
16182
+ message: "an addon action is read-only here",
16183
+ path: ["readOnly"]
16184
+ });
16185
+ if (addonIdOfActionId(entry.id) === null) ctx.addIssue({
16186
+ code: "custom",
16187
+ message: "an addon action id is <addonId>:<localId>",
16188
+ path: ["id"]
16189
+ });
16190
+ });
16191
+ /** What an operator writes for an internal action. */
16192
+ var ActionInputSchema = object({
16193
+ name: string().min(1).max(120),
16194
+ steps: array(ActionStepSchema).min(1).max(50),
16195
+ variables: array(ActionVariableSchema).max(20).optional()
16196
+ });
16197
+ /** Who started a run. Absent = the operator pressed it. */
16198
+ var ActionRunOriginSchema = object({
16199
+ /** The automation block whose step started it. */
16200
+ blockId: string().min(1).optional() });
16201
+ /** `started` = the caller did not ask to wait. */
16202
+ var ActionRunOutcomeSchema = union([AutomationRunOutcomeSchema, literal("started")]);
16203
+ var ActionRunResultSchema = object({
16204
+ runId: string().min(1),
16205
+ outcome: ActionRunOutcomeSchema,
16206
+ /** Why it did not run, or what failed. */
16207
+ message: string().optional()
16208
+ });
16209
+ _enum([
16210
+ "not-found",
16211
+ "read-only",
16212
+ "invalid-variables",
16213
+ "invalid-steps",
16214
+ "not-linked",
16215
+ "busy"
16216
+ ]);
16217
+ object({
16218
+ actionId: string(),
16219
+ runId: string(),
16220
+ isRunning: boolean(),
16221
+ /** Set when the run ended. */
16222
+ outcome: AutomationRunOutcomeSchema.optional(),
16223
+ lastRunAt: number().nullable(),
16224
+ lastError: string().nullable()
15808
16225
  });
15809
16226
  /**
15810
16227
  * `addon-pages` — system-scoped singleton aggregator cap. Public-facing
@@ -18540,7 +18957,7 @@ var CompositionEventPlanSchema = object({
18540
18957
  stateField: string(),
18541
18958
  fieldKey: string()
18542
18959
  });
18543
- /** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
18960
+ /** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
18544
18961
  var CompositionProblemSchema = object({
18545
18962
  code: _enum([
18546
18963
  "reserved-variant",
@@ -18859,7 +19276,7 @@ var GROUP_TEMPLATES = [
18859
19276
  summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
18860
19277
  role: DeviceRole.TemperatureSensor,
18861
19278
  outputCap: "temperature-sensor",
18862
- outputField: "celsius",
19279
+ outputField: "temperature",
18863
19280
  quantity: "temperature",
18864
19281
  defaultAggregate: "mean",
18865
19282
  empty: "null",
@@ -18870,7 +19287,7 @@ var GROUP_TEMPLATES = [
18870
19287
  summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
18871
19288
  role: DeviceRole.HumiditySensor,
18872
19289
  outputCap: "humidity-sensor",
18873
- outputField: "percent",
19290
+ outputField: "humidity",
18874
19291
  quantity: "humidity",
18875
19292
  defaultAggregate: "mean",
18876
19293
  empty: "null",
@@ -18881,7 +19298,7 @@ var GROUP_TEMPLATES = [
18881
19298
  summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
18882
19299
  role: DeviceRole.PressureSensor,
18883
19300
  outputCap: "pressure-sensor",
18884
- outputField: "hpa",
19301
+ outputField: "pressure",
18885
19302
  quantity: "pressure",
18886
19303
  defaultAggregate: "mean",
18887
19304
  empty: "null",
@@ -18892,7 +19309,7 @@ var GROUP_TEMPLATES = [
18892
19309
  summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
18893
19310
  role: DeviceRole.AmbientLightSensor,
18894
19311
  outputCap: "ambient-light-sensor",
18895
- outputField: "lux",
19312
+ outputField: "illuminance",
18896
19313
  quantity: "illuminance",
18897
19314
  defaultAggregate: "mean",
18898
19315
  empty: "null",
@@ -18903,7 +19320,7 @@ var GROUP_TEMPLATES = [
18903
19320
  summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
18904
19321
  role: DeviceRole.PowerSensor,
18905
19322
  outputCap: "power-meter",
18906
- outputField: "watts",
19323
+ outputField: "power",
18907
19324
  quantity: "power",
18908
19325
  defaultAggregate: "sum",
18909
19326
  empty: "omit",
@@ -18914,7 +19331,7 @@ var GROUP_TEMPLATES = [
18914
19331
  summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
18915
19332
  role: DeviceRole.EnergySensor,
18916
19333
  outputCap: "power-meter",
18917
- outputField: "kwhTotal",
19334
+ outputField: "energy",
18918
19335
  quantity: "energy",
18919
19336
  defaultAggregate: "sum",
18920
19337
  empty: "omit",
@@ -18925,7 +19342,7 @@ var GROUP_TEMPLATES = [
18925
19342
  summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
18926
19343
  role: DeviceRole.BatterySensor,
18927
19344
  outputCap: "battery",
18928
- outputField: "percentage",
19345
+ outputField: "level",
18929
19346
  quantity: "percentage",
18930
19347
  defaultAggregate: "mean",
18931
19348
  empty: "null",
@@ -19503,7 +19920,18 @@ method(object({}), object({ blocks: array(CoreBlockSchema) }), { auth: "admin" }
19503
19920
  kind: "mutation",
19504
19921
  auth: "admin",
19505
19922
  access: "view"
19506
- });
19923
+ }), method(object({
19924
+ blockId: string().min(1),
19925
+ trace: AutomationRunTraceSchema.optional(),
19926
+ runStartedAt: number().optional(),
19927
+ keepTraces: number().int().min(1).max(100).optional()
19928
+ }), _void(), {
19929
+ kind: "mutation",
19930
+ auth: "admin"
19931
+ }), method(object({ blockId: string().min(1) }), AutomationStateDocSchema, { auth: "admin" }), method(object({ blockId: string().min(1) }), object({
19932
+ traces: array(AutomationRunTraceSchema),
19933
+ lastError: string().nullable()
19934
+ }), { auth: "admin" });
19507
19935
  /**
19508
19936
  * `custom-model-registry` — collection cap exposing operator-registered
19509
19937
  * custom detection models. Each provider (today: `addon-model-studio`)
@@ -44992,51 +45420,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
44992
45420
  kind: "mutation",
44993
45421
  auth: "admin"
44994
45422
  });
44995
- new Set([
44996
- {
44997
- id: "person",
44998
- name: "Person"
44999
- },
45000
- {
45001
- id: "vehicle",
45002
- name: "Vehicle"
45003
- },
45004
- {
45005
- id: "animal",
45006
- name: "Animal"
45007
- },
45008
- {
45009
- id: "package",
45010
- name: "Package"
45011
- }
45012
- ].map((l) => l.id));
45013
- var COCO_TO_MACRO = {
45014
- mapping: {
45015
- person: "person",
45016
- bicycle: "vehicle",
45017
- car: "vehicle",
45018
- motorcycle: "vehicle",
45019
- airplane: "vehicle",
45020
- bus: "vehicle",
45021
- train: "vehicle",
45022
- truck: "vehicle",
45023
- boat: "vehicle",
45024
- bird: "animal",
45025
- cat: "animal",
45026
- dog: "animal",
45027
- horse: "animal",
45028
- sheep: "animal",
45029
- cow: "animal",
45030
- elephant: "animal",
45031
- bear: "animal",
45032
- zebra: "animal",
45033
- giraffe: "animal",
45034
- suitcase: "package",
45035
- backpack: "package",
45036
- handbag: "package"
45037
- },
45038
- preserveOriginal: false
45039
- };
45040
45423
  var AUDIO_MACRO_LABELS = [
45041
45424
  {
45042
45425
  id: "speech",
@@ -57603,9 +57986,9 @@ method(object({ nodeId: string().optional() }).optional(), array(AddonListItemSc
57603
57986
  */
57604
57987
  var AirQualitySensorStatusSchema = object({
57605
57988
  /** Carbon dioxide concentration in ppm. */
57606
- co2Ppm: number().min(0).optional().meta(readingMeta("concentration-volume")),
57989
+ co2: number().min(0).optional().meta(readingMeta("concentration-volume")),
57607
57990
  /** Total volatile organic compounds in ppb. */
57608
- vocPpb: number().min(0).optional().meta(readingMeta("concentration-ppb")),
57991
+ voc: number().min(0).optional().meta(readingMeta("concentration-ppb")),
57609
57992
  /** Particulate matter ≤ 2.5 μm in µg/m³. */
57610
57993
  pm25: number().min(0).optional().meta(readingMeta("concentration-mass")),
57611
57994
  /** Particulate matter ≤ 10 μm in µg/m³. */
@@ -57638,12 +58021,12 @@ var airQualitySensorCapability = {
57638
58021
  * History (D850): recorded series.
57639
58022
  */
57640
58023
  history: { fields: {
57641
- co2Ppm: {
58024
+ co2: {
57642
58025
  kind: "gauge",
57643
58026
  unit: "ppm",
57644
58027
  deadband: 5
57645
58028
  },
57646
- vocPpb: {
58029
+ voc: {
57647
58030
  kind: "gauge",
57648
58031
  unit: "ppb",
57649
58032
  deadband: 5
@@ -57674,7 +58057,7 @@ var airQualitySensorCapability = {
57674
58057
  */
57675
58058
  var AmbientLightSensorStatusSchema = object({
57676
58059
  /** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
57677
- lux: number().min(0).nullable().meta(readingMeta("illuminance", {
58060
+ illuminance: number().min(0).nullable().meta(readingMeta("illuminance", {
57678
58061
  precision: 0,
57679
58062
  label: "Illuminance"
57680
58063
  })),
@@ -57703,7 +58086,7 @@ var ambientLightSensorCapability = {
57703
58086
  /**
57704
58087
  * History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
57705
58088
  */
57706
- history: { fields: { lux: {
58089
+ history: { fields: { illuminance: {
57707
58090
  kind: "gauge",
57708
58091
  unit: "lx",
57709
58092
  deadbandPct: 10,
@@ -57842,6 +58225,84 @@ var audioMetricsCapability = {
57842
58225
  */
57843
58226
  history: "none"
57844
58227
  };
58228
+ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
58229
+ actionId: string().min(1),
58230
+ variables: record(string(), ActionVariableValueSchema).optional()
58231
+ }), _void(), {
58232
+ kind: "mutation",
58233
+ auth: "admin"
58234
+ }), method(object({ actionId: string().min(1) }), _void(), {
58235
+ kind: "mutation",
58236
+ auth: "admin"
58237
+ });
58238
+ /**
58239
+ * actions — the ONE surface for runnable actions, for the UI and for
58240
+ * automations. Provided by the core-blocks builtin on the hub.
58241
+ *
58242
+ * An action is a LIST ENTRY, not a device (D883): either internal (cap and wait
58243
+ * steps, kept in the hub's `actions` record kind) or declared by an addon over
58244
+ * `action-source`. `list` asks every `action-source` provider LIVE and overlays
58245
+ * the run status from the hub's `runs` ledger; there is no catalog here to
58246
+ * drift (D3).
58247
+ *
58248
+ * **Permissions follow the camera, as linked devices do.** An action is linked
58249
+ * to cameras by the operator (`setLinks`, D356: nothing links itself). A
58250
+ * non-admin may `get` / `run` an action only through a camera they may see that
58251
+ * links it: they name the camera (`deviceId`, a top-level field so the scope
58252
+ * gate sees it) and the provider refuses an action that camera does not link.
58253
+ * An admin, and an in-process caller (an automation block), may run any action.
58254
+ * Every refusal is typed (`[not-linked] …`) and logged.
58255
+ *
58256
+ * A second `run` of an action that is already running is REFUSED — traced and
58257
+ * logged — never queued.
58258
+ */
58259
+ var ActionIdInput = object({ actionId: string().min(1) });
58260
+ var ActionLinksSchema = object({
58261
+ deviceId: number().int().nonnegative(),
58262
+ actionIds: array(string().min(1)).max(100)
58263
+ });
58264
+ method(object({}), array(ActionEntrySchema), { auth: "admin" }), method(object({
58265
+ actionId: string().min(1),
58266
+ deviceId: number().int().nonnegative().optional()
58267
+ }), object({ action: ActionEntrySchema.nullable() }), {
58268
+ role: "viewer",
58269
+ auth: "protected",
58270
+ kind: "query",
58271
+ caller: "required"
58272
+ }), method(object({
58273
+ actionId: string().min(1),
58274
+ variables: record(string(), ActionVariableValueSchema).optional(),
58275
+ wait: boolean().optional(),
58276
+ origin: ActionRunOriginSchema.optional(),
58277
+ deviceId: number().int().nonnegative().optional()
58278
+ }), ActionRunResultSchema, {
58279
+ role: "viewer",
58280
+ auth: "protected",
58281
+ kind: "mutation",
58282
+ caller: "required"
58283
+ }), method(ActionIdInput, _void(), {
58284
+ kind: "mutation",
58285
+ auth: "admin"
58286
+ }), method(ActionIdInput, object({ traces: array(AutomationRunTraceSchema) }), { auth: "admin" }), method(object({ action: ActionInputSchema }), object({ action: ActionEntrySchema }), {
58287
+ kind: "mutation",
58288
+ auth: "admin"
58289
+ }), method(object({
58290
+ actionId: string().min(1),
58291
+ action: ActionInputSchema.partial()
58292
+ }), object({ action: ActionEntrySchema }), {
58293
+ kind: "mutation",
58294
+ auth: "admin"
58295
+ }), method(ActionIdInput, _void(), {
58296
+ kind: "mutation",
58297
+ auth: "admin"
58298
+ }), method(object({ deviceId: number().int().nonnegative() }), array(ActionEntrySchema), {
58299
+ role: "viewer",
58300
+ auth: "protected",
58301
+ kind: "query"
58302
+ }), method(object({ deviceId: number().int().nonnegative() }), ActionLinksSchema, { auth: "admin" }), method(ActionLinksSchema, ActionLinksSchema, {
58303
+ kind: "mutation",
58304
+ auth: "admin"
58305
+ });
57845
58306
  /**
57846
58307
  * Automation-control cap. Models HA `automation.*` entities on
57847
58308
  * `DeviceType.Automation`. An automation is a trigger+condition+
@@ -57938,7 +58399,7 @@ var BatteryStatusSchema = object({
57938
58399
  * Consumers must SKIP a null rather than coerce it — `battery-band` already
57939
58400
  * declines to band a non-finite reading, which is the correct shape.
57940
58401
  */
57941
- percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
58402
+ level: number().min(0).max(100).nullable().meta(readingMeta("percentage", { label: "Charge" })),
57942
58403
  /**
57943
58404
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
57944
58405
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -57948,7 +58409,7 @@ var BatteryStatusSchema = object({
57948
58409
  * `'unknown'` is the absence of an answer: the provider has not read the
57949
58410
  * power fields yet, or the firmware reported neither. Before it existed,
57950
58411
  * two unreadable fields produced `'none'`, and a camera nobody had reached
57951
- * was drawn "on battery alone" — the same D315 defect `percentage` closed
58412
+ * was drawn "on battery alone" — the same D315 defect `level` closed
57952
58413
  * by going nullable. Consumers SKIP it (no charger state published, no
57953
58414
  * glyph, no HomeKit ChargingState) rather than coerce it either way.
57954
58415
  */
@@ -57972,7 +58433,7 @@ var BatteryStatusSchema = object({
57972
58433
  * that only report charge. A second reading on this cap, not a second
57973
58434
  * `numeric-sensor` on the same device.
57974
58435
  */
57975
- volts: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
58436
+ voltage: number().nullable().optional().meta(readingMeta("voltage", { label: "Voltage" })),
57976
58437
  /**
57977
58438
  * Ms epoch of the last time the device PROVED it was reachable — a
57978
58439
  * completed firmware round-trip, an observed wake, or an inbound push
@@ -58006,7 +58467,7 @@ var BatteryStatusSchema = object({
58006
58467
  /**
58007
58468
  * True when the source is a BINARY low-battery indicator (HA
58008
58469
  * `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
58009
- * charge level — `percentage` is then a coarse stand-in (100 = normal,
58470
+ * charge level — `level` is then a coarse stand-in (100 = normal,
58010
58471
  * sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
58011
58472
  * misleading exact percentage. Absent/false → genuine 0–100 % reading.
58012
58473
  */
@@ -58026,15 +58487,15 @@ var BATTERY_DEVICE_TYPES = [
58026
58487
  var batteryCustomize = {
58027
58488
  version: 1,
58028
58489
  targets: [{
58029
- id: "percentage",
58490
+ id: "level",
58030
58491
  cardinality: "scalar",
58031
58492
  vocabulary: {
58032
58493
  cap: "battery",
58033
- stateField: "percentage"
58494
+ stateField: "level"
58034
58495
  },
58035
58496
  deviceTypes: BATTERY_DEVICE_TYPES,
58036
58497
  apply: "add",
58037
- path: "percentage",
58498
+ path: "level",
58038
58499
  sources: [{
58039
58500
  kind: "field",
58040
58501
  valueKinds: ["number", "string"],
@@ -58128,7 +58589,7 @@ onStatusChanged: { data: object({
58128
58589
  schema: BatteryStatusSchema,
58129
58590
  kind: "push",
58130
58591
  empty: {
58131
- percentage: null,
58592
+ level: null,
58132
58593
  charging: "unknown",
58133
58594
  sleeping: false,
58134
58595
  lastUpdated: 0
@@ -58155,11 +58616,11 @@ onStatusChanged: { data: object({
58155
58616
  * History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
58156
58617
  */
58157
58618
  history: { fields: {
58158
- percentage: {
58619
+ level: {
58159
58620
  kind: "gauge",
58160
58621
  unit: "%"
58161
58622
  },
58162
- volts: {
58623
+ voltage: {
58163
58624
  kind: "gauge",
58164
58625
  unit: "V"
58165
58626
  }
@@ -58219,14 +58680,14 @@ var binaryCapability = {
58219
58680
  * controls to this single-method surface.
58220
58681
  *
58221
58682
  * The cap is intentionally minimal: a single `setBrightness({deviceId,
58222
- * percentage})` mutation plus the auto-injected `getStatus`. Drivers
58683
+ * level})` mutation plus the auto-injected `getStatus`. Drivers
58223
58684
  * that expose richer controls (color temperature, scenes, schedules)
58224
58685
  * should surface those via the device's `getSettingsUISchema()`
58225
58686
  * instead of bloating this cap.
58226
58687
  */
58227
58688
  var BrightnessStatusSchema = object({
58228
58689
  /** Current level as 0..100 inclusive. Firmware-reported. */
58229
- percentage: number().min(0).max(100).meta(readingMeta("percentage")),
58690
+ level: number().min(0).max(100).meta(readingMeta("percentage")),
58230
58691
  /** Ms epoch of the last operator-driven change. Useful for UI freshness. */
58231
58692
  lastChangedAt: number()
58232
58693
  });
@@ -58238,7 +58699,7 @@ var brightnessCapability = {
58238
58699
  deviceTypes: [DeviceType.Light],
58239
58700
  methods: { setBrightness: method(object({
58240
58701
  deviceId: number().int().nonnegative(),
58241
- percentage: number().min(0).max(100)
58702
+ level: number().min(0).max(100)
58242
58703
  }), _void(), {
58243
58704
  kind: "mutation",
58244
58705
  auth: "protected"
@@ -58251,7 +58712,7 @@ var brightnessCapability = {
58251
58712
  */
58252
58713
  onBrightnessChanged: { data: object({
58253
58714
  deviceId: number(),
58254
- percentage: number().min(0).max(100),
58715
+ level: number().min(0).max(100),
58255
58716
  lastChangedAt: number()
58256
58717
  }) } },
58257
58718
  status: {
@@ -58274,7 +58735,7 @@ onBrightnessChanged: { data: object({
58274
58735
  /**
58275
58736
  * History (D850): recorded series. Actuator tier: level keeps every change.
58276
58737
  */
58277
- history: { fields: { percentage: {
58738
+ history: { fields: { level: {
58278
58739
  kind: "gauge",
58279
58740
  unit: "%",
58280
58741
  minIntervalMs: 0
@@ -58871,11 +59332,11 @@ var ColorInputSchema = discriminatedUnion("mode", [
58871
59332
  }),
58872
59333
  object({
58873
59334
  mode: literal("mired"),
58874
- mireds: number().int().min(50).max(1e3)
59335
+ colorTemperature: number().int().min(50).max(1e3)
58875
59336
  })
58876
59337
  ]);
58877
59338
  var ColorStatusSchema = object({
58878
- /** Active color mode — which of `rgb` / `hsv` / `mireds` reflects
59339
+ /** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
58879
59340
  * the bulb's current state. */
58880
59341
  mode: _enum([
58881
59342
  "rgb",
@@ -58887,7 +59348,7 @@ var ColorStatusSchema = object({
58887
59348
  /** Populated when `mode === 'hsv'`. */
58888
59349
  hsv: HsvTripletSchema.optional(),
58889
59350
  /** Populated when `mode === 'mired'`. */
58890
- mireds: number().int().optional().meta(readingMeta("colour-temperature")),
59351
+ colorTemperature: number().int().optional().meta(readingMeta("colour-temperature")),
58891
59352
  /** Ms epoch of the last operator-driven change. */
58892
59353
  lastChangedAt: number()
58893
59354
  });
@@ -58919,7 +59380,7 @@ onColorChanged: { data: object({
58919
59380
  ]),
58920
59381
  rgb: RgbTripletSchema.optional(),
58921
59382
  hsv: HsvTripletSchema.optional(),
58922
- mireds: number().int().optional(),
59383
+ colorTemperature: number().int().optional(),
58923
59384
  lastChangedAt: number()
58924
59385
  }) } },
58925
59386
  status: {
@@ -59796,11 +60257,11 @@ var DishwasherStatusSchema = object({
59796
60257
  /** Feature keys of the programs the appliance currently offers — drives the UI selector. */
59797
60258
  availablePrograms: array(string()),
59798
60259
  /** Seconds remaining on the active cycle, or null when not running / not known. */
59799
- remainingSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
60260
+ remaining: number().int().nonnegative().nullable().meta(readingMeta("duration")),
59800
60261
  /** Seconds the delayed start is set to (time until the cycle starts), or null. */
59801
- delayedStartSeconds: number().int().nonnegative().nullable().meta(readingMeta("duration")),
60262
+ delayedStart: number().int().nonnegative().nullable().meta(readingMeta("duration")),
59802
60263
  /** Cycle completion 0..100, or null when not applicable. */
59803
- progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
60264
+ progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
59804
60265
  /** True when the door is reported open; null when the door state is not known. */
59805
60266
  doorOpen: boolean().nullable(),
59806
60267
  /** True when the door is latched (locked) during a cycle; null when not reported. */
@@ -60019,14 +60480,14 @@ var dishwasherCapability = {
60019
60480
  runtimeState: DishwasherStatusSchema,
60020
60481
  durability: "session",
60021
60482
  history: { fields: {
60022
- progressPercent: {
60483
+ progress: {
60023
60484
  kind: "gauge",
60024
60485
  unit: "%",
60025
60486
  deadband: 2
60026
60487
  },
60027
60488
  state: { kind: "enum" },
60028
60489
  operationState: { kind: "enum" },
60029
- remainingSeconds: {
60490
+ remaining: {
60030
60491
  kind: "gauge",
60031
60492
  unit: "s",
60032
60493
  minIntervalMs: 6e4
@@ -60617,7 +61078,7 @@ var FanDirectionSchema = _enum(["forward", "reverse"]);
60617
61078
  var FanControlStatusSchema = object({
60618
61079
  /** Active speed as 0..100 inclusive. Null when the device has no
60619
61080
  * speed surface (single-speed fan). */
60620
- percentage: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
61081
+ speed: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
60621
61082
  /** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
60622
61083
  * a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
60623
61084
  percentageStep: number().positive().optional().meta(readingMeta("percentage")),
@@ -60644,7 +61105,7 @@ var fanControlCapability = {
60644
61105
  methods: {
60645
61106
  setPercentage: method(object({
60646
61107
  deviceId: number().int().nonnegative(),
60647
- percentage: number().min(0).max(100)
61108
+ speed: number().min(0).max(100)
60648
61109
  }), _void(), {
60649
61110
  kind: "mutation",
60650
61111
  auth: "protected"
@@ -60677,7 +61138,7 @@ var fanControlCapability = {
60677
61138
  },
60678
61139
  /**
60679
61140
  * Runtime-state slice — mirrored by the kernel. UI fan speed
60680
- * sliders read `percentage` for live updates.
61141
+ * sliders read `speed` for live updates.
60681
61142
  */
60682
61143
  runtimeState: FanControlStatusSchema,
60683
61144
  /**
@@ -60691,7 +61152,7 @@ var fanControlCapability = {
60691
61152
  * History (D850): recorded series. Actuator tier: speed keeps every change.
60692
61153
  */
60693
61154
  history: { fields: {
60694
- percentage: {
61155
+ speed: {
60695
61156
  kind: "gauge",
60696
61157
  unit: "%",
60697
61158
  minIntervalMs: 0
@@ -61136,7 +61597,7 @@ var humidifierCapability = {
61136
61597
  */
61137
61598
  var HumiditySensorStatusSchema = object({
61138
61599
  /** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
61139
- percent: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
61600
+ humidity: number().min(0).max(100).nullable().meta(readingMeta("humidity", {
61140
61601
  precision: 0,
61141
61602
  label: "Humidity"
61142
61603
  })),
@@ -61165,7 +61626,7 @@ var humiditySensorCapability = {
61165
61626
  /**
61166
61627
  * History (D850): recorded series.
61167
61628
  */
61168
- history: { fields: { percent: {
61629
+ history: { fields: { humidity: {
61169
61630
  kind: "gauge",
61170
61631
  unit: "%",
61171
61632
  deadband: .5
@@ -61805,7 +62266,7 @@ var LawnMowerControlStatusSchema = object({
61805
62266
  batteryLevel: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
61806
62267
  /** 0..100 mowing-completion percentage of the current task, or null when no
61807
62268
  * task is active / progress is unavailable. */
61808
- progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
62269
+ progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
61809
62270
  /** Current device/event code (dynamic — mostly status, sometimes an error),
61810
62271
  * or null when unknown. */
61811
62272
  currentCode: number().nullable().meta(readingMeta("none")),
@@ -62305,7 +62766,7 @@ var lockControlCapability = {
62305
62766
  volatileStateFields: ["lastChangedAt"]
62306
62767
  };
62307
62768
  /**
62308
- * A monotonic total between resets (D944). Energy uses `power-meter.kwhTotal`
62769
+ * A monotonic total between resets (D944). Energy uses `power-meter.energy`
62309
62770
  * so dashboards keep one series; every other instantaneous reading lands here.
62310
62771
  * `value` is the time integral in the source quantity's accumulated base
62311
62772
  * (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
@@ -62399,10 +62860,10 @@ var MediaPlayerStatusSchema = object({
62399
62860
  currentMedia: MediaInfoSchema.nullable(),
62400
62861
  /** Current playback position in ms. Null when not seekable or
62401
62862
  * nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
62402
- positionMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
62863
+ position: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
62403
62864
  /** Total duration of the current media in ms. Null when unknown
62404
62865
  * (live stream) or nothing is playing. */
62405
- durationMs: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
62866
+ duration: number().int().nonnegative().nullable().meta(readingMeta("duration-ms")),
62406
62867
  /** Shuffle toggle. Null when no shuffle surface.
62407
62868
  * Pair with `DeviceFeature.MediaPlayerShuffle`. */
62408
62869
  shuffle: boolean().nullable(),
@@ -62441,7 +62902,7 @@ var mediaPlayerCapability = {
62441
62902
  }),
62442
62903
  seek: method(object({
62443
62904
  deviceId: number().int().nonnegative(),
62444
- positionMs: number().int().nonnegative()
62905
+ position: number().int().nonnegative()
62445
62906
  }), _void(), {
62446
62907
  kind: "mutation",
62447
62908
  auth: "protected"
@@ -62513,7 +62974,7 @@ var mediaPlayerCapability = {
62513
62974
  /**
62514
62975
  * History (D850): volume (a level an operator or an automation sets; the
62515
62976
  * default 10 s floor folds a slider drag into its end value) and mute.
62516
- * `positionMs` is not recorded: it moves continuously while playing.
62977
+ * `position` is not recorded: it moves continuously while playing.
62517
62978
  */
62518
62979
  history: { fields: {
62519
62980
  volumeLevel: {
@@ -63475,9 +63936,9 @@ var NetworkLinkStatusSchema = object({
63475
63936
  * one whose reading has not landed must not be drawn at 0 %. Consumers
63476
63937
  * SKIP a null rather than coerce it.
63477
63938
  */
63478
- signalPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
63939
+ signal: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
63479
63940
  /** Raw received signal strength in dBm, when the firmware reports one. */
63480
- rssiDbm: number().optional().meta(readingMeta("signal-level")),
63941
+ rssi: number().optional().meta(readingMeta("signal-level")),
63481
63942
  /** Network name of a wireless link, when the firmware reports it. */
63482
63943
  ssid: string().optional(),
63483
63944
  /** Ms epoch of the last observation. Lets consumers reason about freshness. */
@@ -63513,7 +63974,7 @@ onStatusChanged: { data: object({
63513
63974
  kind: "push",
63514
63975
  empty: {
63515
63976
  type: "unknown",
63516
- signalPercent: null,
63977
+ signal: null,
63517
63978
  lastUpdated: 0
63518
63979
  }
63519
63980
  },
@@ -63536,13 +63997,13 @@ onStatusChanged: { data: object({
63536
63997
  * History (D850): recorded series.
63537
63998
  */
63538
63999
  history: { fields: {
63539
- signalPercent: {
64000
+ signal: {
63540
64001
  kind: "gauge",
63541
64002
  unit: "%",
63542
64003
  deadband: 3,
63543
64004
  minIntervalMs: 6e4
63544
64005
  },
63545
- rssiDbm: {
64006
+ rssi: {
63546
64007
  kind: "gauge",
63547
64008
  unit: "dBm",
63548
64009
  deadband: 2,
@@ -64287,10 +64748,20 @@ var PetFeederDeviceStatusSchema = _enum([
64287
64748
  ]);
64288
64749
  var gramsPortion = number().int().min(4).max(200);
64289
64750
  var PetFeederStatusSchema = object({
64290
- /** Food currently in the bowl (grams). Null when the device has not
64291
- * reported a reading yet. On dual-hopper models this is the combined
64292
- * bowl reading; per-hopper levels live in `food1`/`food2`. */
64751
+ /** Food in the TANK (hopper), as the feeder's own sensor reports it
64752
+ * (`state.food`). A coarse level code, not grams — `0` is empty. The
64753
+ * amount in the bowl is `bowlFood`. On dual-hopper models this is the
64754
+ * combined reading; per-hopper levels live in `food1`/`food2`. Null when
64755
+ * the device has not reported yet. */
64293
64756
  foodLevel: number().nullable().meta(readingMeta("none")),
64757
+ /** Food in the BOWL as the feeder reports it (`state.bowl`), in the
64758
+ * feeder's own units. Null when the model reports none. */
64759
+ bowlFood: number().nullable().meta(readingMeta("none")),
64760
+ /** True while the pet is eating (`state.eating`). */
64761
+ eating: boolean(),
64762
+ /** Whether `markFoodReplenished` does anything on this model. When false
64763
+ * the client must not offer it. */
64764
+ supportsMarkRefilled: boolean(),
64294
64765
  /** Hopper-1 food level (grams) on dual-hopper feeders; null on
64295
64766
  * single-hopper models. */
64296
64767
  food1: number().nullable().meta(readingMeta("none")),
@@ -64298,8 +64769,8 @@ var PetFeederStatusSchema = object({
64298
64769
  * single-hopper models. */
64299
64770
  food2: number().nullable().meta(readingMeta("none")),
64300
64771
  /** Derived low-food flag — mirrors the HA `food_level` binary_sensor
64301
- * (`device_class: problem`, on = low). True when the bowl is empty /
64302
- * below the feeder's low threshold. */
64772
+ * (`device_class: problem`, on = low). True when the tank reports empty,
64773
+ * or, on a dual-hopper model, when EITHER hopper is empty. */
64303
64774
  lowFood: boolean(),
64304
64775
  /** Battery charge 0..100 (%). Null on mains-powered models or when the
64305
64776
  * device has no battery reading. */
@@ -64367,7 +64838,9 @@ var petFeederCapability = {
64367
64838
  kind: "mutation",
64368
64839
  auth: "protected"
64369
64840
  }),
64370
- /** Mark a hopper as refilled (D4H/D4S/D4SH). */
64841
+ /** Tell the PetKit cloud a hopper was refilled so it stops its low-food
64842
+ * reminders (D4H/D4S/D4SH only — see `supportsMarkRefilled`). It does not
64843
+ * change any sensor reading. */
64371
64844
  markFoodReplenished: method(object({ deviceId: number().int().nonnegative() }), _void(), {
64372
64845
  kind: "mutation",
64373
64846
  auth: "protected"
@@ -64440,6 +64913,7 @@ var petFeederCapability = {
64440
64913
  */
64441
64914
  history: { fields: {
64442
64915
  foodLevel: { kind: "gauge" },
64916
+ bowlFood: { kind: "gauge" },
64443
64917
  food1: { kind: "gauge" },
64444
64918
  food2: { kind: "gauge" },
64445
64919
  batteryPower: {
@@ -64849,16 +65323,16 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
64849
65323
  * in real-world devices.
64850
65324
  */
64851
65325
  var PowerMeterStatusSchema = object({
64852
- /** Instantaneous power draw in watts. */
64853
- watts: number().optional().meta(readingMeta("power", { label: "Power" })),
65326
+ /** Instantaneous power draw (watts). */
65327
+ power: number().optional().meta(readingMeta("power", { label: "Power" })),
64854
65328
  /** Cumulative energy in kilowatt-hours since the meter was reset. */
64855
- kwhTotal: number().optional().meta(readingMeta("energy", { label: "Energy" })),
64856
- /** Voltage in volts. */
64857
- volts: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
65329
+ energy: number().optional().meta(readingMeta("energy", { label: "Energy" })),
65330
+ /** Voltage (volts). */
65331
+ voltage: number().optional().meta(readingMeta("voltage", { label: "Voltage" })),
64858
65332
  /** Current in amperes. */
64859
- amps: number().optional().meta(readingMeta("current", { label: "Current" })),
65333
+ current: number().optional().meta(readingMeta("current", { label: "Current" })),
64860
65334
  /** Apparent power in volt-amperes. */
64861
- va: number().optional().meta(readingMeta("apparent-power")),
65335
+ apparentPower: number().optional().meta(readingMeta("apparent-power")),
64862
65336
  /** Power factor (0..1) if reported. */
64863
65337
  powerFactor: number().min(0).max(1).optional().meta(readingMeta("ratio")),
64864
65338
  /** Ms epoch when the slice was last updated. */
@@ -64916,14 +65390,14 @@ function powerTarget(id, unit) {
64916
65390
  advancedExpression: true
64917
65391
  };
64918
65392
  }
64919
- /** "Power and energy" extension: watts, energy, voltage and current from other devices (D951). */
65393
+ /** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
64920
65394
  var powerMeterCustomize = {
64921
65395
  version: 1,
64922
65396
  targets: [
64923
- powerTarget("watts", "W"),
64924
- powerTarget("kwhTotal", "kWh"),
64925
- powerTarget("volts", "V"),
64926
- powerTarget("amps", "A")
65397
+ powerTarget("power", "W"),
65398
+ powerTarget("energy", "kWh"),
65399
+ powerTarget("voltage", "V"),
65400
+ powerTarget("current", "A")
64927
65401
  ]
64928
65402
  };
64929
65403
  var powerMeterCapability = {
@@ -64939,41 +65413,41 @@ var powerMeterCapability = {
64939
65413
  },
64940
65414
  runtimeState: PowerMeterStatusSchema,
64941
65415
  /**
64942
- * Runtime-state durability: **restored** — as `numeric-sensor`; `kwhTotal` is an accumulator whose restored value is the baseline.
65416
+ * Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
64943
65417
  *
64944
65418
  * See `RuntimeStateDurability`. Enforced by
64945
65419
  * `scripts/check-runtime-state-durability.ts`.
64946
65420
  */
64947
65421
  durability: "restored",
64948
65422
  /**
64949
- * History (D850): recorded series. Gauges are floored at 30 s; `kwhTotal` is the one monotonic meter (counter).
65423
+ * History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
64950
65424
  */
64951
65425
  history: { fields: {
64952
- watts: {
65426
+ power: {
64953
65427
  kind: "gauge",
64954
65428
  unit: "W",
64955
65429
  deadband: 1,
64956
65430
  minIntervalMs: 3e4
64957
65431
  },
64958
- kwhTotal: {
65432
+ energy: {
64959
65433
  kind: "counter",
64960
65434
  unit: "kWh",
64961
65435
  deadband: .01,
64962
65436
  minIntervalMs: 6e4
64963
65437
  },
64964
- volts: {
65438
+ voltage: {
64965
65439
  kind: "gauge",
64966
65440
  unit: "V",
64967
65441
  deadband: 1,
64968
65442
  minIntervalMs: 3e4
64969
65443
  },
64970
- amps: {
65444
+ current: {
64971
65445
  kind: "gauge",
64972
65446
  unit: "A",
64973
65447
  deadband: .05,
64974
65448
  minIntervalMs: 3e4
64975
65449
  },
64976
- va: {
65450
+ apparentPower: {
64977
65451
  kind: "gauge",
64978
65452
  unit: "VA",
64979
65453
  deadband: 1,
@@ -65023,9 +65497,6 @@ var PresenceStatusSchema = object({
65023
65497
  location: string().nullable(),
65024
65498
  /** GPS coordinates when available. Null otherwise. */
65025
65499
  gps: GpsLocationSchema.nullable(),
65026
- /** Optional battery level of the tracking device (0..100). Null
65027
- * when not reported. */
65028
- batteryPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
65029
65500
  /** Ms epoch when the slice was last updated. */
65030
65501
  lastChangedAt: number()
65031
65502
  });
@@ -65054,14 +65525,7 @@ var presenceCapability = {
65054
65525
  * `scripts/check-runtime-state-durability.ts`.
65055
65526
  */
65056
65527
  durability: "restored",
65057
- /**
65058
- * History (D850): recorded series.
65059
- */
65060
- history: { fields: { batteryPercent: {
65061
- kind: "gauge",
65062
- unit: "%",
65063
- deadband: 1
65064
- } } },
65528
+ history: "none",
65065
65529
  /** Clock fields: written, but excluded from the compare that decides
65066
65530
  * whether persisting is worth a SQLite commit. */
65067
65531
  volatileStateFields: ["lastChangedAt"]
@@ -65076,7 +65540,7 @@ var presenceCapability = {
65076
65540
  */
65077
65541
  var PressureSensorStatusSchema = object({
65078
65542
  /** Current pressure in hPa. `null` when the sample was refused (D393). */
65079
- hpa: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
65543
+ pressure: number().nullable().meta(readingMeta("pressure", { precision: 0 })),
65080
65544
  /** Ms epoch when the slice was last updated. */
65081
65545
  lastFetchedAt: number()
65082
65546
  });
@@ -65102,7 +65566,7 @@ var pressureSensorCapability = {
65102
65566
  /**
65103
65567
  * History (D850): recorded series.
65104
65568
  */
65105
- history: { fields: { hpa: {
65569
+ history: { fields: { pressure: {
65106
65570
  kind: "gauge",
65107
65571
  unit: "hPa",
65108
65572
  deadband: .1
@@ -68801,7 +69265,7 @@ var tamperCapability = {
68801
69265
  */
68802
69266
  var TemperatureSensorStatusSchema = object({
68803
69267
  /** Current temperature in Celsius. `null` when the sample was refused (D393). */
68804
- celsius: number().nullable().meta(readingMeta("temperature", {
69268
+ temperature: number().nullable().meta(readingMeta("temperature", {
68805
69269
  precision: 1,
68806
69270
  label: "Temperature"
68807
69271
  })),
@@ -68830,7 +69294,7 @@ var temperatureSensorCapability = {
68830
69294
  /**
68831
69295
  * History (D850): recorded series.
68832
69296
  */
68833
- history: { fields: { celsius: {
69297
+ history: { fields: { temperature: {
68834
69298
  kind: "gauge",
68835
69299
  unit: "°C",
68836
69300
  deadband: .1
@@ -69127,7 +69591,7 @@ var VacuumControlStatusSchema = object({
69127
69591
  /** Speed tokens the hardware accepts — drives the UI selector. */
69128
69592
  availableFanSpeeds: array(string()),
69129
69593
  /** 0..100 cleaning-completion percentage of the current task, or null. */
69130
- progressPercent: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
69594
+ progress: number().min(0).max(100).nullable().meta(readingMeta("percentage")),
69131
69595
  /** Current error code (0 / null = no error). */
69132
69596
  errorCode: number().nullable().meta(readingMeta("none")),
69133
69597
  /** Human label for {@link errorCode}, or null when none / undecodable. */
@@ -71164,7 +71628,7 @@ var BaseDevice = class {
71164
71628
  * `device-local-state.ts`. Drivers access via:
71165
71629
  *
71166
71630
  * `this.state.battery.sleeping = true` // patches the battery slice
71167
- * `const pct = this.state.battery.percentage` // reads the battery slice
71631
+ * `const pct = this.state.battery.level` // reads the battery slice
71168
71632
  * `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
71169
71633
  *
71170
71634
  * Adding a new cap with `runtimeState:` automatically extends this
@@ -71204,7 +71668,7 @@ var BaseDevice = class {
71204
71668
  * shape; drivers don't redeclare it, they just write through.
71205
71669
  *
71206
71670
  * Read: `this.runtimeState.getCapState('battery')` →
71207
- * `{percentage, charging, sleeping, lastUpdated}` for any
71671
+ * `{level, charging, sleeping, lastUpdated}` for any
71208
71672
  * provider that registers `batteryCapability`.
71209
71673
  * Write: `this.runtimeState.setCapState('battery', { … })`.
71210
71674
  *
@@ -72378,6 +72842,104 @@ Object.freeze({
72378
72842
  access: "create",
72379
72843
  role: "admin"
72380
72844
  },
72845
+ "actions.create": {
72846
+ capName: "actions",
72847
+ capScope: "system",
72848
+ addonId: null,
72849
+ access: "create",
72850
+ role: "admin"
72851
+ },
72852
+ "actions.delete": {
72853
+ capName: "actions",
72854
+ capScope: "system",
72855
+ addonId: null,
72856
+ access: "delete",
72857
+ role: "admin"
72858
+ },
72859
+ "actions.get": {
72860
+ capName: "actions",
72861
+ capScope: "system",
72862
+ addonId: null,
72863
+ access: "view",
72864
+ role: "viewer"
72865
+ },
72866
+ "actions.getLinks": {
72867
+ capName: "actions",
72868
+ capScope: "system",
72869
+ addonId: null,
72870
+ access: "view",
72871
+ role: "admin"
72872
+ },
72873
+ "actions.getTraces": {
72874
+ capName: "actions",
72875
+ capScope: "system",
72876
+ addonId: null,
72877
+ access: "view",
72878
+ role: "admin"
72879
+ },
72880
+ "actions.list": {
72881
+ capName: "actions",
72882
+ capScope: "system",
72883
+ addonId: null,
72884
+ access: "view",
72885
+ role: "admin"
72886
+ },
72887
+ "actions.listForCamera": {
72888
+ capName: "actions",
72889
+ capScope: "system",
72890
+ addonId: null,
72891
+ access: "view",
72892
+ role: "viewer"
72893
+ },
72894
+ "actions.run": {
72895
+ capName: "actions",
72896
+ capScope: "system",
72897
+ addonId: null,
72898
+ access: "create",
72899
+ role: "viewer"
72900
+ },
72901
+ "actions.setLinks": {
72902
+ capName: "actions",
72903
+ capScope: "system",
72904
+ addonId: null,
72905
+ access: "create",
72906
+ role: "admin"
72907
+ },
72908
+ "actions.stop": {
72909
+ capName: "actions",
72910
+ capScope: "system",
72911
+ addonId: null,
72912
+ access: "create",
72913
+ role: "admin"
72914
+ },
72915
+ "actions.update": {
72916
+ capName: "actions",
72917
+ capScope: "system",
72918
+ addonId: null,
72919
+ access: "create",
72920
+ role: "admin"
72921
+ },
72922
+ "actionSource.listActions": {
72923
+ capName: "action-source",
72924
+ capScope: "system",
72925
+ addonId: null,
72926
+ access: "view",
72927
+ role: "admin"
72928
+ },
72929
+ "actionSource.runAction": {
72930
+ capName: "action-source",
72931
+ capScope: "system",
72932
+ addonId: null,
72933
+ access: "create",
72934
+ role: "admin"
72935
+ },
72936
+ "actionSource.stopAction": {
72937
+ capName: "action-source",
72938
+ capScope: "system",
72939
+ addonId: null,
72940
+ access: "create",
72941
+ role: "admin"
72942
+ },
72381
72943
  "addonPages.listPages": {
72382
72944
  capName: "addon-pages",
72383
72945
  capScope: "system",
@@ -73659,6 +74221,13 @@ Object.freeze({
73659
74221
  access: "view",
73660
74222
  role: "admin"
73661
74223
  },
74224
+ "coreBlocks.getAutomationRunState": {
74225
+ capName: "core-blocks",
74226
+ capScope: "system",
74227
+ addonId: null,
74228
+ access: "view",
74229
+ role: "admin"
74230
+ },
73662
74231
  "coreBlocks.getBlockSettings": {
73663
74232
  capName: "core-blocks",
73664
74233
  capScope: "system",
@@ -73680,6 +74249,13 @@ Object.freeze({
73680
74249
  access: "view",
73681
74250
  role: "admin"
73682
74251
  },
74252
+ "coreBlocks.getTraces": {
74253
+ capName: "core-blocks",
74254
+ capScope: "system",
74255
+ addonId: null,
74256
+ access: "view",
74257
+ role: "admin"
74258
+ },
73683
74259
  "coreBlocks.getTypeDefs": {
73684
74260
  capName: "core-blocks",
73685
74261
  capScope: "system",
@@ -73715,6 +74291,13 @@ Object.freeze({
73715
74291
  access: "create",
73716
74292
  role: "admin"
73717
74293
  },
74294
+ "coreBlocks.reportAutomationRun": {
74295
+ capName: "core-blocks",
74296
+ capScope: "system",
74297
+ addonId: null,
74298
+ access: "create",
74299
+ role: "admin"
74300
+ },
73718
74301
  "coreBlocks.restart": {
73719
74302
  capName: "core-blocks",
73720
74303
  capScope: "system",
@@ -82288,7 +82871,7 @@ var ACTUATOR_CAP_VOCABULARY = {
82288
82871
  label: t("Full brightness", "Luminosità massima"),
82289
82872
  phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
82290
82873
  icon: "sun",
82291
- args: { percentage: 100 }
82874
+ args: { level: 100 }
82292
82875
  },
82293
82876
  {
82294
82877
  id: "brightness.half",
@@ -82296,7 +82879,7 @@ var ACTUATOR_CAP_VOCABULARY = {
82296
82879
  label: t("Half brightness", "Luminosità a metà"),
82297
82880
  phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
82298
82881
  icon: "sun-dim",
82299
- args: { percentage: 50 }
82882
+ args: { level: 50 }
82300
82883
  },
82301
82884
  {
82302
82885
  id: "brightness.off",
@@ -82304,16 +82887,16 @@ var ACTUATOR_CAP_VOCABULARY = {
82304
82887
  label: t("Brightness off", "Luminosità a zero"),
82305
82888
  phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
82306
82889
  icon: "lightbulb-off",
82307
- args: { percentage: 0 }
82890
+ args: { level: 0 }
82308
82891
  },
82309
82892
  {
82310
82893
  id: "brightness.set",
82311
82894
  method: "setBrightness",
82312
82895
  label: t("Set brightness", "Imposta la luminosità"),
82313
- phrase: t("Set the brightness of {device} to {percentage}", "Imposta la luminosità di {device} a {percentage}"),
82896
+ phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
82314
82897
  icon: "sun-medium",
82315
82898
  openArgs: [{
82316
- key: "percentage",
82899
+ key: "level",
82317
82900
  label: PERCENT,
82318
82901
  offer: {
82319
82902
  kind: "number",
@@ -82327,13 +82910,13 @@ var ACTUATOR_CAP_VOCABULARY = {
82327
82910
  ],
82328
82911
  state: [{
82329
82912
  kind: "numeric",
82330
- field: "percentage",
82913
+ field: "level",
82331
82914
  quantity: t("the brightness", "la luminosità"),
82332
82915
  label: t("Brightness", "Luminosità"),
82333
82916
  unit: "%",
82334
82917
  icon: "sun"
82335
82918
  }],
82336
- events: { onBrightnessChanged: { notOperatorFacing: "the `percentage` state trigger reads the same change" } }
82919
+ events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
82337
82920
  },
82338
82921
  color: {
82339
82922
  scope: "device",
@@ -82347,7 +82930,7 @@ var ACTUATOR_CAP_VOCABULARY = {
82347
82930
  icon: "sun",
82348
82931
  args: { color: {
82349
82932
  mode: "mired",
82350
- mireds: 370
82933
+ colorTemperature: 370
82351
82934
  } }
82352
82935
  },
82353
82936
  {
@@ -82358,7 +82941,7 @@ var ACTUATOR_CAP_VOCABULARY = {
82358
82941
  icon: "snowflake",
82359
82942
  args: { color: {
82360
82943
  mode: "mired",
82361
- mireds: 200
82944
+ colorTemperature: 200
82362
82945
  } }
82363
82946
  },
82364
82947
  {
@@ -82972,7 +83555,7 @@ var ACTUATOR_CAP_VOCABULARY = {
82972
83555
  label: t("Fan off", "Ventilatore spento"),
82973
83556
  phrase: t("Stop {device}", "Ferma {device}"),
82974
83557
  icon: "power-off",
82975
- args: { percentage: 0 }
83558
+ args: { speed: 0 }
82976
83559
  },
82977
83560
  {
82978
83561
  id: "fan.full",
@@ -82980,16 +83563,16 @@ var ACTUATOR_CAP_VOCABULARY = {
82980
83563
  label: t("Fan full", "Ventilatore al massimo"),
82981
83564
  phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
82982
83565
  icon: "fan",
82983
- args: { percentage: 100 }
83566
+ args: { speed: 100 }
82984
83567
  },
82985
83568
  {
82986
83569
  id: "fan.speed",
82987
83570
  method: "setPercentage",
82988
83571
  label: t("Set speed", "Imposta la velocità"),
82989
- phrase: t("Set the speed of {device} to {percentage}", "Imposta la velocità di {device} al {percentage}"),
83572
+ phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
82990
83573
  icon: "fan",
82991
83574
  openArgs: [{
82992
- key: "percentage",
83575
+ key: "speed",
82993
83576
  label: t("Speed", "Velocità"),
82994
83577
  offer: {
82995
83578
  kind: "number",
@@ -83051,7 +83634,7 @@ var ACTUATOR_CAP_VOCABULARY = {
83051
83634
  ],
83052
83635
  state: [{
83053
83636
  kind: "numeric",
83054
- field: "percentage",
83637
+ field: "speed",
83055
83638
  quantity: t("the speed", "la velocità"),
83056
83639
  label: t("Speed", "Velocità"),
83057
83640
  unit: "%",
@@ -83849,7 +84432,7 @@ var APPLIANCE_CAP_VOCABULARY = {
83849
84432
  },
83850
84433
  {
83851
84434
  kind: "numeric",
83852
- field: "progressPercent",
84435
+ field: "progress",
83853
84436
  quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
83854
84437
  label: t("Progress", "Avanzamento"),
83855
84438
  unit: "%",
@@ -84207,10 +84790,10 @@ var APPLIANCE_CAP_VOCABULARY = {
84207
84790
  id: "media.seek",
84208
84791
  method: "seek",
84209
84792
  label: t("Seek", "Vai al punto"),
84210
- phrase: t("Move {device} to {positionMs}", "Porta {device} al punto {positionMs}"),
84793
+ phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
84211
84794
  icon: "fast-forward",
84212
84795
  openArgs: [{
84213
- key: "positionMs",
84796
+ key: "position",
84214
84797
  label: t("Position", "Posizione"),
84215
84798
  offer: {
84216
84799
  kind: "number",
@@ -85259,7 +85842,7 @@ var SENSOR_CAP_VOCABULARY = {
85259
85842
  state: [
85260
85843
  {
85261
85844
  kind: "numeric",
85262
- field: "co2Ppm",
85845
+ field: "co2",
85263
85846
  quantity: t("the CO₂", "la CO₂"),
85264
85847
  label: t("CO₂", "CO₂"),
85265
85848
  unit: "ppm",
@@ -85267,7 +85850,7 @@ var SENSOR_CAP_VOCABULARY = {
85267
85850
  },
85268
85851
  {
85269
85852
  kind: "numeric",
85270
- field: "vocPpb",
85853
+ field: "voc",
85271
85854
  quantity: t("the VOC level", "il livello di COV"),
85272
85855
  label: t("VOC", "COV"),
85273
85856
  unit: "ppb",
@@ -85303,7 +85886,7 @@ var SENSOR_CAP_VOCABULARY = {
85303
85886
  noun: t("Light level", "Luminosità ambiente"),
85304
85887
  state: [{
85305
85888
  kind: "numeric",
85306
- field: "lux",
85889
+ field: "illuminance",
85307
85890
  quantity: t("the light level", "la luminosità"),
85308
85891
  label: t("Illuminance", "Illuminamento"),
85309
85892
  unit: "lx",
@@ -85506,7 +86089,7 @@ var SENSOR_CAP_VOCABULARY = {
85506
86089
  noun: t("Humidity", "Umidità"),
85507
86090
  state: [{
85508
86091
  kind: "numeric",
85509
- field: "percent",
86092
+ field: "humidity",
85510
86093
  quantity: t("the humidity", "l’umidità"),
85511
86094
  label: t("Humidity", "Umidità"),
85512
86095
  unit: "%",
@@ -85554,7 +86137,7 @@ var SENSOR_CAP_VOCABULARY = {
85554
86137
  state: [
85555
86138
  {
85556
86139
  kind: "numeric",
85557
- field: "watts",
86140
+ field: "power",
85558
86141
  quantity: t("the power draw", "il consumo"),
85559
86142
  label: t("Power", "Potenza"),
85560
86143
  unit: "W",
@@ -85562,7 +86145,7 @@ var SENSOR_CAP_VOCABULARY = {
85562
86145
  },
85563
86146
  {
85564
86147
  kind: "numeric",
85565
- field: "kwhTotal",
86148
+ field: "energy",
85566
86149
  quantity: t("the energy used", "l’energia consumata"),
85567
86150
  label: t("Energy", "Energia"),
85568
86151
  unit: "kWh",
@@ -85570,7 +86153,7 @@ var SENSOR_CAP_VOCABULARY = {
85570
86153
  },
85571
86154
  {
85572
86155
  kind: "numeric",
85573
- field: "volts",
86156
+ field: "voltage",
85574
86157
  quantity: t("the voltage", "la tensione"),
85575
86158
  label: t("Voltage", "Tensione"),
85576
86159
  unit: "V",
@@ -85578,7 +86161,7 @@ var SENSOR_CAP_VOCABULARY = {
85578
86161
  },
85579
86162
  {
85580
86163
  kind: "numeric",
85581
- field: "amps",
86164
+ field: "current",
85582
86165
  quantity: t("the current", "la corrente"),
85583
86166
  label: t("Current", "Corrente"),
85584
86167
  unit: "A",
@@ -85595,13 +86178,6 @@ var SENSOR_CAP_VOCABULARY = {
85595
86178
  label: t("Where", "Posizione"),
85596
86179
  phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
85597
86180
  icon: "map-pin"
85598
- }, {
85599
- kind: "numeric",
85600
- field: "batteryPercent",
85601
- quantity: t("the phone battery", "la batteria del telefono"),
85602
- label: t("Battery", "Batteria"),
85603
- unit: "%",
85604
- icon: "battery"
85605
86181
  }]
85606
86182
  },
85607
86183
  "pressure-sensor": {
@@ -85609,7 +86185,7 @@ var SENSOR_CAP_VOCABULARY = {
85609
86185
  noun: t("Pressure", "Pressione"),
85610
86186
  state: [{
85611
86187
  kind: "numeric",
85612
- field: "hpa",
86188
+ field: "pressure",
85613
86189
  quantity: t("the pressure", "la pressione"),
85614
86190
  label: t("Pressure", "Pressione"),
85615
86191
  unit: "hPa",
@@ -85645,7 +86221,7 @@ var SENSOR_CAP_VOCABULARY = {
85645
86221
  noun: t("Temperature", "Temperatura"),
85646
86222
  state: [{
85647
86223
  kind: "numeric",
85648
- field: "celsius",
86224
+ field: "temperature",
85649
86225
  quantity: t("the temperature", "la temperatura"),
85650
86226
  label: t("Temperature", "Temperatura"),
85651
86227
  unit: "°C",
@@ -85716,7 +86292,7 @@ var SENSOR_CAP_VOCABULARY = {
85716
86292
  state: [
85717
86293
  {
85718
86294
  kind: "numeric",
85719
- field: "percentage",
86295
+ field: "level",
85720
86296
  quantity: t("the battery level", "il livello della batteria"),
85721
86297
  label: t("Battery", "Batteria"),
85722
86298
  unit: "%",
@@ -85758,7 +86334,7 @@ var SENSOR_CAP_VOCABULARY = {
85758
86334
  icon: "battery-charging"
85759
86335
  }
85760
86336
  ],
85761
- events: { onStatusChanged: { notOperatorFacing: "the percentage / sleeping / charging state triggers each read one field of this change" } },
86337
+ events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
85762
86338
  extraEvents: [{
85763
86339
  category: EventCategory.DeviceAwake,
85764
86340
  label: t("Woke up", "Risvegliato"),
@@ -85776,7 +86352,7 @@ var SENSOR_CAP_VOCABULARY = {
85776
86352
  noun: t("Network link", "Collegamento di rete"),
85777
86353
  state: [{
85778
86354
  kind: "numeric",
85779
- field: "signalPercent",
86355
+ field: "signal",
85780
86356
  quantity: t("the signal strength", "l’intensità del segnale"),
85781
86357
  label: t("Signal", "Segnale"),
85782
86358
  unit: "%",
@@ -85869,6 +86445,8 @@ var ML = "model and training machinery — no device action";
85869
86445
  var INTERNAL = "internal plumbing between addons — never operator-facing";
85870
86446
  /** Every system-scoped cap, with why it is not a device's vocabulary. */
85871
86447
  var SYSTEM_CAP_VOCABULARY = {
86448
+ "action-source": system(INTERNAL),
86449
+ actions: system("declared actions — run from the Actions page and from the cameras that link them"),
85872
86450
  "addon-pages": system(UI_PLUMBING),
85873
86451
  "addon-pages-source": system(UI_PLUMBING),
85874
86452
  "addon-routes": system(UI_PLUMBING),
@@ -86065,6 +86643,31 @@ Object.freeze({
86065
86643
  form: "single",
86066
86644
  optional: false
86067
86645
  }],
86646
+ "actions.get": [{
86647
+ name: "deviceId",
86648
+ form: "single",
86649
+ optional: true
86650
+ }],
86651
+ "actions.getLinks": [{
86652
+ name: "deviceId",
86653
+ form: "single",
86654
+ optional: false
86655
+ }],
86656
+ "actions.listForCamera": [{
86657
+ name: "deviceId",
86658
+ form: "single",
86659
+ optional: false
86660
+ }],
86661
+ "actions.run": [{
86662
+ name: "deviceId",
86663
+ form: "single",
86664
+ optional: true
86665
+ }],
86666
+ "actions.setLinks": [{
86667
+ name: "deviceId",
86668
+ form: "single",
86669
+ optional: false
86670
+ }],
86068
86671
  "addonSettings.getDeviceSettings": [{
86069
86672
  name: "deviceId",
86070
86673
  form: "single",
@@ -90288,6 +90891,7 @@ function bestLocationMatch(externalName, existing, threshold = .8) {
90288
90891
  }
90289
90892
  return best;
90290
90893
  }
90894
+ String.raw`(?<=^|["'(\s>,\[{])`;
90291
90895
  var MB = 1024 * 1024;
90292
90896
  1024 * MB, 3072 * MB;
90293
90897
  //#endregion
@@ -115640,15 +116244,15 @@ var HmActuatorDevice = class extends HmChildDevice {
115640
116244
  * keep that class a thin actuator-wiring layer.
115641
116245
  */
115642
116246
  var COLD_TEMPERATURE = {
115643
- celsius: 0,
116247
+ temperature: 0,
115644
116248
  lastFetchedAt: 0
115645
116249
  };
115646
116250
  var COLD_HUMIDITY = {
115647
- percent: 0,
116251
+ humidity: 0,
115648
116252
  lastFetchedAt: 0
115649
116253
  };
115650
116254
  var COLD_AMBIENT_LIGHT = {
115651
- lux: 0,
116255
+ illuminance: 0,
115652
116256
  lastFetchedAt: 0
115653
116257
  };
115654
116258
  var COLD_POWER = { lastFetchedAt: 0 };
@@ -115740,15 +116344,15 @@ var HmSensorDevice = class extends HmChildDevice {
115740
116344
  decodeSensorPush(parameter, value, now) {
115741
116345
  if (typeof value !== "number") return;
115742
116346
  if (this.caps.has("temperature-sensor") && parameter === "ACTUAL_TEMPERATURE") this.runtimeState.setCapState("temperature-sensor", {
115743
- celsius: value,
116347
+ temperature: value,
115744
116348
  lastFetchedAt: now
115745
116349
  });
115746
116350
  if (this.caps.has("humidity-sensor") && parameter === "HUMIDITY") this.runtimeState.setCapState("humidity-sensor", {
115747
- percent: value,
116351
+ humidity: value,
115748
116352
  lastFetchedAt: now
115749
116353
  });
115750
116354
  if (this.caps.has("ambient-light-sensor") && parameter === "ILLUMINATION") this.runtimeState.setCapState("ambient-light-sensor", {
115751
- lux: Math.max(0, value),
116355
+ illuminance: Math.max(0, value),
115752
116356
  lastFetchedAt: now
115753
116357
  });
115754
116358
  this.decodePowerPush(parameter, value, now);
@@ -115761,28 +116365,28 @@ var HmSensorDevice = class extends HmChildDevice {
115761
116365
  case "POWER":
115762
116366
  this.runtimeState.setCapState("power-meter", {
115763
116367
  ...prev,
115764
- watts: value,
116368
+ power: value,
115765
116369
  lastFetchedAt: now
115766
116370
  });
115767
116371
  return;
115768
116372
  case "ENERGY_COUNTER":
115769
116373
  this.runtimeState.setCapState("power-meter", {
115770
116374
  ...prev,
115771
- kwhTotal: value / 1e3,
116375
+ energy: value / 1e3,
115772
116376
  lastFetchedAt: now
115773
116377
  });
115774
116378
  return;
115775
116379
  case "VOLTAGE":
115776
116380
  this.runtimeState.setCapState("power-meter", {
115777
116381
  ...prev,
115778
- volts: value,
116382
+ voltage: value,
115779
116383
  lastFetchedAt: now
115780
116384
  });
115781
116385
  return;
115782
116386
  case "CURRENT":
115783
116387
  this.runtimeState.setCapState("power-meter", {
115784
116388
  ...prev,
115785
- amps: value / 1e3,
116389
+ current: value / 1e3,
115786
116390
  lastFetchedAt: now
115787
116391
  });
115788
116392
  return;
@@ -115880,7 +116484,7 @@ var COLD_BINARY = {
115880
116484
  lastChangedAt: 0
115881
116485
  };
115882
116486
  var COLD_TEMP = {
115883
- celsius: 0,
116487
+ temperature: 0,
115884
116488
  lastFetchedAt: 0
115885
116489
  };
115886
116490
  /**
@@ -115944,7 +116548,7 @@ var HmDiagnosticDevice = class extends HmChildDevice {
115944
116548
  if (stored === null) return;
115945
116549
  if (this.capName === "temperature-sensor") {
115946
116550
  this.runtimeState.setCapState("temperature-sensor", {
115947
- celsius: stored,
116551
+ temperature: stored,
115948
116552
  lastFetchedAt: now
115949
116553
  });
115950
116554
  return;