@camstack/types 1.2.434 → 1.2.436

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 (54) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/addon.js +1 -1
  3. package/dist/addon.mjs +1 -1
  4. package/dist/capabilities/addons.cap.d.ts +8 -0
  5. package/dist/capabilities/air-quality-sensor.cap.d.ts +8 -8
  6. package/dist/capabilities/ambient-light-sensor.cap.d.ts +4 -4
  7. package/dist/capabilities/battery.cap.d.ts +14 -14
  8. package/dist/capabilities/brightness.cap.d.ts +7 -7
  9. package/dist/capabilities/capability-definition.d.ts +3 -3
  10. package/dist/capabilities/color.cap.d.ts +6 -6
  11. package/dist/capabilities/device-history.cap.d.ts +2 -2
  12. package/dist/capabilities/dishwasher.cap.d.ts +11 -11
  13. package/dist/capabilities/fan-control.cap.d.ts +6 -6
  14. package/dist/capabilities/humidity-sensor.cap.d.ts +4 -4
  15. package/dist/capabilities/index.d.ts +1 -1
  16. package/dist/capabilities/lawn-mower-control.cap.d.ts +3 -3
  17. package/dist/capabilities/media-player.cap.d.ts +8 -8
  18. package/dist/capabilities/meter.cap.d.ts +1 -1
  19. package/dist/capabilities/network-link.cap.d.ts +13 -13
  20. package/dist/capabilities/notification-output.cap.d.ts +70 -0
  21. package/dist/capabilities/power-meter.cap.d.ts +22 -22
  22. package/dist/capabilities/presence.cap.d.ts +1 -15
  23. package/dist/capabilities/pressure-sensor.cap.d.ts +4 -4
  24. package/dist/capabilities/temperature-sensor.cap.d.ts +4 -4
  25. package/dist/capabilities/vacuum-control.cap.d.ts +3 -3
  26. package/dist/client.js +50 -2
  27. package/dist/client.mjs +50 -2
  28. package/dist/composition/composition-report.d.ts +1 -1
  29. package/dist/composition/examples.d.ts +1 -1
  30. package/dist/composition/helpers/appliance.d.ts +1 -1
  31. package/dist/composition/helpers/index.d.ts +1 -1
  32. package/dist/composition/helpers/source-pick.d.ts +7 -0
  33. package/dist/{composition-Bb8iwHEJ.mjs → composition-DwA0uVW5.mjs} +3 -2
  34. package/dist/{composition-CpAc0YfQ.js → composition-WNkEpwkF.js} +3 -2
  35. package/dist/device/base-device.d.ts +2 -2
  36. package/dist/device/device-runtime-state.d.ts +1 -1
  37. package/dist/device/device-state-handle.d.ts +1 -1
  38. package/dist/device/system-mirror.d.ts +1 -1
  39. package/dist/generated/addon-cap-facts.d.ts +1 -1
  40. package/dist/generated/customize-catalog.d.ts +15 -15
  41. package/dist/generated/history-catalog.d.ts +1 -1
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.js +331 -212
  44. package/dist/index.mjs +328 -213
  45. package/dist/interfaces/addon.d.ts +8 -0
  46. package/dist/interfaces/event-bus.d.ts +3 -3
  47. package/dist/node.js +1 -1
  48. package/dist/node.mjs +1 -1
  49. package/dist/notification/delivery-params.d.ts +15 -0
  50. package/dist/{sleep-DFaVPxfm.mjs → sleep-Crlmu_tO.mjs} +26 -30
  51. package/dist/{sleep-CO61AfwW.js → sleep-DHitF_e4.js} +26 -30
  52. package/dist/vendor-login-proxy/index.d.ts +1 -1
  53. package/dist/vendor-login-proxy/url-rewrite.d.ts +7 -0
  54. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sleep = require("./sleep-CO61AfwW.js");
2
+ const require_sleep = require("./sleep-DHitF_e4.js");
3
3
  const require_event_category = require("./event-category-E17zaHjN.js");
4
- const require_composition = require("./composition-CpAc0YfQ.js");
4
+ const require_composition = require("./composition-WNkEpwkF.js");
5
5
  const require_node_color = require("./node-color.js");
6
6
  const require_err_msg = require("./err-msg-U7lLUMNz.js");
7
7
  const require_enums = require("./enums.js");
@@ -14905,7 +14905,7 @@ var CompositionProblemCodeSchema = zod.z.enum([
14905
14905
  "member-constraint",
14906
14906
  "retention"
14907
14907
  ]);
