@camstack/types 1.2.416 → 1.2.417

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/dist/addon.js +1 -1
  2. package/dist/addon.mjs +1 -1
  3. package/dist/capabilities/air-quality-sensor.cap.d.ts +2 -8
  4. package/dist/capabilities/ambient-light-sensor.cap.d.ts +3 -14
  5. package/dist/capabilities/battery.cap.d.ts +9 -2
  6. package/dist/capabilities/binary.cap.d.ts +0 -5
  7. package/dist/capabilities/capability-definition.d.ts +6 -6
  8. package/dist/capabilities/consumables.cap.d.ts +30 -41
  9. package/dist/capabilities/control.cap.d.ts +3 -25
  10. package/dist/capabilities/core-blocks.cap.d.ts +1 -0
  11. package/dist/capabilities/customize-catalog.d.ts +0 -8
  12. package/dist/capabilities/customize-spec.d.ts +2 -3
  13. package/dist/capabilities/device-manager.cap.d.ts +79 -0
  14. package/dist/capabilities/device-provider.cap.d.ts +36 -0
  15. package/dist/capabilities/enum-sensor.cap.d.ts +5 -17
  16. package/dist/capabilities/humidity-sensor.cap.d.ts +3 -14
  17. package/dist/capabilities/index.d.ts +1 -1
  18. package/dist/capabilities/motion.cap.d.ts +1 -1
  19. package/dist/capabilities/numeric-sensor.cap.d.ts +8 -16
  20. package/dist/capabilities/pet-feeder.cap.d.ts +1 -1
  21. package/dist/capabilities/power-meter.cap.d.ts +0 -11
  22. package/dist/capabilities/pressure-sensor.cap.d.ts +3 -9
  23. package/dist/capabilities/running-state.cap.d.ts +1 -2
  24. package/dist/capabilities/runtime-field-unit.d.ts +1 -0
  25. package/dist/capabilities/runtime-field-units.d.ts +8 -0
  26. package/dist/capabilities/switch.cap.d.ts +0 -5
  27. package/dist/capabilities/temperature-sensor.cap.d.ts +5 -20
  28. package/dist/capabilities/weather.cap.d.ts +4 -13
  29. package/dist/client.d.ts +2 -1
  30. package/dist/client.js +54 -5
  31. package/dist/client.mjs +52 -6
  32. package/dist/composition/composition-report.d.ts +8 -3
  33. package/dist/composition/state-fields.d.ts +1 -1
  34. package/dist/composition/validate-composition.d.ts +3 -2
  35. package/dist/device/cap-vocabulary/types.d.ts +2 -2
  36. package/dist/device/schema-fields.d.ts +3 -0
  37. package/dist/device/source-info.d.ts +12 -6
  38. package/dist/generated/addon-cap-facts.d.ts +1 -1
  39. package/dist/generated/customize-catalog.d.ts +11 -87
  40. package/dist/generated/history-catalog.d.ts +1 -1
  41. package/dist/index.d.ts +3 -1
  42. package/dist/index.js +755 -490
  43. package/dist/index.mjs +738 -490
  44. package/dist/{sleep-BErAxhul.mjs → sleep-CARd6wZF.mjs} +161 -128
  45. package/dist/{sleep-BPQ2ZyaI.js → sleep-gtskVoMw.js} +214 -127
  46. package/dist/units/convert.d.ts +5 -0
  47. package/dist/units/format-reading.d.ts +15 -0
  48. package/dist/units/index.d.ts +8 -1
  49. package/dist/units/ingest-reading.d.ts +21 -0
  50. package/dist/units/quantity.d.ts +47 -0
  51. package/dist/units/threshold.d.ts +6 -0
  52. package/dist/units/unit-table.d.ts +2 -228
  53. package/package.json +1 -1
  54. package/dist/capabilities/advanced-parameters.d.ts +0 -17
@@ -6,22 +6,16 @@ import { DeviceType } from '../device/device-type.js';
6
6
  * entries with `device_class: temperature` and any future native
7
7
  * thermometer.
8
8
  *