14908
- /** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.celsius`. */
14908
+ /** One refusal, named (D391). `path` points into the composition, e.g. `features[0].fields.temperature`. */
14909
14909
  var CompositionProblemSchema = zod.z.object({
14910
14910
  code: CompositionProblemCodeSchema,
14911
14911
  path: zod.z.string(),
@@ -15574,12 +15574,13 @@ var CHANGED = {
15574
15574
  expr: "now"
15575
15575
  };
15576
15576
  function numeric(input) {
15577
+ const { alsoFrom, ...base } = input;
15577
15578
  return {
15578
- ...input,
15579
+ ...base,
15579
15580
  family: "numeric",
15580
15581
  deviceType: require_err_msg.DeviceType.Sensor,
15581
15582
  memberDeviceType: require_err_msg.DeviceType.Sensor,
15582
- memberDeviceTypes: [require_err_msg.DeviceType.Sensor],
15583
+ memberDeviceTypes: [require_err_msg.DeviceType.Sensor, ...alsoFrom?.deviceTypes ?? []],
15583
15584
  activeWhen: void 0,
15584
15585
  commandCaps: [],
15585
15586
  baseUnit: require_sleep.baseUnitOf(input.quantity),
@@ -15587,9 +15588,10 @@ function numeric(input) {
15587
15588
  accept: [{
15588
15589
  cap: input.outputCap,
15589
15590
  fieldPath: input.outputField
15590
- }]
15591
+ }, ...alsoFrom === void 0 ? [] : [alsoFrom.accept]]
15591
15592
  };
15592
15593
  }
15594
+ var CLIMATE_DEVICES = [require_err_msg.DeviceType.Thermostat, require_err_msg.DeviceType.Climate];
15593
15595
  function binary(input) {
15594
15596
  return {
15595
15597
  ...input,
@@ -15611,29 +15613,43 @@ var GROUP_TEMPLATES = [
15611
15613
  summary: "Mean, median, min, max or sum of temperatures. Offline and unknown members are left out, never read as 0 °C.",
15612
15614
  role: require_err_msg.DeviceRole.TemperatureSensor,
15613
15615
  outputCap: "temperature-sensor",
15614
- outputField: "celsius",
15616
+ outputField: "temperature",
15615
15617
  quantity: "temperature",
15616
15618
  defaultAggregate: "mean",
15617
15619
  empty: "null",
15618
- companions: [NOW$2]
15620
+ companions: [NOW$2],
15621
+ alsoFrom: {
15622
+ deviceTypes: CLIMATE_DEVICES,
15623
+ accept: {
15624
+ cap: "climate-control",
15625
+ fieldPath: "currentTemp"
15626
+ }
15627
+ }
15619
15628
  }),
15620
15629
  numeric({
15621
15630
  id: "humidity",
15622
15631
  summary: "Humidity in percent. Offline and unknown members are left out, never read as 0 %.",
15623
15632
  role: require_err_msg.DeviceRole.HumiditySensor,
15624
15633
  outputCap: "humidity-sensor",
15625
- outputField: "percent",
15634
+ outputField: "humidity",
15626
15635
  quantity: "humidity",
15627
15636
  defaultAggregate: "mean",
15628
15637
  empty: "null",
15629
- companions: [NOW$2]
15638
+ companions: [NOW$2],
15639
+ alsoFrom: {
15640
+ deviceTypes: CLIMATE_DEVICES,
15641
+ accept: {
15642
+ cap: "climate-control",
15643
+ fieldPath: "currentHumidity"
15644
+ }
15645
+ }
15630
15646
  }),
15631
15647
  numeric({
15632
15648
  id: "pressure",
15633
15649
  summary: "Pressure in hectopascals. Offline and unknown members are left out, never read as 0 hPa.",
15634
15650
  role: require_err_msg.DeviceRole.PressureSensor,
15635
15651
  outputCap: "pressure-sensor",
15636
- outputField: "hpa",
15652
+ outputField: "pressure",
15637
15653
  quantity: "pressure",
15638
15654
  defaultAggregate: "mean",
15639
15655
  empty: "null",
@@ -15644,7 +15660,7 @@ var GROUP_TEMPLATES = [
15644
15660
  summary: "Illuminance in lux. Offline and unknown members are left out, never read as 0 lx.",
15645
15661
  role: require_err_msg.DeviceRole.AmbientLightSensor,
15646
15662
  outputCap: "ambient-light-sensor",
15647
- outputField: "lux",
15663
+ outputField: "illuminance",
15648
15664
  quantity: "illuminance",
15649
15665
  defaultAggregate: "mean",
15650
15666
  empty: "null",
@@ -15655,7 +15671,7 @@ var GROUP_TEMPLATES = [
15655
15671
  summary: "Power in watts, summed by default. Nobody reporting omits the key rather than writing 0 W.",
15656
15672
  role: require_err_msg.DeviceRole.PowerSensor,
15657
15673
  outputCap: "power-meter",
15658
- outputField: "watts",
15674
+ outputField: "power",
15659
15675
  quantity: "power",
15660
15676
  defaultAggregate: "sum",
15661
15677
  empty: "omit",
@@ -15666,7 +15682,7 @@ var GROUP_TEMPLATES = [
15666
15682
  summary: "Energy in kilowatt-hours, summed by default. Nobody reporting omits the key rather than writing 0 kWh.",
15667
15683
  role: require_err_msg.DeviceRole.EnergySensor,
15668
15684
  outputCap: "power-meter",
15669
- outputField: "kwhTotal",
15685
+ outputField: "energy",
15670
15686
  quantity: "energy",
15671
15687
  defaultAggregate: "sum",
15672
15688
  empty: "omit",
@@ -15677,7 +15693,7 @@ var GROUP_TEMPLATES = [
15677
15693
  summary: "Battery charge in percent. Offline and unknown members are left out, never read as 0 %.",
15678
15694
  role: require_err_msg.DeviceRole.BatterySensor,
15679
15695
  outputCap: "battery",
15680
- outputField: "percentage",
15696
+ outputField: "level",
15681
15697
  quantity: "percentage",
15682
15698
  defaultAggregate: "mean",
15683
15699
  empty: "null",
@@ -16131,17 +16147,17 @@ async function runFanOut(calls, invoke) {
16131
16147
  //#region src/generated/history-catalog.ts
16132
16148
  /**
16133
16149
  * Cap history catalog, projected from every `*.cap.ts` `history` block.
16134
- * 42 caps with series (77 series), 33 caps answered `'none'`.
16150
+ * 41 caps with series (76 series), 34 caps answered `'none'`.
16135
16151
  * Field keys are `runtimeState` paths (`a.b` into fixed objects only).
16136
16152
  */
16137
16153
  var HISTORY_CATALOG = {
16138
16154
  "air-quality-sensor": {
16139
- "co2Ppm": {
16155
+ "co2": {
16140
16156
  kind: "gauge",
16141
16157
  unit: "ppm",
16142
16158
  deadband: 5
16143
16159
  },
16144
- "vocPpb": {
16160
+ "voc": {
16145
16161
  kind: "gauge",
16146
16162
  unit: "ppb",
16147
16163
  deadband: 5
@@ -16177,24 +16193,24 @@ var HISTORY_CATALOG = {
16177
16193
  "triggered"
16178
16194
  ]
16179
16195
  } },
16180
- "ambient-light-sensor": { "lux": {
16196
+ "ambient-light-sensor": { "illuminance": {
16181
16197
  kind: "gauge",
16182
16198
  unit: "lx",
16183
16199
  deadbandPct: 10,
16184
16200
  minIntervalMs: 6e4
16185
16201
  } },
16186
16202
  "battery": {
16187
- "percentage": {
16203
+ "level": {
16188
16204
  kind: "gauge",
16189
16205
  unit: "%"
16190
16206
  },
16191
- "volts": {
16207
+ "voltage": {
16192
16208
  kind: "gauge",
16193
16209
  unit: "V"
16194
16210
  }
16195
16211
  },
16196
16212
  "binary": { "on": { kind: "boolean" } },
16197
- "brightness": { "percentage": {
16213
+ "brightness": { "level": {
16198
16214
  kind: "gauge",
16199
16215
  unit: "%",
16200
16216
  minIntervalMs: 0
@@ -16236,7 +16252,7 @@ var HISTORY_CATALOG = {
16236
16252
  } },
16237
16253
  "device-status": { "online": { kind: "boolean" } },
16238
16254
  "dishwasher": {
16239
- "progressPercent": {
16255
+ "progress": {
16240
16256
  kind: "gauge",
16241
16257
  unit: "%",
16242
16258
  deadband: 2
@@ -16266,7 +16282,7 @@ var HISTORY_CATALOG = {
16266
16282
  "Aborting"
16267
16283
  ]
16268
16284
  },
16269
- "remainingSeconds": {
16285
+ "remaining": {
16270
16286
  kind: "gauge",
16271
16287
  unit: "s",
16272
16288
  minIntervalMs: 6e4
@@ -16279,7 +16295,7 @@ var HISTORY_CATALOG = {
16279
16295
  skipWhenSet: "timestamp"
16280
16296
  } },
16281
16297
  "fan-control": {
16282
- "percentage": {
16298
+ "speed": {
16283
16299
  kind: "gauge",
16284
16300
  unit: "%",
16285
16301
  minIntervalMs: 0
@@ -16301,7 +16317,7 @@ var HISTORY_CATALOG = {
16301
16317
  },
16302
16318
  "on": { kind: "boolean" }
16303
16319
  },
16304
- "humidity-sensor": { "percent": {
16320
+ "humidity-sensor": { "humidity": {
16305
16321
  kind: "gauge",
16306
16322
  unit: "%",
16307
16323
  deadband: .5
@@ -16339,13 +16355,13 @@ var HISTORY_CATALOG = {
16339
16355
  excludeDeviceTypes: [require_err_msg.DeviceType.Camera]
16340
16356
  } },
16341
16357
  "network-link": {
16342
- "signalPercent": {
16358
+ "signal": {
16343
16359
  kind: "gauge",
16344
16360
  unit: "%",
16345
16361
  deadband: 3,
16346
16362
  minIntervalMs: 6e4
16347
16363
  },
16348
- "rssiDbm": {
16364
+ "rssi": {
16349
16365
  kind: "gauge",
16350
16366
  unit: "dBm",
16351
16367
  deadband: 2,
@@ -16372,31 +16388,31 @@ var HISTORY_CATALOG = {
16372
16388
  }
16373
16389
  },
16374
16390
  "power-meter": {
16375
- "watts": {
16391
+ "power": {
16376
16392
  kind: "gauge",
16377
16393
  unit: "W",
16378
16394
  deadband: 1,
16379
16395
  minIntervalMs: 3e4
16380
16396
  },
16381
- "kwhTotal": {
16397
+ "energy": {
16382
16398
  kind: "counter",
16383
16399
  unit: "kWh",
16384
16400
  deadband: .01,
16385
16401
  minIntervalMs: 6e4
16386
16402
  },
16387
- "volts": {
16403
+ "voltage": {
16388
16404
  kind: "gauge",
16389
16405
  unit: "V",
16390
16406
  deadband: 1,
16391
16407
  minIntervalMs: 3e4
16392
16408
  },
16393
- "amps": {
16409
+ "current": {
16394
16410
  kind: "gauge",
16395
16411
  unit: "A",
16396
16412
  deadband: .05,
16397
16413
  minIntervalMs: 3e4
16398
16414
  },
16399
- "va": {
16415
+ "apparentPower": {
16400
16416
  kind: "gauge",
16401
16417
  unit: "VA",
16402
16418
  deadband: 1,
@@ -16409,12 +16425,7 @@ var HISTORY_CATALOG = {
16409
16425
  minIntervalMs: 6e4
16410
16426
  }
16411
16427
  },
16412
- "presence": { "batteryPercent": {
16413
- kind: "gauge",
16414
- unit: "%",
16415
- deadband: 1
16416
- } },
16417
- "pressure-sensor": { "hpa": {
16428
+ "pressure-sensor": { "pressure": {
16418
16429
  kind: "gauge",
16419
16430
  unit: "hPa",
16420
16431
  deadband: .1
@@ -16441,7 +16452,7 @@ var HISTORY_CATALOG = {
16441
16452
  },
16442
16453
  "switch": { "on": { kind: "boolean" } },
16443
16454
  "tamper": { "tampered": { kind: "boolean" } },
16444
- "temperature-sensor": { "celsius": {
16455
+ "temperature-sensor": { "temperature": {
16445
16456
  kind: "gauge",
16446
16457
  unit: "°C",
16447
16458
  deadband: .1
@@ -16549,6 +16560,7 @@ var HISTORY_NONE_CAPS = [
16549
16560
  "native-object-detection",
16550
16561
  "navigation",
16551
16562
  "notifier",
16563
+ "presence",
16552
16564
  "privacy-mask",
16553
16565
  "ptz-autotrack",
16554
16566
  "recording-onboard",
@@ -16686,10 +16698,10 @@ function derivativeDraft(spec, retention = require_composition.DEFAULT_HISTORY_R
16686
16698
  function integralDraft(spec, retention = require_composition.DEFAULT_HISTORY_RETENTION) {
16687
16699
  const problems = [...historyProblems(spec.source)];
16688
16700
  const kind = declaredSeriesKind(spec.source);
16689
- const watts = spec.source.cap === "power-meter" && spec.source.fieldPath === "watts";
16701
+ const isPower = spec.source.cap === "power-meter" && spec.source.fieldPath === "power";
16690
16702
  if (kind === "counter" || kind === "boolean" || kind === "enum") problems.push(problem("kind-mismatch", "helper.source", "an integral reads an instantaneous gauge, not a counter or a state"));
16691
- if (spec.output === "energy" && !watts) problems.push(problem("kind-mismatch", "helper.output", "energy is the integral of power-meter.watts; another reading uses the meter"));
16692
- if (spec.output === "meter" && watts) problems.push(problem("kind-mismatch", "helper.output", "power integrates to power-meter.kwhTotal, which energy dashboards already read"));
16703
+ if (spec.output === "energy" && !isPower) problems.push(problem("kind-mismatch", "helper.output", "energy is the integral of power-meter.power; another reading uses the meter"));
16704
+ if (spec.output === "meter" && isPower) problems.push(problem("kind-mismatch", "helper.output", "power integrates to power-meter.energy, which energy dashboards already read"));
16693
16705
  const tier = require_composition.planResetTier(spec.reset, retention);
16694
16706
  if (!tier.ok) problems.push(problem("retention", "helper.reset", tier.reason));
16695
16707
  const energy = spec.output === "energy";
@@ -16698,7 +16710,7 @@ function integralDraft(spec, retention = require_composition.DEFAULT_HISTORY_RET
16698
16710
  draft: draft({
16699
16711
  role: energy ? require_err_msg.DeviceRole.EnergySensor : require_err_msg.DeviceRole.NumericSensor,
16700
16712
  cap: energy ? "power-meter" : "meter",
16701
- field: energy ? "kwhTotal" : "value",
16713
+ field: energy ? "energy" : "value",
16702
16714
  empty: "offline",
16703
16715
  spec,
16704
16716
  member: spec.source
@@ -16957,9 +16969,9 @@ function expressionSource(expr, bindings = {}) {
16957
16969
  }
16958
16970
  function compileAppliance(spec) {
16959
16971
  const member = spec.member;
16960
- if (member.cap !== "power-meter" || member.fieldPath !== "watts") return {
16972
+ if (member.cap !== "power-meter" || member.fieldPath !== "power") return {
16961
16973
  ok: false,
16962
- problems: [problem("member-constraint", "helper.member", "an appliance helper reads power-meter.watts")]
16974
+ problems: [problem("member-constraint", "helper.member", "an appliance helper reads power-meter.power")]
16963
16975
  };
16964
16976
  const threshold = unsignedToken(spec.thresholdWatts);
16965
16977
  const start = unsignedToken(spec.startDwellMs);
@@ -17000,7 +17012,7 @@ function compileAppliance(spec) {
17000
17012
  kind: "fields",
17001
17013
  cap: "power-meter",
17002
17014
  fields: {
17003
- watts: read,
17015
+ power: read,
17004
17016
  lastFetchedAt: clock
17005
17017
  }
17006
17018
  }]
@@ -19226,8 +19238,8 @@ var DeviceHistoryProducerKindSchema = zod.z.enum([
19226
19238
  /**
19227
19239
  * A key computed at READ time from stored series of the same device, never
19228
19240
  * stored itself. Energy (kWh per bucket) comes from the power meter's
19229
- * `kwhTotal` counter when the device has one, else from integrating its
19230
- * `watts` gauge over time.
19241
+ * `energy` counter when the device has one, else from integrating its
19242
+ * `power` gauge over time.
19231
19243
  */
19232
19244
  var DEVICE_HISTORY_ENERGY_KEY = "derived:energy.kwh";
19233
19245
  var DeviceHistoryResolutionSchema = zod.z.enum([
@@ -46324,6 +46336,43 @@ var NotificationActionSchema = zod.z.object({
46324
46336
  */
46325
46337
  mode: zod.z.enum(["navigate", "background"]).optional()
46326
46338
  });
46339
+ /** A delivery parameter value: what a notifier declared it takes. */
46340
+ var DeliveryParamValueSchema = zod.z.union([
46341
+ zod.z.string(),
46342
+ zod.z.number(),
46343
+ zod.z.boolean()
46344
+ ]);
46345
+ /**
46346
+ * One extra delivery parameter a notifier KIND declares (D938). A rule that
46347
+ * addresses a target of that kind may set it; a kind that declares nothing is
46348
+ * never handed one. The admin UI derives its control from this descriptor —
46349
+ * no editor knows a service by name.
46350
+ *
46351
+ * Optional fields are `.optional()`, never `.default()` (a Zod default does not
46352
+ * run on the addon cap path).
46353
+ */
46354
+ var DeliveryParamSchema = zod.z.object({
46355
+ key: zod.z.string().min(1),
46356
+ label: zod.z.string(),
46357
+ /** i18n key of the label, resolved by the declaring addon's namespace. */
46358
+ labelKey: zod.z.string().optional(),
46359
+ type: zod.z.enum([
46360
+ "enum",
46361
+ "number",
46362
+ "boolean",
46363
+ "string"
46364
+ ]),
46365
+ /** `enum` only: the closed set of accepted values. */
46366
+ options: zod.z.array(zod.z.object({
46367
+ value: zod.z.string(),
46368
+ label: zod.z.string()
46369
+ })).optional(),
46370
+ /** `number` only. */
46371
+ min: zod.z.number().optional(),
46372
+ max: zod.z.number().optional(),
46373
+ /** What the notifier does when the rule sets nothing; shown as the placeholder. */
46374
+ default: DeliveryParamValueSchema.optional()
46375
+ });
46327
46376
  /**
46328
46377
  * The canonical notification. `body` is the only hard field (Apprise model).
46329
46378
  * `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
@@ -46346,7 +46395,13 @@ var NotificationSchema = zod.z.object({
46346
46395
  tag: zod.z.string().optional(),
46347
46396
  deviceId: zod.z.number().optional(),
46348
46397
  eventId: zod.z.string().optional(),
46349
- metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
46398
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
46399
+ /**
46400
+ * Values for the parameters the target's kind DECLARES in
46401
+ * {@link TargetKindSchema} `deliveryParams`. Already validated against the
46402
+ * declaration by the sender; a notifier reads only the keys it declared.
46403
+ */
46404
+ delivery: zod.z.record(zod.z.string(), DeliveryParamValueSchema).optional()
46350
46405
  });
46351
46406
  /** One declared native severity/priority level for a kind. */
46352
46407
  var TargetKindLevelSchema = zod.z.object({
@@ -46454,6 +46509,11 @@ var TargetKindSchema = zod.z.object({
46454
46509
  */
46455
46510
  destinationKeys: zod.z.array(zod.z.string()).optional(),
46456
46511
  supportsDiscovery: zod.z.boolean(),
46512
+ /**
46513
+ * Extra delivery parameters a rule may set for a target of this kind (D938).
46514
+ * Absent = none; the rule editor then offers nothing.
46515
+ */
46516
+ deliveryParams: zod.z.array(DeliveryParamSchema).optional(),
46457
46517
  caps: TargetKindCapsSchema
46458
46518
  });
46459
46519
  /**
@@ -63691,7 +63751,9 @@ var ManifestShapeSchema = zod.z.object({
63691
63751
  icon: zod.z.string().optional()
63692
63752
  }).optional(),
63693
63753
  protected: zod.z.boolean().optional(),
63694
- removable: zod.z.boolean().optional()
63754
+ removable: zod.z.boolean().optional(),
63755
+ /** Declared Integrations-page block (mirror of `AddonDeclaration.integrationSection`). */
63756
+ integrationSection: zod.z.enum(["system", "providers"]).optional()
63695
63757
  });
63696
63758
  var AddonProcessSchema = zod.z.object({
63697
63759
  pid: zod.z.number().optional(),
@@ -64266,9 +64328,9 @@ var addonsCapability = {
64266
64328
  */
64267
64329
  var AirQualitySensorStatusSchema = zod.z.object({
64268
64330
  /** Carbon dioxide concentration in ppm. */
64269
- co2Ppm: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-volume")),
64331
+ co2: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-volume")),
64270
64332
  /** Total volatile organic compounds in ppb. */
64271
- vocPpb: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-ppb")),
64333
+ voc: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-ppb")),
64272
64334
  /** Particulate matter ≤ 2.5 μm in µg/m³. */
64273
64335
  pm25: zod.z.number().min(0).optional().meta(require_sleep.readingMeta("concentration-mass")),
64274
64336
  /** Particulate matter ≤ 10 μm in µg/m³. */
@@ -64301,12 +64363,12 @@ var airQualitySensorCapability = {
64301
64363
  * History (D850): recorded series.
64302
64364
  */
64303
64365
  history: { fields: {
64304
- co2Ppm: {
64366
+ co2: {
64305
64367
  kind: "gauge",
64306
64368
  unit: "ppm",
64307
64369
  deadband: 5
64308
64370
  },
64309
- vocPpb: {
64371
+ voc: {
64310
64372
  kind: "gauge",
64311
64373
  unit: "ppb",
64312
64374
  deadband: 5
@@ -64339,7 +64401,7 @@ var airQualitySensorCapability = {
64339
64401
  */
64340
64402
  var AmbientLightSensorStatusSchema = zod.z.object({
64341
64403
  /** Current illuminance in lux (lx). `null` when the sample was refused (D393). */
64342
- lux: zod.z.number().min(0).nullable().meta(require_sleep.readingMeta("illuminance", {
64404
+ illuminance: zod.z.number().min(0).nullable().meta(require_sleep.readingMeta("illuminance", {
64343
64405
  precision: 0,
64344
64406
  label: "Illuminance"
64345
64407
  })),
@@ -64368,7 +64430,7 @@ var ambientLightSensorCapability = {
64368
64430
  /**
64369
64431
  * History (D850): recorded series. Wide range, so a RELATIVE deadband (10 %).
64370
64432
  */
64371
- history: { fields: { lux: {
64433
+ history: { fields: { illuminance: {
64372
64434
  kind: "gauge",
64373
64435
  unit: "lx",
64374
64436
  deadbandPct: 10,
@@ -64764,7 +64826,7 @@ var BatteryStatusSchema = zod.z.object({
64764
64826
  * Consumers must SKIP a null rather than coerce it — `battery-band` already
64765
64827
  * declines to band a non-finite reading, which is the correct shape.
64766
64828
  */
64767
- percentage: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage", { label: "Charge" })),
64829
+ level: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage", { label: "Charge" })),
64768
64830
  /**
64769
64831
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
64770
64832
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -64774,7 +64836,7 @@ var BatteryStatusSchema = zod.z.object({
64774
64836
  * `'unknown'` is the absence of an answer: the provider has not read the
64775
64837
  * power fields yet, or the firmware reported neither. Before it existed,
64776
64838
  * two unreadable fields produced `'none'`, and a camera nobody had reached
64777
- * was drawn "on battery alone" — the same D315 defect `percentage` closed
64839
+ * was drawn "on battery alone" — the same D315 defect `level` closed
64778
64840
  * by going nullable. Consumers SKIP it (no charger state published, no
64779
64841
  * glyph, no HomeKit ChargingState) rather than coerce it either way.
64780
64842
  */
@@ -64798,7 +64860,7 @@ var BatteryStatusSchema = zod.z.object({
64798
64860
  * that only report charge. A second reading on this cap, not a second
64799
64861
  * `numeric-sensor` on the same device.
64800
64862
  */
64801
- volts: zod.z.number().nullable().optional().meta(require_sleep.readingMeta("voltage", { label: "Voltage" })),
64863
+ voltage: zod.z.number().nullable().optional().meta(require_sleep.readingMeta("voltage", { label: "Voltage" })),
64802
64864
  /**
64803
64865
  * Ms epoch of the last time the device PROVED it was reachable — a
64804
64866
  * completed firmware round-trip, an observed wake, or an inbound push
@@ -64832,7 +64894,7 @@ var BatteryStatusSchema = zod.z.object({
64832
64894
  /**
64833
64895
  * True when the source is a BINARY low-battery indicator (HA
64834
64896
  * `binary_sensor` device_class=battery / `LOW_BAT`) that has no real
64835
- * charge level — `percentage` is then a coarse stand-in (100 = normal,
64897
+ * charge level — `level` is then a coarse stand-in (100 = normal,
64836
64898
  * sub-threshold = low). UI MUST render "Normal"/"Low" instead of a
64837
64899
  * misleading exact percentage. Absent/false → genuine 0–100 % reading.
64838
64900
  */
@@ -64852,15 +64914,15 @@ var BATTERY_DEVICE_TYPES = [
64852
64914
  var batteryCustomize = {
64853
64915
  version: 1,
64854
64916
  targets: [{
64855
- id: "percentage",
64917
+ id: "level",
64856
64918
  cardinality: "scalar",
64857
64919
  vocabulary: {
64858
64920
  cap: "battery",
64859
- stateField: "percentage"
64921
+ stateField: "level"
64860
64922
  },
64861
64923
  deviceTypes: BATTERY_DEVICE_TYPES,
64862
64924
  apply: "add",
64863
- path: "percentage",
64925
+ path: "level",
64864
64926
  sources: [{
64865
64927
  kind: "field",
64866
64928
  valueKinds: ["number", "string"],
@@ -64954,7 +65016,7 @@ onStatusChanged: { data: zod.z.object({
64954
65016
  schema: BatteryStatusSchema,
64955
65017
  kind: "push",
64956
65018
  empty: {
64957
- percentage: null,
65019
+ level: null,
64958
65020
  charging: "unknown",
64959
65021
  sleeping: false,
64960
65022
  lastUpdated: 0
@@ -64981,11 +65043,11 @@ onStatusChanged: { data: zod.z.object({
64981
65043
  * History (D850): recorded series. The generic capture replaces the `battery` series of `pipeline-analytics:stats-5m`.
64982
65044
  */
64983
65045
  history: { fields: {
64984
- percentage: {
65046
+ level: {
64985
65047
  kind: "gauge",
64986
65048
  unit: "%"
64987
65049
  },
64988
- volts: {
65050
+ voltage: {
64989
65051
  kind: "gauge",
64990
65052
  unit: "V"
64991
65053
  }
@@ -65049,14 +65111,14 @@ var binaryCapability = {
65049
65111
  * controls to this single-method surface.
65050
65112
  *
65051
65113
  * The cap is intentionally minimal: a single `setBrightness({deviceId,
65052
- * percentage})` mutation plus the auto-injected `getStatus`. Drivers
65114
+ * level})` mutation plus the auto-injected `getStatus`. Drivers
65053
65115
  * that expose richer controls (color temperature, scenes, schedules)
65054
65116
  * should surface those via the device's `getSettingsUISchema()`
65055
65117
  * instead of bloating this cap.
65056
65118
  */
65057
65119
  var BrightnessStatusSchema = zod.z.object({
65058
65120
  /** Current level as 0..100 inclusive. Firmware-reported. */
65059
- percentage: zod.z.number().min(0).max(100).meta(require_sleep.readingMeta("percentage")),
65121
+ level: zod.z.number().min(0).max(100).meta(require_sleep.readingMeta("percentage")),
65060
65122
  /** Ms epoch of the last operator-driven change. Useful for UI freshness. */
65061
65123
  lastChangedAt: zod.z.number()
65062
65124
  });
@@ -65068,7 +65130,7 @@ var brightnessCapability = {
65068
65130
  deviceTypes: [require_err_msg.DeviceType.Light],
65069
65131
  methods: { setBrightness: require_sleep.method(zod.z.object({
65070
65132
  deviceId: zod.z.number().int().nonnegative(),
65071
- percentage: zod.z.number().min(0).max(100)
65133
+ level: zod.z.number().min(0).max(100)
65072
65134
  }), zod.z.void(), {
65073
65135
  kind: "mutation",
65074
65136
  auth: "protected"
@@ -65081,7 +65143,7 @@ var brightnessCapability = {
65081
65143
  */
65082
65144
  onBrightnessChanged: { data: zod.z.object({
65083
65145
  deviceId: zod.z.number(),
65084
- percentage: zod.z.number().min(0).max(100),
65146
+ level: zod.z.number().min(0).max(100),
65085
65147
  lastChangedAt: zod.z.number()
65086
65148
  }) } },
65087
65149
  status: {
@@ -65104,7 +65166,7 @@ onBrightnessChanged: { data: zod.z.object({
65104
65166
  /**
65105
65167
  * History (D850): recorded series. Actuator tier: level keeps every change.
65106
65168
  */
65107
- history: { fields: { percentage: {
65169
+ history: { fields: { level: {
65108
65170
  kind: "gauge",
65109
65171
  unit: "%",
65110
65172
  minIntervalMs: 0
@@ -65848,11 +65910,11 @@ var ColorInputSchema = zod.z.discriminatedUnion("mode", [
65848
65910
  }),
65849
65911
  zod.z.object({
65850
65912
  mode: zod.z.literal("mired"),
65851
- mireds: zod.z.number().int().min(50).max(1e3)
65913
+ colorTemperature: zod.z.number().int().min(50).max(1e3)
65852
65914
  })
65853
65915
  ]);
65854
65916
  var ColorStatusSchema = zod.z.object({
65855
- /** Active color mode — which of `rgb` / `hsv` / `mireds` reflects
65917
+ /** Active color mode — which of `rgb` / `hsv` / `colorTemperature` reflects
65856
65918
  * the bulb's current state. */
65857
65919
  mode: zod.z.enum([
65858
65920
  "rgb",
@@ -65864,7 +65926,7 @@ var ColorStatusSchema = zod.z.object({
65864
65926
  /** Populated when `mode === 'hsv'`. */
65865
65927
  hsv: HsvTripletSchema.optional(),
65866
65928
  /** Populated when `mode === 'mired'`. */
65867
- mireds: zod.z.number().int().optional().meta(require_sleep.readingMeta("colour-temperature")),
65929
+ colorTemperature: zod.z.number().int().optional().meta(require_sleep.readingMeta("colour-temperature")),
65868
65930
  /** Ms epoch of the last operator-driven change. */
65869
65931
  lastChangedAt: zod.z.number()
65870
65932
  });
@@ -65900,7 +65962,7 @@ onColorChanged: { data: zod.z.object({
65900
65962
  ]),
65901
65963
  rgb: RgbTripletSchema.optional(),
65902
65964
  hsv: HsvTripletSchema.optional(),
65903
- mireds: zod.z.number().int().optional(),
65965
+ colorTemperature: zod.z.number().int().optional(),
65904
65966
  lastChangedAt: zod.z.number()
65905
65967
  }) } },
65906
65968
  status: {
@@ -66933,11 +66995,11 @@ var DishwasherStatusSchema = zod.z.object({
66933
66995
  /** Feature keys of the programs the appliance currently offers — drives the UI selector. */
66934
66996
  availablePrograms: zod.z.array(zod.z.string()),
66935
66997
  /** Seconds remaining on the active cycle, or null when not running / not known. */
66936
- remainingSeconds: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration")),
66998
+ remaining: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration")),
66937
66999
  /** Seconds the delayed start is set to (time until the cycle starts), or null. */
66938
- delayedStartSeconds: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration")),
67000
+ delayedStart: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration")),
66939
67001
  /** Cycle completion 0..100, or null when not applicable. */
66940
- progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
67002
+ progress: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
66941
67003
  /** True when the door is reported open; null when the door state is not known. */
66942
67004
  doorOpen: zod.z.boolean().nullable(),
66943
67005
  /** True when the door is latched (locked) during a cycle; null when not reported. */
@@ -67156,14 +67218,14 @@ var dishwasherCapability = {
67156
67218
  runtimeState: DishwasherStatusSchema,
67157
67219
  durability: "session",
67158
67220
  history: { fields: {
67159
- progressPercent: {
67221
+ progress: {
67160
67222
  kind: "gauge",
67161
67223
  unit: "%",
67162
67224
  deadband: 2
67163
67225
  },
67164
67226
  state: { kind: "enum" },
67165
67227
  operationState: { kind: "enum" },
67166
- remainingSeconds: {
67228
+ remaining: {
67167
67229
  kind: "gauge",
67168
67230
  unit: "s",
67169
67231
  minIntervalMs: 6e4
@@ -67816,7 +67878,7 @@ var FanDirectionSchema = zod.z.enum(["forward", "reverse"]);
67816
67878
  var FanControlStatusSchema = zod.z.object({
67817
67879
  /** Active speed as 0..100 inclusive. Null when the device has no
67818
67880
  * speed surface (single-speed fan). */
67819
- percentage: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
67881
+ speed: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
67820
67882
  /** Speed granularity the device accepts (HA `percentage_step`, e.g. 25 for
67821
67883
  * a 4-speed fan). Absent when unknown — the UI then falls back to step 1. */
67822
67884
  percentageStep: zod.z.number().positive().optional().meta(require_sleep.readingMeta("percentage")),
@@ -67843,7 +67905,7 @@ var fanControlCapability = {
67843
67905
  methods: {
67844
67906
  setPercentage: require_sleep.method(zod.z.object({
67845
67907
  deviceId: zod.z.number().int().nonnegative(),
67846
- percentage: zod.z.number().min(0).max(100)
67908
+ speed: zod.z.number().min(0).max(100)
67847
67909
  }), zod.z.void(), {
67848
67910
  kind: "mutation",
67849
67911
  auth: "protected"
@@ -67876,7 +67938,7 @@ var fanControlCapability = {
67876
67938
  },
67877
67939
  /**
67878
67940
  * Runtime-state slice — mirrored by the kernel. UI fan speed
67879
- * sliders read `percentage` for live updates.
67941
+ * sliders read `speed` for live updates.
67880
67942
  */
67881
67943
  runtimeState: FanControlStatusSchema,
67882
67944
  /**
@@ -67890,7 +67952,7 @@ var fanControlCapability = {
67890
67952
  * History (D850): recorded series. Actuator tier: speed keeps every change.
67891
67953
  */
67892
67954
  history: { fields: {
67893
- percentage: {
67955
+ speed: {
67894
67956
  kind: "gauge",
67895
67957
  unit: "%",
67896
67958
  minIntervalMs: 0
@@ -68360,7 +68422,7 @@ var humidifierCapability = {
68360
68422
  */
68361
68423
  var HumiditySensorStatusSchema = zod.z.object({
68362
68424
  /** Current relative humidity, 0..100. `null` when the sample was refused (D393). */
68363
- percent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity", {
68425
+ humidity: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("humidity", {
68364
68426
  precision: 0,
68365
68427
  label: "Humidity"
68366
68428
  })),
@@ -68389,7 +68451,7 @@ var humiditySensorCapability = {
68389
68451
  /**
68390
68452
  * History (D850): recorded series.
68391
68453
  */
68392
- history: { fields: { percent: {
68454
+ history: { fields: { humidity: {
68393
68455
  kind: "gauge",
68394
68456
  unit: "%",
68395
68457
  deadband: .5
@@ -69057,7 +69119,7 @@ var LawnMowerControlStatusSchema = zod.z.object({
69057
69119
  batteryLevel: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
69058
69120
  /** 0..100 mowing-completion percentage of the current task, or null when no
69059
69121
  * task is active / progress is unavailable. */
69060
- progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
69122
+ progress: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
69061
69123
  /** Current device/event code (dynamic — mostly status, sometimes an error),
69062
69124
  * or null when unknown. */
69063
69125
  currentCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
@@ -69754,7 +69816,7 @@ var lockControlCapability = {
69754
69816
  //#endregion
69755
69817
  //#region src/capabilities/meter.cap.ts
69756
69818
  /**
69757
- * A monotonic total between resets (D944). Energy uses `power-meter.kwhTotal`
69819
+ * A monotonic total between resets (D944). Energy uses `power-meter.energy`
69758
69820
  * so dashboards keep one series; every other instantaneous reading lands here.
69759
69821
  * `value` is the time integral in the source quantity's accumulated base
69760
69822
  * (base-unit seconds, or kWh on the power meter). `null` is a gap, never zero.
@@ -69850,10 +69912,10 @@ var MediaPlayerStatusSchema = zod.z.object({
69850
69912
  currentMedia: MediaInfoSchema.nullable(),
69851
69913
  /** Current playback position in ms. Null when not seekable or
69852
69914
  * nothing is playing. Pair with `DeviceFeature.MediaPlayerSeek`. */
69853
- positionMs: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration-ms")),
69915
+ position: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration-ms")),
69854
69916
  /** Total duration of the current media in ms. Null when unknown
69855
69917
  * (live stream) or nothing is playing. */
69856
- durationMs: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration-ms")),
69918
+ duration: zod.z.number().int().nonnegative().nullable().meta(require_sleep.readingMeta("duration-ms")),
69857
69919
  /** Shuffle toggle. Null when no shuffle surface.
69858
69920
  * Pair with `DeviceFeature.MediaPlayerShuffle`. */
69859
69921
  shuffle: zod.z.boolean().nullable(),
@@ -69892,7 +69954,7 @@ var mediaPlayerCapability = {
69892
69954
  }),
69893
69955
  seek: require_sleep.method(zod.z.object({
69894
69956
  deviceId: zod.z.number().int().nonnegative(),
69895
- positionMs: zod.z.number().int().nonnegative()
69957
+ position: zod.z.number().int().nonnegative()
69896
69958
  }), zod.z.void(), {
69897
69959
  kind: "mutation",
69898
69960
  auth: "protected"
@@ -69964,7 +70026,7 @@ var mediaPlayerCapability = {
69964
70026
  /**
69965
70027
  * History (D850): volume (a level an operator or an automation sets; the
69966
70028
  * default 10 s floor folds a slider drag into its end value) and mute.
69967
- * `positionMs` is not recorded: it moves continuously while playing.
70029
+ * `position` is not recorded: it moves continuously while playing.
69968
70030
  */
69969
70031
  history: { fields: {
69970
70032
  volumeLevel: {
@@ -71189,9 +71251,9 @@ var NetworkLinkStatusSchema = zod.z.object({
71189
71251
  * one whose reading has not landed must not be drawn at 0 %. Consumers
71190
71252
  * SKIP a null rather than coerce it.
71191
71253
  */
71192
- signalPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
71254
+ signal: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
71193
71255
  /** Raw received signal strength in dBm, when the firmware reports one. */
71194
- rssiDbm: zod.z.number().optional().meta(require_sleep.readingMeta("signal-level")),
71256
+ rssi: zod.z.number().optional().meta(require_sleep.readingMeta("signal-level")),
71195
71257
  /** Network name of a wireless link, when the firmware reports it. */
71196
71258
  ssid: zod.z.string().optional(),
71197
71259
  /** Ms epoch of the last observation. Lets consumers reason about freshness. */
@@ -71200,7 +71262,7 @@ var NetworkLinkStatusSchema = zod.z.object({
71200
71262
  /** The slice a provider seeds before its first read: nothing is known yet. */
71201
71263
  var NETWORK_LINK_UNKNOWN = {
71202
71264
  type: "unknown",
71203
- signalPercent: null,
71265
+ signal: null,
71204
71266
  lastUpdated: 0
71205
71267
  };
71206
71268
  /**
@@ -71217,9 +71279,9 @@ function signalPercentFromBars(bars, maxBars) {
71217
71279
  * below is 0 %, -50 dBm and above is 100 %, linear between. Non-finite or
71218
71280
  * positive input is not an RSSI: `null`.
71219
71281
  */
71220
- function signalPercentFromRssi(rssiDbm) {
71221
- if (rssiDbm === void 0 || !Number.isFinite(rssiDbm) || rssiDbm > 0) return null;
71222
- return Math.round((Math.min(-50, Math.max(-100, rssiDbm)) + 100) * 2);
71282
+ function signalPercentFromRssi(rssi) {
71283
+ if (rssi === void 0 || !Number.isFinite(rssi) || rssi > 0) return null;
71284
+ return Math.round((Math.min(-50, Math.max(-100, rssi)) + 100) * 2);
71223
71285
  }
71224
71286
  var networkLinkCapability = {
71225
71287
  name: "network-link",
@@ -71270,13 +71332,13 @@ onStatusChanged: { data: zod.z.object({
71270
71332
  * History (D850): recorded series.
71271
71333
  */
71272
71334
  history: { fields: {
71273
- signalPercent: {
71335
+ signal: {
71274
71336
  kind: "gauge",
71275
71337
  unit: "%",
71276
71338
  deadband: 3,
71277
71339
  minIntervalMs: 6e4
71278
71340
  },
71279
- rssiDbm: {
71341
+ rssi: {
71280
71342
  kind: "gauge",
71281
71343
  unit: "dBm",
71282
71344
  deadband: 2,
@@ -73639,16 +73701,16 @@ var platformProbeCapability = {
73639
73701
  * in real-world devices.
73640
73702
  */
73641
73703
  var PowerMeterStatusSchema = zod.z.object({
73642
- /** Instantaneous power draw in watts. */
73643
- watts: zod.z.number().optional().meta(require_sleep.readingMeta("power", { label: "Power" })),
73704
+ /** Instantaneous power draw (watts). */
73705
+ power: zod.z.number().optional().meta(require_sleep.readingMeta("power", { label: "Power" })),
73644
73706
  /** Cumulative energy in kilowatt-hours since the meter was reset. */
73645
- kwhTotal: zod.z.number().optional().meta(require_sleep.readingMeta("energy", { label: "Energy" })),
73646
- /** Voltage in volts. */
73647
- volts: zod.z.number().optional().meta(require_sleep.readingMeta("voltage", { label: "Voltage" })),
73707
+ energy: zod.z.number().optional().meta(require_sleep.readingMeta("energy", { label: "Energy" })),
73708
+ /** Voltage (volts). */
73709
+ voltage: zod.z.number().optional().meta(require_sleep.readingMeta("voltage", { label: "Voltage" })),
73648
73710
  /** Current in amperes. */
73649
- amps: zod.z.number().optional().meta(require_sleep.readingMeta("current", { label: "Current" })),
73711
+ current: zod.z.number().optional().meta(require_sleep.readingMeta("current", { label: "Current" })),
73650
73712
  /** Apparent power in volt-amperes. */
73651
- va: zod.z.number().optional().meta(require_sleep.readingMeta("apparent-power")),
73713
+ apparentPower: zod.z.number().optional().meta(require_sleep.readingMeta("apparent-power")),
73652
73714
  /** Power factor (0..1) if reported. */
73653
73715
  powerFactor: zod.z.number().min(0).max(1).optional().meta(require_sleep.readingMeta("ratio")),
73654
73716
  /** Ms epoch when the slice was last updated. */
@@ -73706,14 +73768,14 @@ function powerTarget(id, unit) {
73706
73768
  advancedExpression: true
73707
73769
  };
73708
73770
  }
73709
- /** "Power and energy" extension: watts, energy, voltage and current from other devices (D951). */
73771
+ /** "Power and energy" extension: power, energy, voltage and current from other devices (D951). */
73710
73772
  var powerMeterCustomize = {
73711
73773
  version: 1,
73712
73774
  targets: [
73713
- powerTarget("watts", "W"),
73714
- powerTarget("kwhTotal", "kWh"),
73715
- powerTarget("volts", "V"),
73716
- powerTarget("amps", "A")
73775
+ powerTarget("power", "W"),
73776
+ powerTarget("energy", "kWh"),
73777
+ powerTarget("voltage", "V"),
73778
+ powerTarget("current", "A")
73717
73779
  ]
73718
73780
  };
73719
73781
  var powerMeterCapability = {
@@ -73729,41 +73791,41 @@ var powerMeterCapability = {
73729
73791
  },
73730
73792
  runtimeState: PowerMeterStatusSchema,
73731
73793
  /**
73732
- * Runtime-state durability: **restored** — as `numeric-sensor`; `kwhTotal` is an accumulator whose restored value is the baseline.
73794
+ * Runtime-state durability: **restored** — as `numeric-sensor`; `energy` is an accumulator whose restored value is the baseline.
73733
73795
  *
73734
73796
  * See `RuntimeStateDurability`. Enforced by
73735
73797
  * `scripts/check-runtime-state-durability.ts`.
73736
73798
  */
73737
73799
  durability: "restored",
73738
73800
  /**
73739
- * History (D850): recorded series. Gauges are floored at 30 s; `kwhTotal` is the one monotonic meter (counter).
73801
+ * History (D850): recorded series. Gauges are floored at 30 s; `energy` is the one monotonic meter (counter).
73740
73802
  */
73741
73803
  history: { fields: {
73742
- watts: {
73804
+ power: {
73743
73805
  kind: "gauge",
73744
73806
  unit: "W",
73745
73807
  deadband: 1,
73746
73808
  minIntervalMs: 3e4
73747
73809
  },
73748
- kwhTotal: {
73810
+ energy: {
73749
73811
  kind: "counter",
73750
73812
  unit: "kWh",
73751
73813
  deadband: .01,
73752
73814
  minIntervalMs: 6e4
73753
73815
  },
73754
- volts: {
73816
+ voltage: {
73755
73817
  kind: "gauge",
73756
73818
  unit: "V",
73757
73819
  deadband: 1,
73758
73820
  minIntervalMs: 3e4
73759
73821
  },
73760
- amps: {
73822
+ current: {
73761
73823
  kind: "gauge",
73762
73824
  unit: "A",
73763
73825
  deadband: .05,
73764
73826
  minIntervalMs: 3e4
73765
73827
  },
73766
- va: {
73828
+ apparentPower: {
73767
73829
  kind: "gauge",
73768
73830
  unit: "VA",
73769
73831
  deadband: 1,
@@ -73815,9 +73877,6 @@ var PresenceStatusSchema = zod.z.object({
73815
73877
  location: zod.z.string().nullable(),
73816
73878
  /** GPS coordinates when available. Null otherwise. */
73817
73879
  gps: GpsLocationSchema.nullable(),
73818
- /** Optional battery level of the tracking device (0..100). Null
73819
- * when not reported. */
73820
- batteryPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
73821
73880
  /** Ms epoch when the slice was last updated. */
73822
73881
  lastChangedAt: zod.z.number()
73823
73882
  });
@@ -73846,14 +73905,7 @@ var presenceCapability = {
73846
73905
  * `scripts/check-runtime-state-durability.ts`.
73847
73906
  */
73848
73907
  durability: "restored",
73849
- /**
73850
- * History (D850): recorded series.
73851
- */
73852
- history: { fields: { batteryPercent: {
73853
- kind: "gauge",
73854
- unit: "%",
73855
- deadband: 1
73856
- } } },
73908
+ history: "none",
73857
73909
  /** Clock fields: written, but excluded from the compare that decides
73858
73910
  * whether persisting is worth a SQLite commit. */
73859
73911
  volatileStateFields: ["lastChangedAt"]
@@ -73870,7 +73922,7 @@ var presenceCapability = {
73870
73922
  */
73871
73923
  var PressureSensorStatusSchema = zod.z.object({
73872
73924
  /** Current pressure in hPa. `null` when the sample was refused (D393). */
73873
- hpa: zod.z.number().nullable().meta(require_sleep.readingMeta("pressure", { precision: 0 })),
73925
+ pressure: zod.z.number().nullable().meta(require_sleep.readingMeta("pressure", { precision: 0 })),
73874
73926
  /** Ms epoch when the slice was last updated. */
73875
73927
  lastFetchedAt: zod.z.number()
73876
73928
  });
@@ -73896,7 +73948,7 @@ var pressureSensorCapability = {
73896
73948
  /**
73897
73949
  * History (D850): recorded series.
73898
73950
  */
73899
- history: { fields: { hpa: {
73951
+ history: { fields: { pressure: {
73900
73952
  kind: "gauge",
73901
73953
  unit: "hPa",
73902
73954
  deadband: .1
@@ -79123,7 +79175,7 @@ var tamperCapability = {
79123
79175
  */
79124
79176
  var TemperatureSensorStatusSchema = zod.z.object({
79125
79177
  /** Current temperature in Celsius. `null` when the sample was refused (D393). */
79126
- celsius: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature", {
79178
+ temperature: zod.z.number().nullable().meta(require_sleep.readingMeta("temperature", {
79127
79179
  precision: 1,
79128
79180
  label: "Temperature"
79129
79181
  })),
@@ -79152,7 +79204,7 @@ var temperatureSensorCapability = {
79152
79204
  /**
79153
79205
  * History (D850): recorded series.
79154
79206
  */
79155
- history: { fields: { celsius: {
79207
+ history: { fields: { temperature: {
79156
79208
  kind: "gauge",
79157
79209
  unit: "°C",
79158
79210
  deadband: .1
@@ -79520,7 +79572,7 @@ var VacuumControlStatusSchema = zod.z.object({
79520
79572
  /** Speed tokens the hardware accepts — drives the UI selector. */
79521
79573
  availableFanSpeeds: zod.z.array(zod.z.string()),
79522
79574
  /** 0..100 cleaning-completion percentage of the current task, or null. */
79523
- progressPercent: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
79575
+ progress: zod.z.number().min(0).max(100).nullable().meta(require_sleep.readingMeta("percentage")),
79524
79576
  /** Current error code (0 / null = no error). */
79525
79577
  errorCode: zod.z.number().nullable().meta(require_sleep.readingMeta("none")),
79526
79578
  /** Human label for {@link errorCode}, or null when none / undecodable. */
@@ -81411,6 +81463,7 @@ function evaluateAggregate(input) {
81411
81463
  function sourcePickForTemplate(template) {
81412
81464
  const valueKind = template.family === "numeric" ? "number" : template.activeWhen === void 0 ? "boolean" : "state";
81413
81465
  return {
81466
+ fieldChoice: template.family === "numeric" ? "first-match" : "operator",
81414
81467
  purpose: "member",
81415
81468
  multiple: true,
81416
81469
  max: 64,
@@ -81430,6 +81483,7 @@ function sourcePickForTemplate(template) {
81430
81483
  /** A statistic or integral reads one field that declares history. */
81431
81484
  function sourcePickForHistory(kind) {
81432
81485
  return {
81486
+ fieldChoice: "operator",
81433
81487
  purpose: "historised",
81434
81488
  multiple: false,
81435
81489
  max: 1,
@@ -81469,6 +81523,7 @@ function sourcePickForMath(kind) {
81469
81523
  const multiple = kind === "sum" || kind === "expression";
81470
81524
  const max = kind === "difference" || kind === "ratio" ? 2 : multiple ? 64 : 1;
81471
81525
  return {
81526
+ fieldChoice: "operator",
81472
81527
  purpose: "reading",
81473
81528
  multiple: multiple || max > 1,
81474
81529
  max,
@@ -82170,7 +82225,7 @@ function named(prefix, sources, cap, fieldPath) {
82170
82225
  return Object.fromEntries(sources.map((s, i) => [`${prefix}${i + 1}`, from(s, cap, fieldPath)]));
82171
82226
  }
82172
82227
  function roomCompositionExample(input) {
82173
- const t = named("t", input.temperatureSources, "temperature-sensor", "celsius");
82228
+ const t = named("t", input.temperatureSources, "temperature-sensor", "temperature");
82174
82229
  const f = named("f", input.temperatureSources, "temperature-sensor", "lastFetchedAt");
82175
82230
  const d = named("d", input.motionSources, "motion", "detected");
82176
82231
  const m = named("m", input.motionSources, "motion", "lastDetectedAt");
@@ -82185,7 +82240,7 @@ function roomCompositionExample(input) {
82185
82240
  kind: "fields",
82186
82241
  cap: "temperature-sensor",
82187
82242
  fields: {
82188
- celsius: {
82243
+ temperature: {
82189
82244
  kind: "expression",
82190
82245
  expr: `round(avg(${Object.keys(t).join(", ")}), 1)`,
82191
82246
  bindings: t
@@ -82231,7 +82286,7 @@ function roomCompositionExample(input) {
82231
82286
  * an `enum-sensor` whose `value` is the raw STRING state — `number(d)` reads it,
82232
82287
  * and anything that is not a number is `null`, never 0 (D393). The battery
82233
82288
  * status sensor is an `enum-sensor` too (`unavailable` keeps its cold `''`, so
82234
- * `percentage` is `null`). `charging` maps `battery_charging` off to
82289
+ * `level` is `null`). `charging` maps `battery_charging` off to
82235
82290
  * `'unknown'`, never `'none'`: off does not prove "on battery alone" (the
82236
82291
  * operator confirms the real semantics live).
82237
82292
  */
@@ -82300,7 +82355,7 @@ function feederCustomizationExample(sources) {
82300
82355
  kind: "fields",
82301
82356
  cap: "battery",
82302
82357
  fields: {
82303
- percentage: {
82358
+ level: {
82304
82359
  kind: "expression",
82305
82360
  expr: "s == \"low\" ? 15 : (s == \"normal\" ? 100 : null)",
82306
82361
  bindings: { s: from(sources.batteryStatus, "enum-sensor", "value") }
@@ -82368,10 +82423,10 @@ function unitConstant(to) {
82368
82423
  /** Primary numeric field that also publishes the cap's `unit` string. */
82369
82424
  var UNIT_COMPANION_FIELD = {
82370
82425
  "numeric-sensor": "value",
82371
- "temperature-sensor": "celsius",
82372
- "humidity-sensor": "percent",
82373
- "pressure-sensor": "hpa",
82374
- "ambient-light-sensor": "lux"
82426
+ "temperature-sensor": "temperature",
82427
+ "humidity-sensor": "humidity",
82428
+ "pressure-sensor": "pressure",
82429
+ "ambient-light-sensor": "illuminance"
82375
82430
  };
82376
82431
  /** `unit` when converting that cap's primary numeric field; otherwise none. */
82377
82432
  function unitCompanionField(cap, fieldPath) {
@@ -82558,7 +82613,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82558
82613
  "battery": {
82559
82614
  version: 1,
82560
82615
  targets: [{
82561
- id: "percentage",
82616
+ id: "level",
82562
82617
  cardinality: "scalar",
82563
82618
  deviceTypes: [
82564
82619
  require_err_msg.DeviceType.Camera,
@@ -82572,7 +82627,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82572
82627
  ],
82573
82628
  apply: "add",
82574
82629
  vocabularyCap: "battery",
82575
- vocabularyStateField: "percentage",
82630
+ vocabularyStateField: "level",
82576
82631
  sources: [{
82577
82632
  kind: "field",
82578
82633
  valueKinds: ["number", "string"],
@@ -82587,7 +82642,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82587
82642
  }],
82588
82643
  sourceReport: { status: "assignment-status" },
82589
82644
  advancedExpression: true,
82590
- path: "percentage",
82645
+ path: "level",
82591
82646
  valueKind: "number",
82592
82647
  nullable: true,
82593
82648
  companions: [
@@ -82822,7 +82877,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82822
82877
  version: 1,
82823
82878
  targets: [
82824
82879
  {
82825
- id: "watts",
82880
+ id: "power",
82826
82881
  cardinality: "scalar",
82827
82882
  deviceTypes: [
82828
82883
  require_err_msg.DeviceType.Switch,
@@ -82842,7 +82897,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82842
82897
  ],
82843
82898
  apply: "add",
82844
82899
  vocabularyCap: "power-meter",
82845
- vocabularyStateField: "watts",
82900
+ vocabularyStateField: "power",
82846
82901
  sources: [{
82847
82902
  kind: "numeric",
82848
82903
  requiredUnit: "W",
@@ -82851,7 +82906,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82851
82906
  }],
82852
82907
  sourceReport: { status: "assignment-status" },
82853
82908
  advancedExpression: true,
82854
- path: "watts",
82909
+ path: "power",
82855
82910
  valueKind: "number",
82856
82911
  nullable: false,
82857
82912
  companions: [{
@@ -82861,7 +82916,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82861
82916
  }]
82862
82917
  },
82863
82918
  {
82864
- id: "kwhTotal",
82919
+ id: "energy",
82865
82920
  cardinality: "scalar",
82866
82921
  deviceTypes: [
82867
82922
  require_err_msg.DeviceType.Switch,
@@ -82881,7 +82936,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82881
82936
  ],
82882
82937
  apply: "add",
82883
82938
  vocabularyCap: "power-meter",
82884
- vocabularyStateField: "kwhTotal",
82939
+ vocabularyStateField: "energy",
82885
82940
  sources: [{
82886
82941
  kind: "numeric",
82887
82942
  requiredUnit: "kWh",
@@ -82890,7 +82945,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82890
82945
  }],
82891
82946
  sourceReport: { status: "assignment-status" },
82892
82947
  advancedExpression: true,
82893
- path: "kwhTotal",
82948
+ path: "energy",
82894
82949
  valueKind: "number",
82895
82950
  nullable: false,
82896
82951
  companions: [{
@@ -82900,7 +82955,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82900
82955
  }]
82901
82956
  },
82902
82957
  {
82903
- id: "volts",
82958
+ id: "voltage",
82904
82959
  cardinality: "scalar",
82905
82960
  deviceTypes: [
82906
82961
  require_err_msg.DeviceType.Switch,
@@ -82920,7 +82975,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82920
82975
  ],
82921
82976
  apply: "add",
82922
82977
  vocabularyCap: "power-meter",
82923
- vocabularyStateField: "volts",
82978
+ vocabularyStateField: "voltage",
82924
82979
  sources: [{
82925
82980
  kind: "numeric",
82926
82981
  requiredUnit: "V",
@@ -82929,7 +82984,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82929
82984
  }],
82930
82985
  sourceReport: { status: "assignment-status" },
82931
82986
  advancedExpression: true,
82932
- path: "volts",
82987
+ path: "voltage",
82933
82988
  valueKind: "number",
82934
82989
  nullable: false,
82935
82990
  companions: [{
@@ -82939,7 +82994,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82939
82994
  }]
82940
82995
  },
82941
82996
  {
82942
- id: "amps",
82997
+ id: "current",
82943
82998
  cardinality: "scalar",
82944
82999
  deviceTypes: [
82945
83000
  require_err_msg.DeviceType.Switch,
@@ -82959,7 +83014,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82959
83014
  ],
82960
83015
  apply: "add",
82961
83016
  vocabularyCap: "power-meter",
82962
- vocabularyStateField: "amps",
83017
+ vocabularyStateField: "current",
82963
83018
  sources: [{
82964
83019
  kind: "numeric",
82965
83020
  requiredUnit: "A",
@@ -82968,7 +83023,7 @@ var CAP_CUSTOMIZE_CATALOG = {
82968
83023
  }],
82969
83024
  sourceReport: { status: "assignment-status" },
82970
83025
  advancedExpression: true,
82971
- path: "amps",
83026
+ path: "current",
82972
83027
  valueKind: "number",
82973
83028
  nullable: false,
82974
83029
  companions: [{
@@ -83069,19 +83124,19 @@ var CAP_CUSTOMIZE_CATALOG = {
83069
83124
  * it is not an override list (D944).
83070
83125
  */
83071
83126
  var CAP_RUNTIME_FIELD_UNITS = {
83072
- "ambient-light-sensor": { lux: "lx" },
83127
+ "ambient-light-sensor": { illuminance: "lx" },
83073
83128
  "battery": {
83074
- percentage: "%",
83075
- volts: "V"
83129
+ level: "%",
83130
+ voltage: "V"
83076
83131
  },
83077
- "humidity-sensor": { percent: "%" },
83132
+ "humidity-sensor": { humidity: "%" },
83078
83133
  "power-meter": {
83079
- watts: "W",
83080
- kwhTotal: "kWh",
83081
- volts: "V",
83082
- amps: "A"
83134
+ power: "W",
83135
+ energy: "kWh",
83136
+ voltage: "V",
83137
+ current: "A"
83083
83138
  },
83084
- "temperature-sensor": { celsius: "°C" }
83139
+ "temperature-sensor": { temperature: "°C" }
83085
83140
  };
83086
83141
  //#endregion
83087
83142
  //#region src/composition/customize/field-source.ts
@@ -85200,7 +85255,7 @@ var BaseDevice = class {
85200
85255
  * `device-local-state.ts`. Drivers access via:
85201
85256
  *
85202
85257
  * `this.state.battery.sleeping = true` // patches the battery slice
85203
- * `const pct = this.state.battery.percentage` // reads the battery slice
85258
+ * `const pct = this.state.battery.level` // reads the battery slice
85204
85259
  * `this.state.deviceStatus.online = true` // mirrors `markOnline(true)`
85205
85260
  *
85206
85261
  * Adding a new cap with `runtimeState:` automatically extends this
@@ -85240,7 +85295,7 @@ var BaseDevice = class {
85240
85295
  * shape; drivers don't redeclare it, they just write through.
85241
85296
  *
85242
85297
  * Read: `this.runtimeState.getCapState('battery')` →
85243
- * `{percentage, charging, sleeping, lastUpdated}` for any
85298
+ * `{level, charging, sleeping, lastUpdated}` for any
85244
85299
  * provider that registers `batteryCapability`.
85245
85300
  * Write: `this.runtimeState.setCapState('battery', { … })`.
85246
85301
  *
@@ -87205,17 +87260,17 @@ function pickAccessoryControl(device) {
87205
87260
  var SENSOR_MAP = {
87206
87261
  "temperature-sensor": {
87207
87262
  capKey: "temperatureSensor",
87208
- field: "celsius",
87263
+ field: "temperature",
87209
87264
  fallbackUnit: "°C"
87210
87265
  },
87211
87266
  "humidity-sensor": {
87212
87267
  capKey: "humiditySensor",
87213
- field: "percent",
87268
+ field: "humidity",
87214
87269
  fallbackUnit: "%"
87215
87270
  },
87216
87271
  "ambient-light-sensor": {
87217
87272
  capKey: "ambientLightSensor",
87218
- field: "lux",
87273
+ field: "illuminance",
87219
87274
  fallbackUnit: "lx"
87220
87275
  },
87221
87276
  "numeric-sensor": {
@@ -97673,7 +97728,7 @@ var ACTUATOR_CAP_VOCABULARY = {
97673
97728
  label: t("Full brightness", "Luminosità massima"),
97674
97729
  phrase: t("Set {device} to full brightness", "Porta {device} alla massima luminosità"),
97675
97730
  icon: "sun",
97676
- args: { percentage: 100 }
97731
+ args: { level: 100 }
97677
97732
  },
97678
97733
  {
97679
97734
  id: "brightness.half",
@@ -97681,7 +97736,7 @@ var ACTUATOR_CAP_VOCABULARY = {
97681
97736
  label: t("Half brightness", "Luminosità a metà"),
97682
97737
  phrase: t("Dim {device} to half", "Abbassa {device} a metà luminosità"),
97683
97738
  icon: "sun-dim",
97684
- args: { percentage: 50 }
97739
+ args: { level: 50 }
97685
97740
  },
97686
97741
  {
97687
97742
  id: "brightness.off",
@@ -97689,16 +97744,16 @@ var ACTUATOR_CAP_VOCABULARY = {
97689
97744
  label: t("Brightness off", "Luminosità a zero"),
97690
97745
  phrase: t("Dim {device} to zero", "Abbassa {device} a zero"),
97691
97746
  icon: "lightbulb-off",
97692
- args: { percentage: 0 }
97747
+ args: { level: 0 }
97693
97748
  },
97694
97749
  {
97695
97750
  id: "brightness.set",
97696
97751
  method: "setBrightness",
97697
97752
  label: t("Set brightness", "Imposta la luminosità"),
97698
- phrase: t("Set the brightness of {device} to {percentage}", "Imposta la luminosità di {device} a {percentage}"),
97753
+ phrase: t("Set the brightness of {device} to {level}", "Imposta la luminosità di {device} a {level}"),
97699
97754
  icon: "sun-medium",
97700
97755
  openArgs: [{
97701
- key: "percentage",
97756
+ key: "level",
97702
97757
  label: PERCENT,
97703
97758
  offer: {
97704
97759
  kind: "number",
@@ -97712,13 +97767,13 @@ var ACTUATOR_CAP_VOCABULARY = {
97712
97767
  ],
97713
97768
  state: [{
97714
97769
  kind: "numeric",
97715
- field: "percentage",
97770
+ field: "level",
97716
97771
  quantity: t("the brightness", "la luminosità"),
97717
97772
  label: t("Brightness", "Luminosità"),
97718
97773
  unit: "%",
97719
97774
  icon: "sun"
97720
97775
  }],
97721
- events: { onBrightnessChanged: { notOperatorFacing: "the `percentage` state trigger reads the same change" } }
97776
+ events: { onBrightnessChanged: { notOperatorFacing: "the `level` state trigger reads the same change" } }
97722
97777
  },
97723
97778
  color: {
97724
97779
  scope: "device",
@@ -97732,7 +97787,7 @@ var ACTUATOR_CAP_VOCABULARY = {
97732
97787
  icon: "sun",
97733
97788
  args: { color: {
97734
97789
  mode: "mired",
97735
- mireds: 370
97790
+ colorTemperature: 370
97736
97791
  } }
97737
97792
  },
97738
97793
  {
@@ -97743,7 +97798,7 @@ var ACTUATOR_CAP_VOCABULARY = {
97743
97798
  icon: "snowflake",
97744
97799
  args: { color: {
97745
97800
  mode: "mired",
97746
- mireds: 200
97801
+ colorTemperature: 200
97747
97802
  } }
97748
97803
  },
97749
97804
  {
@@ -98357,7 +98412,7 @@ var ACTUATOR_CAP_VOCABULARY = {
98357
98412
  label: t("Fan off", "Ventilatore spento"),
98358
98413
  phrase: t("Stop {device}", "Ferma {device}"),
98359
98414
  icon: "power-off",
98360
- args: { percentage: 0 }
98415
+ args: { speed: 0 }
98361
98416
  },
98362
98417
  {
98363
98418
  id: "fan.full",
@@ -98365,16 +98420,16 @@ var ACTUATOR_CAP_VOCABULARY = {
98365
98420
  label: t("Fan full", "Ventilatore al massimo"),
98366
98421
  phrase: t("Run {device} at full speed", "Porta {device} alla massima velocità"),
98367
98422
  icon: "fan",
98368
- args: { percentage: 100 }
98423
+ args: { speed: 100 }
98369
98424
  },
98370
98425
  {
98371
98426
  id: "fan.speed",
98372
98427
  method: "setPercentage",
98373
98428
  label: t("Set speed", "Imposta la velocità"),
98374
- phrase: t("Set the speed of {device} to {percentage}", "Imposta la velocità di {device} al {percentage}"),
98429
+ phrase: t("Set the speed of {device} to {speed}", "Imposta la velocità di {device} al {speed}"),
98375
98430
  icon: "fan",
98376
98431
  openArgs: [{
98377
- key: "percentage",
98432
+ key: "speed",
98378
98433
  label: t("Speed", "Velocità"),
98379
98434
  offer: {
98380
98435
  kind: "number",
@@ -98436,7 +98491,7 @@ var ACTUATOR_CAP_VOCABULARY = {
98436
98491
  ],
98437
98492
  state: [{
98438
98493
  kind: "numeric",
98439
- field: "percentage",
98494
+ field: "speed",
98440
98495
  quantity: t("the speed", "la velocità"),
98441
98496
  label: t("Speed", "Velocità"),
98442
98497
  unit: "%",
@@ -99236,7 +99291,7 @@ var APPLIANCE_CAP_VOCABULARY = {
99236
99291
  },
99237
99292
  {
99238
99293
  kind: "numeric",
99239
- field: "progressPercent",
99294
+ field: "progress",
99240
99295
  quantity: t("the cycle progress", "l’avanzamento del lavaggio"),
99241
99296
  label: t("Progress", "Avanzamento"),
99242
99297
  unit: "%",
@@ -99594,10 +99649,10 @@ var APPLIANCE_CAP_VOCABULARY = {
99594
99649
  id: "media.seek",
99595
99650
  method: "seek",
99596
99651
  label: t("Seek", "Vai al punto"),
99597
- phrase: t("Move {device} to {positionMs}", "Porta {device} al punto {positionMs}"),
99652
+ phrase: t("Move {device} to {position}", "Porta {device} al punto {position}"),
99598
99653
  icon: "fast-forward",
99599
99654
  openArgs: [{
99600
- key: "positionMs",
99655
+ key: "position",
99601
99656
  label: t("Position", "Posizione"),
99602
99657
  offer: {
99603
99658
  kind: "number",
@@ -100650,7 +100705,7 @@ var SENSOR_CAP_VOCABULARY = {
100650
100705
  state: [
100651
100706
  {
100652
100707
  kind: "numeric",
100653
- field: "co2Ppm",
100708
+ field: "co2",
100654
100709
  quantity: t("the CO₂", "la CO₂"),
100655
100710
  label: t("CO₂", "CO₂"),
100656
100711
  unit: "ppm",
@@ -100658,7 +100713,7 @@ var SENSOR_CAP_VOCABULARY = {
100658
100713
  },
100659
100714
  {
100660
100715
  kind: "numeric",
100661
- field: "vocPpb",
100716
+ field: "voc",
100662
100717
  quantity: t("the VOC level", "il livello di COV"),
100663
100718
  label: t("VOC", "COV"),
100664
100719
  unit: "ppb",
@@ -100694,7 +100749,7 @@ var SENSOR_CAP_VOCABULARY = {
100694
100749
  noun: t("Light level", "Luminosità ambiente"),
100695
100750
  state: [{
100696
100751
  kind: "numeric",
100697
- field: "lux",
100752
+ field: "illuminance",
100698
100753
  quantity: t("the light level", "la luminosità"),
100699
100754
  label: t("Illuminance", "Illuminamento"),
100700
100755
  unit: "lx",
@@ -100897,7 +100952,7 @@ var SENSOR_CAP_VOCABULARY = {
100897
100952
  noun: t("Humidity", "Umidità"),
100898
100953
  state: [{
100899
100954
  kind: "numeric",
100900
- field: "percent",
100955
+ field: "humidity",
100901
100956
  quantity: t("the humidity", "l’umidità"),
100902
100957
  label: t("Humidity", "Umidità"),
100903
100958
  unit: "%",
@@ -100945,7 +101000,7 @@ var SENSOR_CAP_VOCABULARY = {
100945
101000
  state: [
100946
101001
  {
100947
101002
  kind: "numeric",
100948
- field: "watts",
101003
+ field: "power",
100949
101004
  quantity: t("the power draw", "il consumo"),
100950
101005
  label: t("Power", "Potenza"),
100951
101006
  unit: "W",
@@ -100953,7 +101008,7 @@ var SENSOR_CAP_VOCABULARY = {
100953
101008
  },
100954
101009
  {
100955
101010
  kind: "numeric",
100956
- field: "kwhTotal",
101011
+ field: "energy",
100957
101012
  quantity: t("the energy used", "l’energia consumata"),
100958
101013
  label: t("Energy", "Energia"),
100959
101014
  unit: "kWh",
@@ -100961,7 +101016,7 @@ var SENSOR_CAP_VOCABULARY = {
100961
101016
  },
100962
101017
  {
100963
101018
  kind: "numeric",
100964
- field: "volts",
101019
+ field: "voltage",
100965
101020
  quantity: t("the voltage", "la tensione"),
100966
101021
  label: t("Voltage", "Tensione"),
100967
101022
  unit: "V",
@@ -100969,7 +101024,7 @@ var SENSOR_CAP_VOCABULARY = {
100969
101024
  },
100970
101025
  {
100971
101026
  kind: "numeric",
100972
- field: "amps",
101027
+ field: "current",
100973
101028
  quantity: t("the current", "la corrente"),
100974
101029
  label: t("Current", "Corrente"),
100975
101030
  unit: "A",
@@ -100986,13 +101041,6 @@ var SENSOR_CAP_VOCABULARY = {
100986
101041
  label: t("Where", "Posizione"),
100987
101042
  phrase: t("When {device} is at {value}", "Quando {device} è in {value}"),
100988
101043
  icon: "map-pin"
100989
- }, {
100990
- kind: "numeric",
100991
- field: "batteryPercent",
100992
- quantity: t("the phone battery", "la batteria del telefono"),
100993
- label: t("Battery", "Batteria"),
100994
- unit: "%",
100995
- icon: "battery"
100996
101044
  }]
100997
101045
  },
100998
101046
  "pressure-sensor": {
@@ -101000,7 +101048,7 @@ var SENSOR_CAP_VOCABULARY = {
101000
101048
  noun: t("Pressure", "Pressione"),
101001
101049
  state: [{
101002
101050
  kind: "numeric",
101003
- field: "hpa",
101051
+ field: "pressure",
101004
101052
  quantity: t("the pressure", "la pressione"),
101005
101053
  label: t("Pressure", "Pressione"),
101006
101054
  unit: "hPa",
@@ -101036,7 +101084,7 @@ var SENSOR_CAP_VOCABULARY = {
101036
101084
  noun: t("Temperature", "Temperatura"),
101037
101085
  state: [{
101038
101086
  kind: "numeric",
101039
- field: "celsius",
101087
+ field: "temperature",
101040
101088
  quantity: t("the temperature", "la temperatura"),
101041
101089
  label: t("Temperature", "Temperatura"),
101042
101090
  unit: "°C",
@@ -101107,7 +101155,7 @@ var SENSOR_CAP_VOCABULARY = {
101107
101155
  state: [
101108
101156
  {
101109
101157
  kind: "numeric",
101110
- field: "percentage",
101158
+ field: "level",
101111
101159
  quantity: t("the battery level", "il livello della batteria"),
101112
101160
  label: t("Battery", "Batteria"),
101113
101161
  unit: "%",
@@ -101149,7 +101197,7 @@ var SENSOR_CAP_VOCABULARY = {
101149
101197
  icon: "battery-charging"
101150
101198
  }
101151
101199
  ],
101152
- events: { onStatusChanged: { notOperatorFacing: "the percentage / sleeping / charging state triggers each read one field of this change" } },
101200
+ events: { onStatusChanged: { notOperatorFacing: "the level / sleeping / charging state triggers each read one field of this change" } },
101153
101201
  extraEvents: [{
101154
101202
  category: require_event_category.EventCategory.DeviceAwake,
101155
101203
  label: t("Woke up", "Risvegliato"),
@@ -101167,7 +101215,7 @@ var SENSOR_CAP_VOCABULARY = {
101167
101215
  noun: t("Network link", "Collegamento di rete"),
101168
101216
  state: [{
101169
101217
  kind: "numeric",
101170
- field: "signalPercent",
101218
+ field: "signal",
101171
101219
  quantity: t("the signal strength", "l’intensità del segnale"),
101172
101220
  label: t("Signal", "Segnale"),
101173
101221
  unit: "%",
@@ -109900,6 +109948,46 @@ function prepareNotification(caps, n) {
109900
109948
  };
109901
109949
  }
109902
109950
  //#endregion
109951
+ //#region src/notification/delivery-params.ts
109952
+ function valueFor(param, raw) {
109953
+ switch (param.type) {
109954
+ case "enum": return typeof raw === "string" && (param.options ?? []).some((o) => o.value === raw) ? raw : void 0;
109955
+ case "number": {
109956
+ if (typeof raw !== "number" || !Number.isFinite(raw)) return void 0;
109957
+ const floor = param.min ?? Number.NEGATIVE_INFINITY;
109958
+ const ceil = param.max ?? Number.POSITIVE_INFINITY;
109959
+ return Math.min(ceil, Math.max(floor, raw));
109960
+ }
109961
+ case "boolean": return typeof raw === "boolean" ? raw : void 0;
109962
+ case "string": return typeof raw === "string" && raw.length > 0 ? raw : void 0;
109963
+ }
109964
+ }
109965
+ /**
109966
+ * The values a rule target's `params` contribute for a kind: only declared
109967
+ * keys, only valid values. `undefined` when nothing survives — a notifier that
109968
+ * declared nothing is never handed a `delivery` block.
109969
+ */
109970
+ function resolveDeliveryParams(declared, params) {
109971
+ if (declared === void 0 || params === void 0) return void 0;
109972
+ const out = {};
109973
+ for (const param of declared) {
109974
+ const value = valueFor(param, params[param.key]);
109975
+ if (value !== void 0) out[param.key] = value;
109976
+ }
109977
+ return Object.keys(out).length > 0 ? out : void 0;
109978
+ }
109979
+ /** The union of several kinds' declarations; the first declaration of a key wins. */
109980
+ function deliveryParamsDeclaredBy(perKind) {
109981
+ const seen = /* @__PURE__ */ new Set();
109982
+ const out = [];
109983
+ for (const declared of perKind) for (const param of declared ?? []) {
109984
+ if (seen.has(param.key)) continue;
109985
+ seen.add(param.key);
109986
+ out.push(param);
109987
+ }
109988
+ return out;
109989
+ }
109990
+ //#endregion
109903
109991
  //#region src/notification/system-event-filters.ts
109904
109992
  /**
109905
109993
  * WHICH narrowing filter speaks about WHICH system-event kind — one predicate,
@@ -118210,6 +118298,29 @@ function rewriteReferer(referer, route) {
118210
118298
  if (upstream === void 0) return null;
118211
118299
  return `${upstream.scheme}://${upstream.host}${rest?.[2] ?? "/"}${url.search}`;
118212
118300
  }
118301
+ function decodeFormComponent(raw) {
118302
+ try {
118303
+ return decodeURIComponent(raw.replace(/\+/g, " "));
118304
+ } catch {
118305
+ return null;
118306
+ }
118307
+ }
118308
+ /**
118309
+ * An `application/x-www-form-urlencoded` body whose field VALUES that are proxy URLs of
118310
+ * this attempt (absolute or root-relative) are turned back into the vendor URL they stand
118311
+ * for — the page's hidden inputs were rewritten on the way out (`rewriteBody`), and the
118312
+ * vendor must get its own URL back. Field order and every untouched pair stay byte-identical.
118313
+ */
118314
+ function rewriteFormBody(body, route) {
118315
+ return body.split("&").map((pair) => {
118316
+ const eq = pair.indexOf("=");
118317
+ if (eq === -1) return pair;
118318
+ const value = decodeFormComponent(pair.slice(eq + 1));
118319
+ if (value === null || !/^(?:https?:\/\/|\/)/i.test(value)) return pair;
118320
+ const back = rewriteReferer(value, route);
118321
+ return back === null ? pair : `${pair.slice(0, eq + 1)}${encodeURIComponent(back)}`;
118322
+ }).join("&");
118323
+ }
118213
118324
  /** Cookies the browser holds for the hub itself must never reach a vendor. */
118214
118325
  function filterForwardedCookies(cookieHeader) {
118215
118326
  return cookieHeader.split(";").map((part) => part.trim()).filter((part) => part.length > 0 && !part.toLowerCase().startsWith("camstack_")).join("; ");
@@ -118270,6 +118381,9 @@ function bodyKindOf(contentType) {
118270
118381
  if (type.startsWith("text/") || type.includes("javascript") || type.includes("json") || type.includes("xml")) return "other";
118271
118382
  return null;
118272
118383
  }
118384
+ function isFormEncoded(contentType) {
118385
+ return (firstHeader(contentType) ?? "").toLowerCase().startsWith("application/x-www-form-urlencoded");
118386
+ }
118273
118387
  function firstHeader(value) {
118274
118388
  return Array.isArray(value) ? value[0] : value;
118275
118389
  }
@@ -118400,7 +118514,7 @@ var VendorLoginProxy = class {
118400
118514
  sendPlain(res, 413, "Request too large");
118401
118515
  return;
118402
118516
  }
118403
- body = read;
118517
+ body = isFormEncoded(req.headers["content-type"]) ? Buffer.from(rewriteFormBody(read.toString("utf8"), route), "utf8") : read;
118404
118518
  }
118405
118519
  const headers = this.#requestHeaders(req, route, upstream);
118406
118520
  const upstreamRes = await this.#fetch(target, {
@@ -118414,9 +118528,10 @@ var VendorLoginProxy = class {
118414
118528
  const kind = bodyKindOf(upstreamRes.headers.get("content-type") ?? "");
118415
118529
  const declaredLength = Number(upstreamRes.headers.get("content-length") ?? "0");
118416
118530
  const text = kind !== null && !(declaredLength > MAX_TEXT_BODY_BYTES) && method !== "HEAD" ? await upstreamRes.text() : null;
118417
- this.#logger.debug("vendor login proxy: upstream answered", { meta: {
118531
+ this.#logger.info("vendor login proxy: upstream answered", { meta: {
118418
118532
  addonId: this.#addonId,
118419
118533
  host: upstream.host,
118534
+ path: target.pathname,
118420
118535
  status: upstreamRes.status,
118421
118536
  method
118422
118537
  } });
@@ -120107,6 +120222,8 @@ exports.DeclareKindResultSchema = DeclareKindResultSchema;
120107
120222
  exports.DeclaredDevices = DeclaredDevices;
120108
120223
  exports.DecodedAudioChunkSchema = require_sleep.DecodedAudioChunkSchema;
120109
120224
  exports.DeleteIntegrationResultSchema = DeleteIntegrationResultSchema;
120225
+ exports.DeliveryParamSchema = DeliveryParamSchema;
120226
+ exports.DeliveryParamValueSchema = DeliveryParamValueSchema;
120110
120227
  exports.DerivativeHelperSpecSchema = require_composition.DerivativeHelperSpecSchema;
120111
120228
  exports.DetailCropConventionSchema = DetailCropConventionSchema;
120112
120229
  exports.DetectionCatalogClassMapSchema = DetectionCatalogClassMapSchema;
@@ -121904,6 +122021,7 @@ exports.defineRecordKinds = require_sleep.defineRecordKinds;
121904
122021
  exports.dehydrateConfigField = require_sleep.dehydrateConfigField;
121905
122022
  exports.dehydrateSchema = require_sleep.dehydrateSchema;
121906
122023
  exports.deleteAlarmProfile = deleteAlarmProfile;
122024
+ exports.deliveryParamsDeclaredBy = deliveryParamsDeclaredBy;
121907
122025
  exports.derivativeDraft = derivativeDraft;
121908
122026
  exports.derivativeUnitLabel = derivativeUnitLabel;
121909
122027
  exports.deriveBatteryPresence = deriveBatteryPresence;
@@ -122462,6 +122580,7 @@ exports.resolveContainerPrimaryChild = resolveContainerPrimaryChild;
122462
122580
  exports.resolveCoreBlockEntry = resolveCoreBlockEntry;
122463
122581
  exports.resolveCoreBlockFiles = resolveCoreBlockFiles;
122464
122582
  exports.resolveCreateExportSubject = resolveCreateExportSubject;
122583
+ exports.resolveDeliveryParams = resolveDeliveryParams;
122465
122584
  exports.resolveDeviceControlKind = resolveDeviceControlKind;
122466
122585
  exports.resolveDeviceProfile = resolveDeviceProfile;
122467
122586
  exports.resolveDeviceTarget = resolveDeviceTarget;