9
- * Unit normalisation: providers convert to Celsius before storing.
10
- * The slice value is always Celsius so cross-cap aggregators
11
- * (climate-control's `currentTemp`, energy analytics) can compose
12
- * without per-source unit fixups. The canonical display unit (`°C`) is
13
- * a descriptor constant in the UI (ROLE_DESCRIPTOR), not stored in
14
- * `sourceInfo`.
9
+ * The number is Celsius (D944). Providers convert on ingest. A failed
10
+ * conversion is `null`, never a guess. Display unit is a read-time preference.
15
11
  *
16
12
  * Status `lastFetchedAt` lets staleness-aware consumers detect a
17
13
  * frozen feed (provider hung) distinct from a "temperature hasn't
18
14
  * changed" steady state.
19
15
  */
20
16
  export declare const TemperatureSensorStatusSchema: z.ZodObject<{
21
- celsius: z.ZodNumber;
17
+ celsius: z.ZodNullable<z.ZodNumber>;
22
18
  lastFetchedAt: z.ZodNumber;
23
- unit: z.ZodOptional<z.ZodString>;
24
- precision: z.ZodOptional<z.ZodNumber>;
25
19
  }, z.core.$strip>;
26
20
  export type TemperatureSensorStatus = z.infer<typeof TemperatureSensorStatusSchema>;
27
21
  export declare const temperatureSensorCapability: {
@@ -33,18 +27,14 @@ export declare const temperatureSensorCapability: {
33
27
  readonly methods: {};
34
28
  readonly status: {
35
29
  readonly schema: z.ZodObject<{
36
- celsius: z.ZodNumber;
30
+ celsius: z.ZodNullable<z.ZodNumber>;
37
31
  lastFetchedAt: z.ZodNumber;
38
- unit: z.ZodOptional<z.ZodString>;
39
- precision: z.ZodOptional<z.ZodNumber>;
40
32
  }, z.core.$strip>;
41
33
  readonly kind: 'push';
42
34
  };
43
35
  readonly runtimeState: z.ZodObject<{
44
- celsius: z.ZodNumber;
36
+ celsius: z.ZodNullable<z.ZodNumber>;
45
37
  lastFetchedAt: z.ZodNumber;
46
- unit: z.ZodOptional<z.ZodString>;
47
- precision: z.ZodOptional<z.ZodNumber>;
48
38
  }, z.core.$strip>;
49
39
  /**
50
40
  * Runtime-state durability: **restored** — as `numeric-sensor` (69 of 125 writes were the clock alone).
@@ -68,10 +58,5 @@ export declare const temperatureSensorCapability: {
68
58
  /** Clock fields: written, but excluded from the compare that decides
69
59
  * whether persisting is worth a SQLite commit. */
70
60
  readonly volatileStateFields: readonly ["lastFetchedAt"];
71
- readonly customize: {
72
- readonly version: 1;
73
- readonly advanced: 'derive';
74
- readonly targets: readonly [];
75
- };
76
61
  };
77
62
  export type ITemperatureSensorProvider = InferProvider<typeof temperatureSensorCapability>;
@@ -23,12 +23,9 @@ import { DeviceType } from '../device/device-type.js';
23
23
  export declare const WeatherStatusSchema: z.ZodObject<{
24
24
  condition: z.ZodNullable<z.ZodString>;
25
25
  temperature: z.ZodNullable<z.ZodNumber>;
26
- temperatureUnit: z.ZodNullable<z.ZodString>;
27
26
  humidity: z.ZodNullable<z.ZodNumber>;
28
27
  pressure: z.ZodNullable<z.ZodNumber>;
29
- pressureUnit: z.ZodNullable<z.ZodString>;
30
28
  windSpeed: z.ZodNullable<z.ZodNumber>;
31
- windSpeedUnit: z.ZodNullable<z.ZodString>;
32
29
  windBearing: z.ZodNullable<z.ZodNumber>;
33
30
  lastFetchedAt: z.ZodNumber;
34
31
  }, z.core.$strip>;
@@ -44,12 +41,9 @@ export declare const weatherCapability: {
44
41
  readonly schema: z.ZodObject<{
45
42
  condition: z.ZodNullable<z.ZodString>;
46
43
  temperature: z.ZodNullable<z.ZodNumber>;
47
- temperatureUnit: z.ZodNullable<z.ZodString>;
48
44
  humidity: z.ZodNullable<z.ZodNumber>;
49
45
  pressure: z.ZodNullable<z.ZodNumber>;
50
- pressureUnit: z.ZodNullable<z.ZodString>;
51
46
  windSpeed: z.ZodNullable<z.ZodNumber>;
52
- windSpeedUnit: z.ZodNullable<z.ZodString>;
53
47
  windBearing: z.ZodNullable<z.ZodNumber>;
54
48
  lastFetchedAt: z.ZodNumber;
55
49
  }, z.core.$strip>;
@@ -62,12 +56,9 @@ export declare const weatherCapability: {
62
56
  readonly runtimeState: z.ZodObject<{
63
57
  condition: z.ZodNullable<z.ZodString>;
64
58
  temperature: z.ZodNullable<z.ZodNumber>;
65
- temperatureUnit: z.ZodNullable<z.ZodString>;
66
59
  humidity: z.ZodNullable<z.ZodNumber>;
67
60
  pressure: z.ZodNullable<z.ZodNumber>;
68
- pressureUnit: z.ZodNullable<z.ZodString>;
69
61
  windSpeed: z.ZodNullable<z.ZodNumber>;
70
- windSpeedUnit: z.ZodNullable<z.ZodString>;
71
62
  windBearing: z.ZodNullable<z.ZodNumber>;
72
63
  lastFetchedAt: z.ZodNumber;
73
64
  }, z.core.$strip>;
@@ -79,13 +70,13 @@ export declare const weatherCapability: {
79
70
  */
80
71
  readonly durability: 'session';
81
72
  /**
82
- * History (D850): recorded series. Units follow the sibling `*Unit` fields.
73
+ * History (D850): recorded series. Numbers are the quantity base (D944).
83
74
  */
84
75
  readonly history: {
85
76
  readonly fields: {
86
77
  readonly temperature: {
87
78
  readonly kind: 'gauge';
88
- readonly unitFrom: 'temperatureUnit';
79
+ readonly unit: '°C';
89
80
  readonly deadband: 0.2;
90
81
  };
91
82
  readonly humidity: {
@@ -95,12 +86,12 @@ export declare const weatherCapability: {
95
86
  };
96
87
  readonly pressure: {
97
88
  readonly kind: 'gauge';
98
- readonly unitFrom: 'pressureUnit';
89
+ readonly unit: 'hPa';
99
90
  readonly deadband: 0.5;
100
91
  };
101
92
  readonly windSpeed: {
102
93
  readonly kind: 'gauge';
103
- readonly unitFrom: 'windSpeedUnit';
94
+ readonly unit: 'm/s';
104
95
  readonly deadband: 0.5;
105
96
  };
106
97
  };
package/dist/client.d.ts CHANGED
@@ -14,4 +14,5 @@
14
14
  * value this entry does not export — a missing name here is `undefined` at
15
15
  * runtime, not a build error.
16
16
  */
17
- export { APPLE_SA_TO_MACRO, AUDIO_MACRO_LABELS, AlarmArmModeSchema, CLIP_BROKER_PACED_RATES, COCO_TO_MACRO, CamProfileSchema, ICON_CATEGORIES, ICON_ENTRIES, ICON_KEYS, ICON_VIEWER_MODULES, IconKeySchema, LOCATION_ICON_FALLBACK, DEFINITIVE_DEVICE_REFUSALS, DEVICE_CERT_RENEW_WINDOW_DAYS, DEVICE_DEFINITIVE_REFUSALS_BEFORE_DELETE, DEVICE_REFRESH_REFUSAL_PREFIX, DEVICE_CERT_SIGNATURE, DEVICE_SIGNATURE_MESSAGE_VERSION, DEFAULT_TIMELAPSE_PREVIEW_TEXT, DeviceType, EVENTFUL_CAP_NAMES, EVENT_KIND_BY_CAP, EVENT_TAXONOMY, MACRO_LABELS, NC_ALARM_DELAY_MAX_SEC, NC_ALARM_SENSORS_MAX, NC_ALARM_SYSTEM_EVENT_KINDS, NC_ALARM_TRIGGERED_MAX_SEC, NC_BATTERY_CONSUMABLE_SYSTEM_EVENT_KINDS, NC_CAMERA_SCOPE_CAP_NAME, NC_CONSUMABLE_LOW_PERCENT_DEFAULT, NC_CONSUMABLE_LOW_PERCENT_MAX, NC_GROUPING_DEFAULT_SEC, NC_GROUPING_MAX_SEC, NC_GROUPING_MIN_SEC, NC_RULE_EDITOR_SECTION_ORDER, NC_RULE_KIND_SPECS, NC_SENSOR_TRANSITION_UNSUPPORTED_REASON, NC_SYSTEM_EVENT_FAMILY_FILTERS, NC_SYSTEM_EVENT_CLASS_SPECS, NC_SYSTEM_EVENT_KIND_GROUP_SPECS, NC_SYSTEM_EVENT_SUMMARY_FAMILIES, NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS, NC_TEMPLATE_VARS, NcAlarmConfigSchema, NcAlarmSensorsSchema, NcAlarmSettingsPatchSchema, NcHistoryEntrySchema, NcRuleLastRunsSchema, NodeDirectorySchema, RECORDING_EXPORT_MAX_READ_BYTES, RETRAIN_REVIEW_ADJUSTED_IOU, RETRAIN_REVIEW_MATCH_IOU, RETRAIN_REVIEW_STATUSES, RETRAIN_REVISION_CONFLICT, SystemMirror, TIMELAPSE_DENSE_FLOOR_SEC, TimelapseRuleSchema, YAMNET_TO_MACRO, alarmDeviceBlocksArming, alarmDeviceSecureOnArm, alarmPatchLanded, canonicalIconKey, buildDeviceEnrollmentLink, buildDeviceSignatureMessage, deviceRefusalFromMessage, isDefinitiveDeviceRefusal, classifyRetrainReview, conditionVisibleForKind, createSystemProxy, droppedConditionsForKind, iconCategoryLabel, iconEntry, iconsInCategory, isIconKey, isHeldBackTemplateVar, isSystemRuleKind, kindsForDiscriminator, locationIconKey, knownValues, nodePickerItems, parseDeviceEnrollmentLink, packagePickerItems, pickerForCondition, pickerForRuleClasses, parseRetrainRevisionConflict, resolveIconKey, resolveModeDelays, retrainBoxIou, retrainRevisionConflictMessage, ruleDeviceCompatCapNames, ruleEditorSectionsForKind, ruleGroupingApplies, ruleKindOf, ruleKindSpec, ruleSeedForSection, searchIcons, sensorTransitionNeverFires, sensorTransitionOffered, stateLabel, summarizeReview, systemEventClassesFor, systemEventClassKinds, systemEventDeliveryProblems, systemEventFilterAppliesToAnyKind, systemEventKindsOfFamily, systemFamilyOfKind, templateCarriesSummary, templateVarDeliveryApplies, templateVarKindApplies, templateVarSystemEventApplies, buildSubjectPath, isDrawableSubjectPath, projectSubjectPath, subjectPathSampleFromBox, subjectPathSvgPoints, expandSystemEventClasses, withSystemEventClasses, } from './index.js';
17
+ export { APPLE_SA_TO_MACRO, AUDIO_MACRO_LABELS, AlarmArmModeSchema, CLIP_BROKER_PACED_RATES, COCO_TO_MACRO, CamProfileSchema, ICON_CATEGORIES, ICON_ENTRIES, ICON_KEYS, ICON_VIEWER_MODULES, IconKeySchema, LOCATION_ICON_FALLBACK, DEFINITIVE_DEVICE_REFUSALS, DEVICE_CERT_RENEW_WINDOW_DAYS, DEVICE_DEFINITIVE_REFUSALS_BEFORE_DELETE, DEVICE_REFRESH_REFUSAL_PREFIX, DEVICE_CERT_SIGNATURE, DEVICE_SIGNATURE_MESSAGE_VERSION, DEFAULT_TIMELAPSE_PREVIEW_TEXT, DeviceType, EVENTFUL_CAP_NAMES, EVENT_KIND_BY_CAP, EVENT_TAXONOMY, MACRO_LABELS, NC_ALARM_DELAY_MAX_SEC, NC_ALARM_SENSORS_MAX, NC_ALARM_SYSTEM_EVENT_KINDS, NC_ALARM_TRIGGERED_MAX_SEC, NC_BATTERY_CONSUMABLE_SYSTEM_EVENT_KINDS, NC_CAMERA_SCOPE_CAP_NAME, NC_CONSUMABLE_LOW_PERCENT_DEFAULT, NC_CONSUMABLE_LOW_PERCENT_MAX, NC_GROUPING_DEFAULT_SEC, NC_GROUPING_MAX_SEC, NC_GROUPING_MIN_SEC, NC_RULE_EDITOR_SECTION_ORDER, NC_RULE_KIND_SPECS, NC_SENSOR_TRANSITION_UNSUPPORTED_REASON, NC_SYSTEM_EVENT_FAMILY_FILTERS, NC_SYSTEM_EVENT_CLASS_SPECS, NC_SYSTEM_EVENT_KIND_GROUP_SPECS, NC_SYSTEM_EVENT_SUMMARY_FAMILIES, NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS, NC_TEMPLATE_VARS, NcAlarmConfigSchema, NcAlarmSensorsSchema, NcAlarmSettingsPatchSchema, NcHistoryEntrySchema, NcRuleLastRunsSchema, NodeDirectorySchema, RECORDING_EXPORT_MAX_READ_BYTES, RETRAIN_REVIEW_ADJUSTED_IOU, RETRAIN_REVIEW_MATCH_IOU, RETRAIN_REVIEW_STATUSES, RETRAIN_REVISION_CONFLICT, SystemMirror, TIMELAPSE_DENSE_FLOOR_SEC, TimelapseRuleSchema, YAMNET_TO_MACRO, alarmDeviceBlocksArming, alarmDeviceSecureOnArm, alarmPatchLanded, canonicalIconKey, buildDeviceEnrollmentLink, buildDeviceSignatureMessage, deviceRefusalFromMessage, isDefinitiveDeviceRefusal, classifyRetrainReview, conditionVisibleForKind, createSystemProxy, droppedConditionsForKind, iconCategoryLabel, iconEntry, iconsInCategory, isIconKey, isHeldBackTemplateVar, isSystemRuleKind, kindsForDiscriminator, locationIconKey, knownValues, nodePickerItems, parseDeviceEnrollmentLink, packagePickerItems, pickerForCondition, pickerForRuleClasses, parseRetrainRevisionConflict, resolveIconKey, resolveModeDelays, retrainBoxIou, retrainRevisionConflictMessage, ruleDeviceCompatCapNames, ruleEditorSectionsForKind, ruleGroupingApplies, ruleKindOf, ruleKindSpec, ruleSeedForSection, searchIcons, sensorTransitionNeverFires, sensorTransitionOffered, stateLabel, summarizeReview, systemEventClassesFor, systemEventClassKinds, systemEventDeliveryProblems, systemEventFilterAppliesToAnyKind, systemEventKindsOfFamily, systemFamilyOfKind, templateCarriesSummary, templateVarDeliveryApplies, templateVarKindApplies, templateVarSystemEventApplies, buildSubjectPath, isDrawableSubjectPath, projectSubjectPath, subjectPathSampleFromBox, subjectPathSvgPoints, expandSystemEventClasses, withSystemEventClasses, bundledCamstack, paintHex, paletteResultSchema, } from './index.js';
18
+ export type { PaletteReady, PaletteResult, PaletteEntryId, PalettePresetId } from './index.js';
package/dist/client.js CHANGED
@@ -306,6 +306,52 @@ function parseRetrainRevisionConflict(message) {
306
306
  expectedRevision: Number(match[2])
307
307
  };
308
308
  }
309
+ var READING_QUANTITIES = [
310
+ "temperature",
311
+ "pressure",
312
+ "speed",
313
+ "precipitation",
314
+ "precipitation-rate",
315
+ "length",
316
+ "area",
317
+ "illuminance",
318
+ "irradiance",
319
+ "power",
320
+ "energy",
321
+ "voltage",
322
+ "current",
323
+ "apparent-power",
324
+ "humidity",
325
+ "percentage",
326
+ "concentration-volume",
327
+ "concentration-mass",
328
+ "concentration-ppb",
329
+ "volume",
330
+ "duration",
331
+ "duration-ms",
332
+ "information",
333
+ "sound-level",
334
+ "signal-level",
335
+ "colour-temperature",
336
+ "angle",
337
+ "bitrate",
338
+ "rate",
339
+ "mass",
340
+ "index",
341
+ "ratio",
342
+ "count",
343
+ "none",
344
+ "device"
345
+ ];
346
+ zod.z.enum(READING_QUANTITIES);
347
+ new Set(READING_QUANTITIES);
348
+ function readingMeta(quantity, extras) {
349
+ return {
350
+ quantity,
351
+ ...extras?.precision !== void 0 ? { precision: extras.precision } : {},
352
+ ...extras?.label !== void 0 ? { label: extras.label } : {}
353
+ };
354
+ }
309
355
  //#endregion
310
356
  //#region src/capabilities/schemas/streaming-shared.ts
311
357
  /** Shared Zod schemas used across streaming capabilities. */
@@ -325,8 +371,8 @@ var CamStreamKindSchema = zod.z.enum([
325
371
  "derived"
326
372
  ]);
327
373
  var CamStreamResolutionSchema = zod.z.object({
328
- width: zod.z.number().int().positive(),
329
- height: zod.z.number().int().positive()
374
+ width: zod.z.number().int().positive().meta(readingMeta("none")),
375
+ height: zod.z.number().int().positive().meta(readingMeta("none"))
330
376
  });
331
377
  zod.z.object({
332
378
  /** Stable, provider-assigned id unique within the (deviceId) scope. */
@@ -22171,7 +22217,7 @@ var paletteUnknownSchema = zod.z.object({
22171
22217
  status: zod.z.literal("unknown"),
22172
22218
  reason: zod.z.string()
22173
22219
  });
22174
- zod.z.discriminatedUnion("status", [paletteReadySchema, paletteUnknownSchema]);
22220
+ var paletteResultSchema = zod.z.discriminatedUnion("status", [paletteReadySchema, paletteUnknownSchema]);
22175
22221
  zod.z.union([zod.z.object({ presetId: zod.z.string() }), zod.z.object({
22176
22222
  presetId: zod.z.string(),
22177
22223
  overrides: zod.z.record(zod.z.string(), paletteSwatchSchema)
@@ -22518,8 +22564,8 @@ var MaskPolygonShapeSchema = zod.z.object({
22518
22564
  /** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
22519
22565
  var MaskGridShapeSchema = zod.z.object({
22520
22566
  kind: zod.z.literal("grid"),
22521
- gridWidth: zod.z.number(),
22522
- gridHeight: zod.z.number(),
22567
+ gridWidth: zod.z.number().meta(readingMeta("none")),
22568
+ gridHeight: zod.z.number().meta(readingMeta("none")),
22523
22569
  cells: zod.z.array(zod.z.boolean())
22524
22570
  });
22525
22571
  /** Directed line / tripwire — an ordered list of normalized points (≥2). */
@@ -32225,6 +32271,7 @@ exports.alarmPatchLanded = alarmPatchLanded;
32225
32271
  exports.buildDeviceEnrollmentLink = buildDeviceEnrollmentLink;
32226
32272
  exports.buildDeviceSignatureMessage = buildDeviceSignatureMessage;
32227
32273
  exports.buildSubjectPath = buildSubjectPath;
32274
+ exports.bundledCamstack = bundledCamstack;
32228
32275
  exports.canonicalIconKey = canonicalIconKey;
32229
32276
  exports.classifyRetrainReview = classifyRetrainReview;
32230
32277
  exports.conditionVisibleForKind = conditionVisibleForKind;
@@ -32245,6 +32292,8 @@ exports.knownValues = knownValues;
32245
32292
  exports.locationIconKey = locationIconKey;
32246
32293
  exports.nodePickerItems = nodePickerItems;
32247
32294
  exports.packagePickerItems = packagePickerItems;
32295
+ exports.paintHex = paintHex;
32296
+ exports.paletteResultSchema = paletteResultSchema;
32248
32297
  exports.parseDeviceEnrollmentLink = parseDeviceEnrollmentLink;
32249
32298
  exports.parseRetrainRevisionConflict = parseRetrainRevisionConflict;
32250
32299
  exports.pickerForCondition = pickerForCondition;
package/dist/client.mjs CHANGED
@@ -305,6 +305,52 @@ function parseRetrainRevisionConflict(message) {
305
305
  expectedRevision: Number(match[2])
306
306
  };
307
307
  }
308
+ var READING_QUANTITIES = [
309
+ "temperature",
310
+ "pressure",
311
+ "speed",
312
+ "precipitation",
313
+ "precipitation-rate",
314
+ "length",
315
+ "area",
316
+ "illuminance",
317
+ "irradiance",
318
+ "power",
319
+ "energy",
320
+ "voltage",
321
+ "current",
322
+ "apparent-power",
323
+ "humidity",
324
+ "percentage",
325
+ "concentration-volume",
326
+ "concentration-mass",
327
+ "concentration-ppb",
328
+ "volume",
329
+ "duration",
330
+ "duration-ms",
331
+ "information",
332
+ "sound-level",
333
+ "signal-level",
334
+ "colour-temperature",
335
+ "angle",
336
+ "bitrate",
337
+ "rate",
338
+ "mass",
339
+ "index",
340
+ "ratio",
341
+ "count",
342
+ "none",
343
+ "device"
344
+ ];
345
+ z.enum(READING_QUANTITIES);
346
+ new Set(READING_QUANTITIES);
347
+ function readingMeta(quantity, extras) {
348
+ return {
349
+ quantity,
350
+ ...extras?.precision !== void 0 ? { precision: extras.precision } : {},
351
+ ...extras?.label !== void 0 ? { label: extras.label } : {}
352
+ };
353
+ }
308
354
  //#endregion
309
355
  //#region src/capabilities/schemas/streaming-shared.ts
310
356
  /** Shared Zod schemas used across streaming capabilities. */
@@ -324,8 +370,8 @@ var CamStreamKindSchema = z.enum([
324
370
  "derived"
325
371
  ]);
326
372
  var CamStreamResolutionSchema = z.object({
327
- width: z.number().int().positive(),
328
- height: z.number().int().positive()
373
+ width: z.number().int().positive().meta(readingMeta("none")),
374
+ height: z.number().int().positive().meta(readingMeta("none"))
329
375
  });
330
376
  z.object({
331
377
  /** Stable, provider-assigned id unique within the (deviceId) scope. */
@@ -22170,7 +22216,7 @@ var paletteUnknownSchema = z.object({
22170
22216
  status: z.literal("unknown"),
22171
22217
  reason: z.string()
22172
22218
  });
22173
- z.discriminatedUnion("status", [paletteReadySchema, paletteUnknownSchema]);
22219
+ var paletteResultSchema = z.discriminatedUnion("status", [paletteReadySchema, paletteUnknownSchema]);
22174
22220
  z.union([z.object({ presetId: z.string() }), z.object({
22175
22221
  presetId: z.string(),
22176
22222
  overrides: z.record(z.string(), paletteSwatchSchema)
@@ -22517,8 +22563,8 @@ var MaskPolygonShapeSchema = z.object({
22517
22563
  /** Boolean cell grid — row-major, length === gridWidth*gridHeight. */
22518
22564
  var MaskGridShapeSchema = z.object({
22519
22565
  kind: z.literal("grid"),
22520
- gridWidth: z.number(),
22521
- gridHeight: z.number(),
22566
+ gridWidth: z.number().meta(readingMeta("none")),
22567
+ gridHeight: z.number().meta(readingMeta("none")),
22522
22568
  cells: z.array(z.boolean())
22523
22569
  });
22524
22570
  /** Directed line / tripwire — an ordered list of normalized points (≥2). */
@@ -32159,4 +32205,4 @@ var TimelapseRuleSchema = TimelapseRuleInputSchema.extend({
32159
32205
  updatedAt: z.number()
32160
32206
  });
32161
32207
  //#endregion
32162
- export { APPLE_SA_TO_MACRO, AUDIO_MACRO_LABELS, AlarmArmModeSchema, CLIP_BROKER_PACED_RATES, COCO_TO_MACRO, CamProfileSchema, DEFAULT_TIMELAPSE_PREVIEW_TEXT, DEFINITIVE_DEVICE_REFUSALS, DEVICE_CERT_RENEW_WINDOW_DAYS, DEVICE_CERT_SIGNATURE, DEVICE_DEFINITIVE_REFUSALS_BEFORE_DELETE, DEVICE_REFRESH_REFUSAL_PREFIX, DEVICE_SIGNATURE_MESSAGE_VERSION, DeviceType, EVENTFUL_CAP_NAMES, EVENT_KIND_BY_CAP, EVENT_TAXONOMY, ICON_CATEGORIES, ICON_ENTRIES, ICON_KEYS, ICON_VIEWER_MODULES, IconKeySchema, LOCATION_ICON_FALLBACK, MACRO_LABELS, NC_ALARM_DELAY_MAX_SEC, NC_ALARM_SENSORS_MAX, NC_ALARM_SYSTEM_EVENT_KINDS, NC_ALARM_TRIGGERED_MAX_SEC, NC_BATTERY_CONSUMABLE_SYSTEM_EVENT_KINDS, NC_CAMERA_SCOPE_CAP_NAME, NC_CONSUMABLE_LOW_PERCENT_DEFAULT, NC_CONSUMABLE_LOW_PERCENT_MAX, NC_GROUPING_DEFAULT_SEC, NC_GROUPING_MAX_SEC, NC_GROUPING_MIN_SEC, NC_RULE_EDITOR_SECTION_ORDER, NC_RULE_KIND_SPECS, NC_SENSOR_TRANSITION_UNSUPPORTED_REASON, NC_SYSTEM_EVENT_CLASS_SPECS, NC_SYSTEM_EVENT_FAMILY_FILTERS, NC_SYSTEM_EVENT_KIND_GROUP_SPECS, NC_SYSTEM_EVENT_SUMMARY_FAMILIES, NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS, NC_TEMPLATE_VARS, NcAlarmConfigSchema, NcAlarmSensorsSchema, NcAlarmSettingsPatchSchema, NcHistoryEntrySchema, NcRuleLastRunsSchema, NodeDirectorySchema, RECORDING_EXPORT_MAX_READ_BYTES, RETRAIN_REVIEW_ADJUSTED_IOU, RETRAIN_REVIEW_MATCH_IOU, RETRAIN_REVIEW_STATUSES, RETRAIN_REVISION_CONFLICT, SystemMirror, TIMELAPSE_DENSE_FLOOR_SEC, TimelapseRuleSchema, YAMNET_TO_MACRO, alarmDeviceBlocksArming, alarmDeviceSecureOnArm, alarmPatchLanded, buildDeviceEnrollmentLink, buildDeviceSignatureMessage, buildSubjectPath, canonicalIconKey, classifyRetrainReview, conditionVisibleForKind, createSystemProxy, deviceRefusalFromMessage, droppedConditionsForKind, expandSystemEventClasses, iconCategoryLabel, iconEntry, iconsInCategory, isDefinitiveDeviceRefusal, isDrawableSubjectPath, isHeldBackTemplateVar, isIconKey, isSystemRuleKind, kindsForDiscriminator, knownValues, locationIconKey, nodePickerItems, packagePickerItems, parseDeviceEnrollmentLink, parseRetrainRevisionConflict, pickerForCondition, pickerForRuleClasses, projectSubjectPath, resolveIconKey, resolveModeDelays, retrainBoxIou, retrainRevisionConflictMessage, ruleDeviceCompatCapNames, ruleEditorSectionsForKind, ruleGroupingApplies, ruleKindOf, ruleKindSpec, ruleSeedForSection, searchIcons, sensorTransitionNeverFires, sensorTransitionOffered, stateLabel, subjectPathSampleFromBox, subjectPathSvgPoints, summarizeReview, systemEventClassKinds, systemEventClassesFor, systemEventDeliveryProblems, systemEventFilterAppliesToAnyKind, systemEventKindsOfFamily, systemFamilyOfKind, templateCarriesSummary, templateVarDeliveryApplies, templateVarKindApplies, templateVarSystemEventApplies, withSystemEventClasses };
32208
+ export { APPLE_SA_TO_MACRO, AUDIO_MACRO_LABELS, AlarmArmModeSchema, CLIP_BROKER_PACED_RATES, COCO_TO_MACRO, CamProfileSchema, DEFAULT_TIMELAPSE_PREVIEW_TEXT, DEFINITIVE_DEVICE_REFUSALS, DEVICE_CERT_RENEW_WINDOW_DAYS, DEVICE_CERT_SIGNATURE, DEVICE_DEFINITIVE_REFUSALS_BEFORE_DELETE, DEVICE_REFRESH_REFUSAL_PREFIX, DEVICE_SIGNATURE_MESSAGE_VERSION, DeviceType, EVENTFUL_CAP_NAMES, EVENT_KIND_BY_CAP, EVENT_TAXONOMY, ICON_CATEGORIES, ICON_ENTRIES, ICON_KEYS, ICON_VIEWER_MODULES, IconKeySchema, LOCATION_ICON_FALLBACK, MACRO_LABELS, NC_ALARM_DELAY_MAX_SEC, NC_ALARM_SENSORS_MAX, NC_ALARM_SYSTEM_EVENT_KINDS, NC_ALARM_TRIGGERED_MAX_SEC, NC_BATTERY_CONSUMABLE_SYSTEM_EVENT_KINDS, NC_CAMERA_SCOPE_CAP_NAME, NC_CONSUMABLE_LOW_PERCENT_DEFAULT, NC_CONSUMABLE_LOW_PERCENT_MAX, NC_GROUPING_DEFAULT_SEC, NC_GROUPING_MAX_SEC, NC_GROUPING_MIN_SEC, NC_RULE_EDITOR_SECTION_ORDER, NC_RULE_KIND_SPECS, NC_SENSOR_TRANSITION_UNSUPPORTED_REASON, NC_SYSTEM_EVENT_CLASS_SPECS, NC_SYSTEM_EVENT_FAMILY_FILTERS, NC_SYSTEM_EVENT_KIND_GROUP_SPECS, NC_SYSTEM_EVENT_SUMMARY_FAMILIES, NC_TEMPLATE_HELD_BACK_SYSTEM_EVENT_KINDS, NC_TEMPLATE_VARS, NcAlarmConfigSchema, NcAlarmSensorsSchema, NcAlarmSettingsPatchSchema, NcHistoryEntrySchema, NcRuleLastRunsSchema, NodeDirectorySchema, RECORDING_EXPORT_MAX_READ_BYTES, RETRAIN_REVIEW_ADJUSTED_IOU, RETRAIN_REVIEW_MATCH_IOU, RETRAIN_REVIEW_STATUSES, RETRAIN_REVISION_CONFLICT, SystemMirror, TIMELAPSE_DENSE_FLOOR_SEC, TimelapseRuleSchema, YAMNET_TO_MACRO, alarmDeviceBlocksArming, alarmDeviceSecureOnArm, alarmPatchLanded, buildDeviceEnrollmentLink, buildDeviceSignatureMessage, buildSubjectPath, bundledCamstack, canonicalIconKey, classifyRetrainReview, conditionVisibleForKind, createSystemProxy, deviceRefusalFromMessage, droppedConditionsForKind, expandSystemEventClasses, iconCategoryLabel, iconEntry, iconsInCategory, isDefinitiveDeviceRefusal, isDrawableSubjectPath, isHeldBackTemplateVar, isIconKey, isSystemRuleKind, kindsForDiscriminator, knownValues, locationIconKey, nodePickerItems, packagePickerItems, paintHex, paletteResultSchema, parseDeviceEnrollmentLink, parseRetrainRevisionConflict, pickerForCondition, pickerForRuleClasses, projectSubjectPath, resolveIconKey, resolveModeDelays, retrainBoxIou, retrainRevisionConflictMessage, ruleDeviceCompatCapNames, ruleEditorSectionsForKind, ruleGroupingApplies, ruleKindOf, ruleKindSpec, ruleSeedForSection, searchIcons, sensorTransitionNeverFires, sensorTransitionOffered, stateLabel, subjectPathSampleFromBox, subjectPathSvgPoints, summarizeReview, systemEventClassKinds, systemEventClassesFor, systemEventDeliveryProblems, systemEventFilterAppliesToAnyKind, systemEventKindsOfFamily, systemFamilyOfKind, templateCarriesSummary, templateVarDeliveryApplies, templateVarKindApplies, templateVarSystemEventApplies, withSystemEventClasses };
@@ -12,6 +12,7 @@ export declare const CompositionProblemCodeSchema: z.ZodEnum<{
12
12
  "kind-mismatch": "kind-mismatch";
13
13
  "may-be-null": "may-be-null";
14
14
  "missing-field": "missing-field";
15
+ "native-capability-replace": "native-capability-replace";
15
16
  "nested-field": "nested-field";
16
17
  "not-composable": "not-composable";
17
18
  "not-item-array": "not-item-array";
@@ -39,6 +40,7 @@ export declare const CompositionProblemSchema: z.ZodObject<{
39
40
  "kind-mismatch": "kind-mismatch";
40
41
  "may-be-null": "may-be-null";
41
42
  "missing-field": "missing-field";
43
+ "native-capability-replace": "native-capability-replace";
42
44
  "nested-field": "nested-field";
43
45
  "not-composable": "not-composable";
44
46
  "not-item-array": "not-item-array";
@@ -166,9 +168,11 @@ export type CompositionFieldPlan = z.infer<typeof CompositionFieldPlanSchema>;
166
168
  /** The key every record map, log line and graph node uses for a planned field. Two items' `status` are two keys. */
167
169
  export declare function compositionFieldKey(plan: Pick<CompositionFieldPlan, 'cap' | 'path' | 'item'>): string;
168
170
  /**
169
- * What a feature does to its target (D663): `new` builds a capability on a new
170
- * device; on an existing device it `add`s a capability the device lacks, or
171
- * `replace`s named fields of one it has natively.
171
+ * What a feature does to its target (D663, D944): `new` builds a capability on a
172
+ * new device; on an existing device it `add`s a capability the device lacks.
173
+ * Replacing a capability the device already serves is refused
174
+ * (`native-capability-replace`), not planned. `replace` remains on the claim
175
+ * wire for a claim the hub already holds.
172
176
  */
173
177
  export declare const CompositionFeatureModeSchema: z.ZodEnum<{
174
178
  add: "add";
@@ -198,6 +202,7 @@ export declare const CompositionValidationSchema: z.ZodObject<{
198
202
  "kind-mismatch": "kind-mismatch";
199
203
  "may-be-null": "may-be-null";
200
204
  "missing-field": "missing-field";
205
+ "native-capability-replace": "native-capability-replace";
201
206
  "nested-field": "nested-field";
202
207
  "not-composable": "not-composable";
203
208
  "not-item-array": "not-item-array";
@@ -20,6 +20,6 @@ export declare function requiredTopLevelKeys(schema: z.ZodType): readonly string
20
20
  /**
21
21
  * The proper prefixes of `path` whose schema accepts `undefined`: a required
22
22
  * leaf under one of them is required only once something writes that parent
23
- * (`remaining.unit` is required only when `remaining` is present).
23
+ * (`remaining.kind` is required only when `remaining` is present).
24
24
  */
25
25
  export declare function optionalAncestors(schema: z.ZodType, path: string): readonly string[];
@@ -67,8 +67,9 @@ export type { CompositionPlanResult } from './plan-result.js';
67
67
  export declare const PENDING_BLOCK_ID = "(unsaved)";
68
68
  /**
69
69
  * The static plan. `target` describes an EXISTING target device (one read);
70
- * it is ignored for a new one. On an existing target each feature REPLACES a
71
- * cap the device has natively, else ADDS it (D663).
70
+ * it is ignored for a new one. On an existing target each feature ADDS a cap
71
+ * the device lacks. A feature that would replace a native capability is
72
+ * refused by name (D944). A new device is unchanged.
72
73
  */
73
74
  export declare function planComposition(composition: Composition, lookupCap: CapabilityLookup, target?: CompositionTargetDescription): CompositionPlanResult;
74
75
  export declare function compositionSourceRefs(composition: Composition): readonly CompositionSourceRef[];
@@ -179,9 +179,9 @@ export interface NumericStateTrigger<C extends VocabCapName> {
179
179
  /** The quantity WITH its article, as it reads in a sentence ("the temperature" / "la temperatura"). */
180
180
  readonly quantity: L10n;
181
181
  readonly label: L10n;
182
- /** Display unit; omit when the device states it (see `unitField`). */
182
+ /** Display unit. The stored number is the quantity base; this is the label. */
183
183
  readonly unit?: string;
184
- /** A status field carrying the device's own unit (`numeric-sensor.unit`). */
184
+ /** @deprecated D944 removed slice unit siblings. Kept so old rows still parse. */
185
185
  readonly unitField?: CapStatusField<C>;
186
186
  readonly icon: VocabIcon;
187
187
  }
@@ -1,8 +1,11 @@
1
1
  import { z } from 'zod';
2
+ import { type ReadingQuantity } from '../units/quantity.js';
2
3
  export interface WireableField {
3
4
  readonly path: string;
4
5
  readonly kind: 'string' | 'number' | 'boolean' | 'enum';
5
6
  readonly enumValues?: readonly string[];
7
+ /** Quantity of a numeric reading, when the schema declares one. */
8
+ readonly quantity?: ReadingQuantity;
6
9
  /** True when `path` is relative to ONE item of an item-array cap (see
7
10
  * `CapabilityStatusItemArray`) — a link targeting it must carry a
8
11
  * `target.itemKey`. Absent/false for plain status fields. */
@@ -17,12 +17,12 @@ import { z } from 'zod';
17
17
  * providers detect renames by matching `uniqueId` and patch `id`
18
18
  * in-place so dispatch keeps working.
19
19
  *
20
- * **Rendering metadata is NOT stored here.** Display fields (`unit`,
21
- * `precision`) live in the cap STATUS SLICE so they flow live with every
22
- * state push and are the single source of truth. The `device_class` tag is
23
- * an HA-specific input that is consumed at the discovery boundary
24
- * (`ha-domain-mapping`) to derive the CamStack `DeviceRole`; it is never
25
- * stored after that point.
20
+ * **Display unit and precision are NOT stored here.** They are a read-time
21
+ * preference (D944). A polymorphic reading stores its `quantity` here once,
22
+ * at adopt, and a date/time value stores `dateTimeShape` the same way —
23
+ * neither is repeated on each sample. The `device_class` tag is an
24
+ * HA-specific input consumed at the discovery boundary (`ha-domain-mapping`)
25
+ * to derive the CamStack `DeviceRole`; it is never stored after that point.
26
26
  *
27
27
  * The `raw` escape hatch carries provider-specific attributes that don't
28
28
  * fit the structured slots (HA `attributes` whitelist, Reolink `deviceCache`
@@ -32,6 +32,12 @@ export declare const SourceInfoSchema: z.ZodObject<{
32
32
  id: z.ZodString;
33
33
  system: z.ZodString;
34
34
  uniqueId: z.ZodOptional<z.ZodString>;
35
+ quantity: z.ZodOptional<z.ZodType<"angle" | "apparent-power" | "area" | "bitrate" | "colour-temperature" | "concentration-mass" | "concentration-ppb" | "concentration-volume" | "count" | "current" | "device" | "duration" | "duration-ms" | "energy" | "humidity" | "illuminance" | "index" | "information" | "irradiance" | "length" | "mass" | "none" | "percentage" | "power" | "precipitation" | "precipitation-rate" | "pressure" | "rate" | "ratio" | "signal-level" | "sound-level" | "speed" | "temperature" | "voltage" | "volume", unknown, z.core.$ZodTypeInternals<"angle" | "apparent-power" | "area" | "bitrate" | "colour-temperature" | "concentration-mass" | "concentration-ppb" | "concentration-volume" | "count" | "current" | "device" | "duration" | "duration-ms" | "energy" | "humidity" | "illuminance" | "index" | "information" | "irradiance" | "length" | "mass" | "none" | "percentage" | "power" | "precipitation" | "precipitation-rate" | "pressure" | "rate" | "ratio" | "signal-level" | "sound-level" | "speed" | "temperature" | "voltage" | "volume", unknown>>>;
36
+ dateTimeShape: z.ZodOptional<z.ZodEnum<{
37
+ date: "date";
38
+ datetime: "datetime";
39
+ time: "time";
40
+ }>>;
35
41
  raw: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
36
42
  }, z.core.$strip>;
37
43
  export type SourceInfo = z.infer<typeof SourceInfoSchema>;
@@ -5,7 +5,7 @@
5
5
  * `ALL_CAPABILITY_DEFINITIONS` (the whole Zod schema graph, ~+100 MB heap per
6
6
  * runner). See docs/decisions/adr-0028.md.
7
7
  *
8
- * Coverage: 1 advance-derived caps, 74 caps with 367 state leaves.
8
+ * Coverage: 1 advance-derived caps, 74 caps with 348 state leaves.
9
9
  */
10
10
  /** A bindable scalar in a capability's runtime state. */
11
11
  export interface CapStateLeaf {
@@ -1,26 +1,16 @@
1
1
  import { DeviceType } from '../device/device-type.js';
2
2
  /**
3
3
  * Customize catalog, projected from every `*.cap.ts` `customize` block.
4
- * 11 caps. Field keys are `runtimeState` paths. No Zod.
4
+ * 5 caps. Field keys are `runtimeState` paths. No Zod.
5
5
  */
6
6
  export declare const CAP_CUSTOMIZE_CATALOG: {
7
- readonly 'ambient-light-sensor': {
8
- readonly version: 1;
9
- readonly targets: readonly [];
10
- readonly advancedParameters: readonly [{
11
- readonly path: 'lux';
12
- readonly kind: 'number';
13
- readonly label: 'Illuminance';
14
- readonly unit: 'lx';
15
- }];
16
- };
17
7
  readonly battery: {
18
8
  readonly version: 1;
19
9
  readonly targets: readonly [{
20
10
  readonly id: 'percentage';
21
11
  readonly cardinality: 'scalar';
22
12
  readonly deviceTypes: readonly [DeviceType.Camera, DeviceType.Sensor, DeviceType.Button, DeviceType.Switch, DeviceType.PetFeeder, DeviceType.Container, DeviceType.Thermostat];
23
- readonly apply: 'add-or-replace';
13
+ readonly apply: 'add';
24
14
  readonly vocabularyCap: 'battery';
25
15
  readonly vocabularyStateField: 'percentage';
26
16
  readonly sources: readonly [{
@@ -60,29 +50,6 @@ export declare const CAP_CUSTOMIZE_CATALOG: {
60
50
  readonly when: 'add';
61
51
  }];
62
52
  }];
63
- readonly advancedParameters: readonly [{
64
- readonly path: 'binary';
65
- readonly kind: 'boolean';
66
- readonly label: 'Binary indicator';
67
- }, {
68
- readonly path: 'charging';
69
- readonly kind: 'enum';
70
- readonly label: 'Charging source';
71
- readonly enumValues: readonly ["dc", "solar", "none", "unknown"];
72
- }, {
73
- readonly path: 'sleeping';
74
- readonly kind: 'boolean';
75
- readonly label: 'Sleeping';
76
- }];
77
- };
78
- readonly binary: {
79
- readonly version: 1;
80
- readonly targets: readonly [];
81
- readonly advancedParameters: readonly [{
82
- readonly path: 'on';
83
- readonly kind: 'boolean';
84
- readonly label: 'On';
85
- }];
86
53
  };
87
54
  readonly consumables: {
88
55
  readonly version: 1;
@@ -130,8 +97,8 @@ export declare const CAP_CUSTOMIZE_CATALOG: {
130
97
  }];
131
98
  }];
132
99
  readonly literals: readonly [{
133
- readonly path: 'remaining.unit';
134
- readonly values: readonly ["days", "hours", "cycles"];
100
+ readonly path: 'remaining.kind';
101
+ readonly values: readonly ["duration", "count"];
135
102
  }];
136
103
  }, {
137
104
  readonly path: 'status';
@@ -167,7 +134,6 @@ export declare const CAP_CUSTOMIZE_CATALOG: {
167
134
  readonly when: 'add';
168
135
  }];
169
136
  }];
170
- readonly advancedParameters: readonly [];
171
137
  };
172
138
  readonly doorbell: {
173
139
  readonly version: 1;
@@ -204,17 +170,6 @@ export declare const CAP_CUSTOMIZE_CATALOG: {
204
170
  readonly highWater: 'composer-advance';
205
171
  readonly debounceMs: 2000;
206
172
  }];
207
- readonly advancedParameters: readonly [];
208
- };
209
- readonly 'humidity-sensor': {
210
- readonly version: 1;
211
- readonly targets: readonly [];
212
- readonly advancedParameters: readonly [{
213
- readonly path: 'percent';
214
- readonly kind: 'number';
215
- readonly label: 'Humidity';
216
- readonly unit: '%';
217
- }];
218
173
  };
219
174
  readonly motion: {
220
175
  readonly version: 1;
@@ -222,7 +177,7 @@ export declare const CAP_CUSTOMIZE_CATALOG: {
222
177
  readonly id: 'detected';
223
178
  readonly cardinality: 'event';
224
179
  readonly deviceTypes: readonly [DeviceType.Camera];
225
- readonly apply: 'replace';
180
+ readonly apply: 'add';
226
181
  readonly vocabularyCap: 'motion';
227
182
  readonly vocabularyEvent: 'onMotionChanged';
228
183
  readonly sources: readonly [{
@@ -250,22 +205,6 @@ export declare const CAP_CUSTOMIZE_CATALOG: {
250
205
  readonly timeoutMs: 30000;
251
206
  readonly sourceModes: readonly ["in-addition", "confirm", "replace"];
252
207
  }];
253
- readonly advancedParameters: readonly [];
254
- };
255
- readonly 'power-meter': {
256
- readonly version: 1;
257
- readonly targets: readonly [];
258
- readonly advancedParameters: readonly [{
259
- readonly path: 'kwhTotal';
260
- readonly kind: 'number';
261
- readonly label: 'Energy';
262
- readonly unit: 'kWh';
263
- }, {
264
- readonly path: 'watts';
265
- readonly kind: 'number';
266
- readonly label: 'Power';
267
- readonly unit: 'W';
268
- }];
269
208
  };
270
209
  readonly 'running-state': {
271
210
  readonly version: 1;
@@ -273,7 +212,7 @@ export declare const CAP_CUSTOMIZE_CATALOG: {
273
212
  readonly id: 'running';
274
213
  readonly cardinality: 'scalar';
275
214
  readonly deviceTypes: readonly [DeviceType.Dishwasher, DeviceType.Vacuum, DeviceType.LawnMower, DeviceType.MediaPlayer, DeviceType.WaterHeater, DeviceType.Humidifier, DeviceType.Fan, DeviceType.Climate, DeviceType.Thermostat, DeviceType.PetFeeder];
276
- readonly apply: 'add-or-replace';
215
+ readonly apply: 'add';
277
216
  readonly vocabularyCap: 'running-state';
278
217
  readonly vocabularyStateField: 'running';
279
218
  readonly sources: readonly [{
@@ -334,25 +273,10 @@ export declare const CAP_CUSTOMIZE_CATALOG: {
334
273
  readonly sourceChangedAt: 'prefer';
335
274
  }];
336
275
  }];
337
- readonly advancedParameters: readonly [];
338
- };
339
- readonly switch: {
340
- readonly version: 1;
341
- readonly targets: readonly [];
342
- readonly advancedParameters: readonly [{
343
- readonly path: 'on';
344
- readonly kind: 'boolean';
345
- readonly label: 'On';
346
- }];
347
- };
348
- readonly 'temperature-sensor': {
349
- readonly version: 1;
350
- readonly targets: readonly [];
351
- readonly advancedParameters: readonly [{
352
- readonly path: 'celsius';
353
- readonly kind: 'number';
354
- readonly label: 'Temperature';
355
- readonly unit: '°C';
356
- }];
357
276
  };
358
277
  };
278
+ /**
279
+ * Unit meta on runtime-state fields. The composed-device row reads this;
280
+ * it is not an override list (D944).
281
+ */
282
+ export declare const CAP_RUNTIME_FIELD_UNITS: Readonly<Record<string, Readonly<Record<string, string>>>>;
@@ -1,7 +1,7 @@
1
1
  import type { CapabilityHistoryField, CapabilityHistoryItems } from '../capabilities/capability-definition.js';
2
2
  /**
3
3
  * Cap history catalog, projected from every `*.cap.ts` `history` block.
4
- * 41 caps with series (74 series), 30 caps answered `'none'`.
4
+ * 41 caps with series (75 series), 30 caps answered `'none'`.
5
5
  * Field keys are `runtimeState` paths (`a.b` into fixed objects only).
6
6
  */
7
7
  export declare const HISTORY_CATALOG: Readonly<Record<string, Readonly<Record<string, CapabilityHistoryField>>>>;