@camstack/types 1.2.422 → 1.2.424

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 (47) hide show
  1. package/dist/addon.js +1 -1
  2. package/dist/addon.mjs +1 -1
  3. package/dist/capabilities/composer.cap.d.ts +6 -0
  4. package/dist/capabilities/core-blocks.cap.d.ts +43 -0
  5. package/dist/capabilities/group-active.cap.d.ts +46 -0
  6. package/dist/capabilities/group-commands.cap.d.ts +1 -1
  7. package/dist/capabilities/group-status.cap.d.ts +1 -1
  8. package/dist/capabilities/index.d.ts +3 -1
  9. package/dist/capabilities/lock-control.cap.d.ts +1 -0
  10. package/dist/capabilities/notification-rules.cap.d.ts +12 -0
  11. package/dist/capabilities/switch.cap.d.ts +1 -1
  12. package/dist/client.js +17 -1
  13. package/dist/client.mjs +17 -1
  14. package/dist/composition/composition-report.d.ts +2 -0
  15. package/dist/composition/composition.d.ts +9 -0
  16. package/dist/composition/helpers/actuator-methods.d.ts +39 -0
  17. package/dist/composition/helpers/aggregate.d.ts +2 -0
  18. package/dist/composition/helpers/catalog.d.ts +7 -1
  19. package/dist/composition/helpers/compile-history.d.ts +16 -1
  20. package/dist/composition/helpers/compile-math.d.ts +9 -0
  21. package/dist/composition/helpers/history-math.d.ts +8 -0
  22. package/dist/composition/helpers/index.d.ts +6 -4
  23. package/dist/composition/helpers/source-pick.d.ts +8 -1
  24. package/dist/composition/helpers/spec.d.ts +49 -3
  25. package/dist/{composition-CpETZ4HL.mjs → composition-Bb8iwHEJ.mjs} +175 -5
  26. package/dist/{composition-CPRAP41h.js → composition-CpAc0YfQ.js} +228 -4
  27. package/dist/device/cap-vocabulary/entries/sensors.d.ts +1 -1
  28. package/dist/expression/builtins.d.ts +11 -2
  29. package/dist/expression/expression-source.d.ts +6 -1
  30. package/dist/generated/addon-api.d.ts +14 -0
  31. package/dist/generated/addon-cap-facts.d.ts +1 -1
  32. package/dist/generated/cap-status-types.d.ts +3 -1
  33. package/dist/generated/capability-router-map.d.ts +5 -2
  34. package/dist/generated/device-local-state.d.ts +3 -0
  35. package/dist/generated/device-proxy.d.ts +3 -0
  36. package/dist/generated/device-scoped-caps.d.ts +1 -1
  37. package/dist/generated/history-catalog.d.ts +1 -1
  38. package/dist/generated/method-access-map.d.ts +1 -1
  39. package/dist/generated/method-device-selectors.d.ts +1 -1
  40. package/dist/generated/runtime-state-durability.d.ts +1 -1
  41. package/dist/index.js +648 -34
  42. package/dist/index.mjs +625 -35
  43. package/dist/node.js +1 -1
  44. package/dist/node.mjs +1 -1
  45. package/dist/{sleep-0sD_LHLI.mjs → sleep--jXS9hWo.mjs} +10 -1
  46. package/dist/{sleep-CEKGW7A5.js → sleep-edKiOXLo.js} +10 -1
  47. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -23833,7 +23833,20 @@ var NcRuleInputSchema = zod.z.object({
23833
23833
  * save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
23834
23834
  * path does not run Zod defaults.
23835
23835
  */
23836
- groupingSec: zod.z.number().int().min(5).max(60).optional()
23836
+ groupingSec: zod.z.number().int().min(5).max(60).optional(),
23837
+ /**
23838
+ * ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
23839
+ * carries "Correct" / "Wrong" buttons (and, where the channel has room, a
23840
+ * "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
23841
+ * same mark the Library writes, and records whose notification it was and
23842
+ * when. A channel with no buttons gets the same two choices as links.
23843
+ *
23844
+ * `.optional()`, never `.default()` (a Zod default does not run on the addon
23845
+ * cap path): absent and `false` both mean off, which is what every rule
23846
+ * authored before this field meant. An editor turns it off by writing
23847
+ * `false`, so it needs no `clear` key.
23848
+ */
23849
+ askVerdict: zod.z.boolean().optional()
23837
23850
  });
23838
23851
  /**
23839
23852
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -26834,6 +26847,7 @@ function createDeviceProxy(api, binding, opts) {
26834
26847
  const featureProbeInterface = { getStatus: (input) => dispatch("feature-probe", "featureProbe", "getStatus", "query", input) };
26835
26848
  const floodInterface = { getStatus: (input) => dispatch("flood", "flood", "getStatus", "query", input) };
26836
26849
  const gasInterface = { getStatus: (input) => dispatch("gas", "gas", "getStatus", "query", input) };
26850
+ const groupActiveInterface = { getStatus: (input) => dispatch("group-active", "groupActive", "getStatus", "query", input) };
26837
26851
  const groupCommandsInterface = { getStatus: (input) => dispatch("group-commands", "groupCommands", "getStatus", "query", input) };
26838
26852
  const groupStatusInterface = { getStatus: (input) => dispatch("group-status", "groupStatus", "getStatus", "query", input) };
26839
26853
  const heatingValveInterface = { getStatus: (input) => dispatch("heating-valve", "heatingValve", "getStatus", "query", input) };
@@ -27391,6 +27405,7 @@ function createDeviceProxy(api, binding, opts) {
27391
27405
  featureProbe: createSliceHandle(stateSource, binding.deviceId, "feature-probe"),
27392
27406
  flood: createSliceHandle(stateSource, binding.deviceId, "flood"),
27393
27407
  gas: createSliceHandle(stateSource, binding.deviceId, "gas"),
27408
+ groupActive: createSliceHandle(stateSource, binding.deviceId, "group-active"),
27394
27409
  groupCommands: createSliceHandle(stateSource, binding.deviceId, "group-commands"),
27395
27410
  groupStatus: createSliceHandle(stateSource, binding.deviceId, "group-status"),
27396
27411
  heatingValve: createSliceHandle(stateSource, binding.deviceId, "heating-valve"),
@@ -27477,6 +27492,7 @@ function createDeviceProxy(api, binding, opts) {
27477
27492
  ...bound("feature-probe") ? { featureProbe: featureProbeInterface } : {},
27478
27493
  ...bound("flood") ? { flood: floodInterface } : {},
27479
27494
  ...bound("gas") ? { gas: gasInterface } : {},
27495
+ ...bound("group-active") ? { groupActive: groupActiveInterface } : {},
27480
27496
  ...bound("group-commands") ? { groupCommands: groupCommandsInterface } : {},
27481
27497
  ...bound("group-status") ? { groupStatus: groupStatusInterface } : {},
27482
27498
  ...bound("heating-valve") ? { heatingValve: heatingValveInterface } : {},
package/dist/client.mjs CHANGED
@@ -23832,7 +23832,20 @@ var NcRuleInputSchema = z.object({
23832
23832
  * save by the hub's grouping guard). `.optional()`, never `.default()`: the addon cap
23833
23833
  * path does not run Zod defaults.
23834
23834
  */
23835
- groupingSec: z.number().int().min(5).max(60).optional()
23835
+ groupingSec: z.number().int().min(5).max(60).optional(),
23836
+ /**
23837
+ * ASK ME TO CONFIRM DETECTIONS (#243): a DETECTION notification of this rule
23838
+ * carries "Correct" / "Wrong" buttons (and, where the channel has room, a
23839
+ * "Wrong, it is a <class>" choice). A tap marks the track for retraining, the
23840
+ * same mark the Library writes, and records whose notification it was and
23841
+ * when. A channel with no buttons gets the same two choices as links.
23842
+ *
23843
+ * `.optional()`, never `.default()` (a Zod default does not run on the addon
23844
+ * cap path): absent and `false` both mean off, which is what every rule
23845
+ * authored before this field meant. An editor turns it off by writing
23846
+ * `false`, so it needs no `clear` key.
23847
+ */
23848
+ askVerdict: z.boolean().optional()
23836
23849
  });
23837
23850
  /**
23838
23851
  * Partial patch for `updateRule` — any subset of the input fields, plus the
@@ -26833,6 +26846,7 @@ function createDeviceProxy(api, binding, opts) {
26833
26846
  const featureProbeInterface = { getStatus: (input) => dispatch("feature-probe", "featureProbe", "getStatus", "query", input) };
26834
26847
  const floodInterface = { getStatus: (input) => dispatch("flood", "flood", "getStatus", "query", input) };
26835
26848
  const gasInterface = { getStatus: (input) => dispatch("gas", "gas", "getStatus", "query", input) };
26849
+ const groupActiveInterface = { getStatus: (input) => dispatch("group-active", "groupActive", "getStatus", "query", input) };
26836
26850
  const groupCommandsInterface = { getStatus: (input) => dispatch("group-commands", "groupCommands", "getStatus", "query", input) };
26837
26851
  const groupStatusInterface = { getStatus: (input) => dispatch("group-status", "groupStatus", "getStatus", "query", input) };
26838
26852
  const heatingValveInterface = { getStatus: (input) => dispatch("heating-valve", "heatingValve", "getStatus", "query", input) };
@@ -27390,6 +27404,7 @@ function createDeviceProxy(api, binding, opts) {
27390
27404
  featureProbe: createSliceHandle(stateSource, binding.deviceId, "feature-probe"),
27391
27405
  flood: createSliceHandle(stateSource, binding.deviceId, "flood"),
27392
27406
  gas: createSliceHandle(stateSource, binding.deviceId, "gas"),
27407
+ groupActive: createSliceHandle(stateSource, binding.deviceId, "group-active"),
27393
27408
  groupCommands: createSliceHandle(stateSource, binding.deviceId, "group-commands"),
27394
27409
  groupStatus: createSliceHandle(stateSource, binding.deviceId, "group-status"),
27395
27410
  heatingValve: createSliceHandle(stateSource, binding.deviceId, "heating-valve"),
@@ -27476,6 +27491,7 @@ function createDeviceProxy(api, binding, opts) {
27476
27491
  ...bound("feature-probe") ? { featureProbe: featureProbeInterface } : {},
27477
27492
  ...bound("flood") ? { flood: floodInterface } : {},
27478
27493
  ...bound("gas") ? { gas: gasInterface } : {},
27494
+ ...bound("group-active") ? { groupActive: groupActiveInterface } : {},
27479
27495
  ...bound("group-commands") ? { groupCommands: groupCommandsInterface } : {},
27480
27496
  ...bound("group-status") ? { groupStatus: groupStatusInterface } : {},
27481
27497
  ...bound("heating-valve") ? { heatingValve: heatingValveInterface } : {},
@@ -183,6 +183,7 @@ export declare const CompositionFieldPlanSchema: z.ZodObject<{
183
183
  cap: z.ZodString;
184
184
  fieldPath: z.ZodString;
185
185
  }, z.core.$strip>>;
186
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
186
187
  publish: z.ZodEnum<{
187
188
  excluded: "excluded";
188
189
  included: "included";
@@ -361,6 +362,7 @@ export declare const CompositionValidationSchema: z.ZodObject<{
361
362
  cap: z.ZodString;
362
363
  fieldPath: z.ZodString;
363
364
  }, z.core.$strip>>;
365
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
364
366
  publish: z.ZodEnum<{
365
367
  excluded: "excluded";
366
368
  included: "included";
@@ -128,6 +128,7 @@ export declare const CompositionAggregateSourceSchema: z.ZodObject<{
128
128
  cap: z.ZodString;
129
129
  fieldPath: z.ZodString;
130
130
  }, z.core.$strip>>;
131
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
131
132
  publish: z.ZodEnum<{
132
133
  excluded: "excluded";
133
134
  included: "included";
@@ -213,6 +214,7 @@ export declare const CompositionFieldSourceSchema: z.ZodDiscriminatedUnion<[z.Zo
213
214
  cap: z.ZodString;
214
215
  fieldPath: z.ZodString;
215
216
  }, z.core.$strip>>;
217
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
216
218
  publish: z.ZodEnum<{
217
219
  excluded: "excluded";
218
220
  included: "included";
@@ -328,6 +330,7 @@ export declare const CompositionItemEntrySchema: z.ZodObject<{
328
330
  cap: z.ZodString;
329
331
  fieldPath: z.ZodString;
330
332
  }, z.core.$strip>>;
333
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
331
334
  publish: z.ZodEnum<{
332
335
  excluded: "excluded";
333
336
  included: "included";
@@ -412,6 +415,7 @@ export declare const CompositionFieldsFeatureSchema: z.ZodObject<{
412
415
  cap: z.ZodString;
413
416
  fieldPath: z.ZodString;
414
417
  }, z.core.$strip>>;
418
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
415
419
  publish: z.ZodEnum<{
416
420
  excluded: "excluded";
417
421
  included: "included";
@@ -492,6 +496,7 @@ export declare const CompositionFieldsFeatureSchema: z.ZodObject<{
492
496
  cap: z.ZodString;
493
497
  fieldPath: z.ZodString;
494
498
  }, z.core.$strip>>;
499
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
495
500
  publish: z.ZodEnum<{
496
501
  excluded: "excluded";
497
502
  included: "included";
@@ -600,6 +605,7 @@ export declare const CompositionFeatureSchema: z.ZodDiscriminatedUnion<[z.ZodObj
600
605
  cap: z.ZodString;
601
606
  fieldPath: z.ZodString;
602
607
  }, z.core.$strip>>;
608
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
603
609
  publish: z.ZodEnum<{
604
610
  excluded: "excluded";
605
611
  included: "included";
@@ -680,6 +686,7 @@ export declare const CompositionFeatureSchema: z.ZodDiscriminatedUnion<[z.ZodObj
680
686
  cap: z.ZodString;
681
687
  fieldPath: z.ZodString;
682
688
  }, z.core.$strip>>;
689
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
683
690
  publish: z.ZodEnum<{
684
691
  excluded: "excluded";
685
692
  included: "included";
@@ -830,6 +837,7 @@ export declare const CompositionSchema: z.ZodObject<{
830
837
  cap: z.ZodString;
831
838
  fieldPath: z.ZodString;
832
839
  }, z.core.$strip>>;
840
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
833
841
  publish: z.ZodEnum<{
834
842
  excluded: "excluded";
835
843
  included: "included";
@@ -910,6 +918,7 @@ export declare const CompositionSchema: z.ZodObject<{
910
918
  cap: z.ZodString;
911
919
  fieldPath: z.ZodString;
912
920
  }, z.core.$strip>>;
921
+ activeWhen: z.ZodOptional<z.ZodArray<z.ZodString>>;
913
922
  publish: z.ZodEnum<{
914
923
  excluded: "excluded";
915
924
  included: "included";
@@ -0,0 +1,39 @@
1
+ /**
2
+ * One method table per actuator type (D944). A group offers a method only
3
+ * when every member can take it, so a command never reaches a member that
4
+ * lacks the surface: the cap must be bound by every member (the primary cap of
5
+ * the type is the exception — a member that lacks it is simply not commanded),
6
+ * and a row that names a device feature needs every member to advertise it.
7
+ * Offline does not remove a method: capability is the binding, not liveness.
8
+ */
9
+ import { DeviceFeature } from '../../device/device-type.js';
10
+ export declare const ACTUATOR_TEMPLATE_IDS: readonly ['switch', 'light', 'fan', 'cover', 'valve', 'lock', 'media-player', 'climate'];
11
+ export type ActuatorTemplateId = (typeof ACTUATOR_TEMPLATE_IDS)[number];
12
+ export interface ActuatorMethodRow {
13
+ readonly cap: string;
14
+ readonly method: string;
15
+ /** Every member must advertise this feature for the row to be shared. */
16
+ readonly requires: DeviceFeature | null;
17
+ /** The call must say `confirm: true`; the group refuses it otherwise. */
18
+ readonly confirm: boolean;
19
+ }
20
+ /** The first row's cap is the type's own: always offered, members without it are skipped. */
21
+ export declare const ACTUATOR_METHODS: Readonly<Record<ActuatorTemplateId, readonly ActuatorMethodRow[]>>;
22
+ export interface ActuatorMemberSurface {
23
+ readonly caps: readonly string[];
24
+ readonly features: readonly string[];
25
+ }
26
+ export declare function actuatorMethodRow(templateId: ActuatorTemplateId, cap: string, method: string): ActuatorMethodRow | null;
27
+ /**
28
+ * The rows every member can take. An empty member list shares nothing; the
29
+ * caller passes a surface for every member it could read, or none at all.
30
+ */
31
+ export declare function sharedActuatorMethods(templateId: ActuatorTemplateId, members: readonly ActuatorMemberSurface[]): readonly ActuatorMethodRow[];
32
+ /** The device features every member has, among those the table gates on, in table order. */
33
+ export declare function sharedActuatorFeatures(templateId: ActuatorTemplateId, featureLists: readonly (readonly string[])[]): readonly DeviceFeature[];
34
+ export declare const UNLOCK_CONFIRMATION: string;
35
+ /**
36
+ * Why a call must not be fanned out, or null. Only a confirmed row passes
37
+ * without `confirm: true`; anything else is the caller's to refuse by name.
38
+ */
39
+ export declare function methodRefusal(method: ActuatorMethodRow | null, args: Readonly<Record<string, unknown>>): string | null;
@@ -20,6 +20,8 @@ export interface AggregateCounts {
20
20
  export type AggregatePublish = 'value' | 'included' | 'excluded' | 'total';
21
21
  export type AggregateEmpty = 'null' | 'omit' | 'offline';
22
22
  export interface EvaluateAggregateInput {
23
+ /** Enum states that count as active, for a reducer over states instead of booleans. */
24
+ readonly activeWhen?: readonly string[];
23
25
  readonly reducer: AggregateReducer;
24
26
  readonly members: readonly AggregateReadResult[];
25
27
  readonly publish: AggregatePublish;
@@ -20,8 +20,14 @@ export interface GroupTemplate {
20
20
  readonly summary: string;
21
21
  readonly deviceType: DeviceType;
22
22
  readonly role: DeviceRole | undefined;
23
- /** Members are this one device type. */
23
+ /** Members are this one device type — or, for a climate group, one of a few. */
24
24
  readonly memberDeviceType: DeviceType;
25
+ readonly memberDeviceTypes: readonly DeviceType[];
26
+ /**
27
+ * Enum states of the member field that count as active. Set when the member
28
+ * field is a state rather than a yes/no (a cover is `open`, a lock `locked`).
29
+ */
30
+ readonly activeWhen: readonly string[] | undefined;
25
31
  readonly outputCap: string;
26
32
  readonly outputField: string;
27
33
  /**
@@ -1,12 +1,27 @@
1
1
  import type { CompositionProblem } from '../composition-report.js';
2
2
  import type { SeriesKind } from './history-math.js';
3
3
  import { type HistoryRetention } from './history-window.js';
4
- import type { HelperMember, IntegralHelperSpec, StatisticHelperSpec } from './spec.js';
4
+ import type { DerivativeHelperSpec, HelperMember, IntegralHelperSpec, StatisticHelperSpec } from './spec.js';
5
+ /**
6
+ * The unit of a rate: the source series' unit per second, minute or hour
7
+ * (`°C/h`). A source with no unit of its own (a generic number) has none to
8
+ * borrow, so the label is null and the chart shows the bare number.
9
+ */
10
+ export declare function derivativeUnitLabel(spec: DerivativeHelperSpec): string | null;
5
11
  export declare function declaredSeriesKind(member: HelperMember): SeriesKind | 'enum' | null;
6
12
  export declare function statisticDraft(spec: StatisticHelperSpec, retention?: HistoryRetention): {
7
13
  readonly draft: unknown;
8
14
  readonly problems: readonly CompositionProblem[];
9
15
  };
16
+ /**
17
+ * A derivative reads a gauge or a counter and publishes its rate per second,
18
+ * minute or hour. The output is a plain number: a rate of a temperature is not
19
+ * a temperature, so the chart carries no inherited unit.
20
+ */
21
+ export declare function derivativeDraft(spec: DerivativeHelperSpec, retention?: HistoryRetention): {
22
+ readonly draft: unknown;
23
+ readonly problems: readonly CompositionProblem[];
24
+ };
10
25
  export declare function integralDraft(spec: IntegralHelperSpec, retention?: HistoryRetention): {
11
26
  readonly draft: unknown;
12
27
  readonly problems: readonly CompositionProblem[];
@@ -0,0 +1,9 @@
1
+ import type { CompositionProblem } from '../composition-report.js';
2
+ import type { ArithmeticHelperSpec, ExpressionHelperSpec, ThresholdHelperSpec } from './spec.js';
3
+ export interface MathDraft {
4
+ readonly draft: unknown;
5
+ readonly problems: readonly CompositionProblem[];
6
+ }
7
+ export declare function thresholdDraft(spec: ThresholdHelperSpec): MathDraft;
8
+ export declare function arithmeticDraft(spec: ArithmeticHelperSpec): MathDraft;
9
+ export declare function expressionDraft(spec: ExpressionHelperSpec): MathDraft;
@@ -37,3 +37,11 @@ export interface HistoryValue {
37
37
  export declare function evaluateStatistic(stat: StatisticStat, read: SeriesRead): HistoryValue;
38
38
  export type IntegralScale = 'energy-kwh' | 'per-second';
39
39
  export declare function integrateReading(read: SeriesRead, scale: IntegralScale): HistoryValue;
40
+ /**
41
+ * Rate of change over a window, per `perMs`. The slope is taken between the
42
+ * first and the last measured sample, so a hole inside the window neither
43
+ * counts as zero nor stretches the elapsed time. A gauge that reported
44
+ * nothing after the value held at the start is flat (rate 0); fewer than two
45
+ * samples and no held value is a known gap (D393).
46
+ */
47
+ export declare function evaluateDerivative(read: SeriesRead, perMs: number): HistoryValue;
@@ -1,12 +1,14 @@
1
+ export { ACTUATOR_METHODS, ACTUATOR_TEMPLATE_IDS, type ActuatorMemberSurface, type ActuatorMethodRow, type ActuatorTemplateId, actuatorMethodRow, methodRefusal, sharedActuatorFeatures, sharedActuatorMethods, UNLOCK_CONFIRMATION, } from './actuator-methods.js';
1
2
  export { FAN_OUT_CONCURRENCY, LIGHT_SHARED_CAPS, type FanOutCall, type FanOutFailed, type FanOutMember, type FanOutMemberResult, type FanOutOk, type LightSharedCap, activeForReducer, fanOutTargets, reducerForActive, runFanOut, sharedColorModes, sharedLightCaps, } from './actuator.js';
2
3
  export { type AggregateCounts, type AggregateEmpty, type AggregateOutcome, type AggregatePublish, type AggregateReadResult, type AggregateUnavailable, type AggregateValue, type EvaluateAggregateInput, evaluateAggregate, } from './aggregate.js';
3
4
  export { APPLIANCE_DEFAULTS, APPLIANCE_KINDS, APPLIANCE_TEMPLATE_ID, type ApplianceDefaults, type ApplianceKind, applianceDeviceType, isApplianceKind, sourcePickForAppliance, } from './appliance.js';
4
5
  export { type GroupTemplate, type HelperAccept, type HelperCompanion, GROUP_TEMPLATES, groupTemplate, } from './catalog.js';
5
6
  export { type HelperCompileResult, type HelperCompiled, type HelperRefused, compileHelper, sameHelperBody, templateDeviceType, } from './compile.js';
6
- export { declaredSeriesKind, integralDraft, statisticDraft } from './compile-history.js';
7
+ export { declaredSeriesKind, derivativeDraft, derivativeUnitLabel, integralDraft, statisticDraft, } from './compile-history.js';
8
+ export { arithmeticDraft, expressionDraft, thresholdDraft } from './compile-math.js';
7
9
  export { KWH_PER_WATT_MS, wattMillisecondsToKwh } from './energy.js';
8
- export { type HistoryValue, type IntegralScale, type SeriesBefore, type SeriesKind, type SeriesPoint, type SeriesRead, STATISTIC_STATS, SERIES_KINDS, evaluateStatistic, integrateReading, } from './history-math.js';
10
+ export { type HistoryValue, type IntegralScale, type SeriesBefore, type SeriesKind, type SeriesPoint, type SeriesRead, STATISTIC_STATS, SERIES_KINDS, evaluateDerivative, evaluateStatistic, integrateReading, } from './history-math.js';
9
11
  export { type CalendarPeriod, type CalendarWindow, type HistoryRetention, type HistoryTier, type HistoryTierPlan, type OpenRange, type ResetPeriod, type RollingSpan, type RollingWindow, type StatisticWindow, CALENDAR_PERIODS, CalendarWindowSchema, DAY_MS, DEFAULT_HISTORY_RETENTION, HISTORY_FAST_MS, HISTORY_SLOW_MS, HISTORY_TIERS, HOUR_MS, MINUTE_MS, MIN_CUSTOM_MINUTES, RESET_PERIODS, ROLLING_SPANS, RollingWindowSchema, StatisticWindowSchema, integralCadenceMs, maxDurationMs, nextLocalMidnight, openReset, openStatistic, planResetTier, planStatisticTier, rollingDurationMs, statisticCadenceMs, } from './history-window.js';
10
12
  export { type HelperMemberFact, helperSaveProblems, } from './save.js';
11
- export { type SourcePick, type SourcePickAccept, type SourcePickHistory, type SourcePickRequest, sourcePickForHistory, sourcePickForTemplate, } from './source-pick.js';
12
- export { ACTIVE_CRITERIA, AGGREGATE_REDUCERS, ActiveCriterionSchema, AggregateReducerSchema, BINARY_AGGREGATES, GROUP_TEMPLATE_IDS, ApplianceHelperSpecSchema, GroupHelperSpecSchema, GroupTemplateIdSchema, HelperMemberSchema, HelperSpecSchema, INTEGRAL_OUTPUTS, IntegralHelperSpecSchema, MAX_HELPER_MEMBERS, helperMembers, NUMERIC_AGGREGATES, StatisticHelperSpecSchema, type ActiveCriterion, type AggregateReducer, type BinaryAggregate, type ApplianceHelperSpec, type GroupHelperSpec, type GroupTemplateId, type HelperMember, type HelperSpec, type IntegralHelperSpec, type IntegralOutput, type NumericAggregate, type StatisticHelperSpec, type StatisticStat, } from './spec.js';
13
+ export { type SourcePick, type SourcePickAccept, type SourcePickHistory, type SourcePickRequest, type MathSourceKind, sourcePickForHistory, sourcePickForMath, sourcePickForTemplate, } from './source-pick.js';
14
+ export { ACTIVE_CRITERIA, AGGREGATE_REDUCERS, ActiveCriterionSchema, AggregateReducerSchema, BINARY_AGGREGATES, GROUP_TEMPLATE_IDS, ApplianceHelperSpecSchema, ARITHMETIC_OPS, ArithmeticHelperSpecSchema, DERIVATIVE_UNITS, DerivativeHelperSpecSchema, EXPRESSION_OUTPUTS, ExpressionHelperSpecSchema, ThresholdHelperSpecSchema, GroupHelperSpecSchema, GroupTemplateIdSchema, HelperMemberSchema, HelperSpecSchema, INTEGRAL_OUTPUTS, IntegralHelperSpecSchema, MAX_HELPER_MEMBERS, helperMembers, isHistoryHelper, NUMERIC_AGGREGATES, StatisticHelperSpecSchema, type ActiveCriterion, type AggregateReducer, type BinaryAggregate, type ApplianceHelperSpec, type ArithmeticHelperSpec, type ArithmeticOp, type DerivativeHelperSpec, type DerivativeUnit, type ExpressionHelperSpec, type ExpressionInput, type ExpressionOutput, type ThresholdHelperSpec, type GroupHelperSpec, type GroupTemplateId, type HelperMember, type HelperSpec, type HistoryHelperSpec, type IntegralHelperSpec, type IntegralOutput, type NumericAggregate, type StatisticHelperSpec, type StatisticStat, } from './spec.js';
@@ -9,7 +9,7 @@ import type { GroupTemplate } from './catalog.js';
9
9
  export interface SourcePickAccept {
10
10
  readonly cap: string;
11
11
  readonly fieldPath: string;
12
- readonly valueKind: 'number' | 'boolean';
12
+ readonly valueKind: 'number' | 'boolean' | 'state';
13
13
  }
14
14
  export interface SourcePickHistory {
15
15
  readonly required: boolean;
@@ -40,3 +40,10 @@ export interface SourcePick {
40
40
  export declare function sourcePickForTemplate(template: GroupTemplate): SourcePickRequest;
41
41
  /** A statistic or integral reads one field that declares history. */
42
42
  export declare function sourcePickForHistory(kind: 'statistic' | 'integral'): SourcePickRequest;
43
+ export type MathSourceKind = 'threshold' | 'sum' | 'difference' | 'ratio' | 'expression' | 'derivative';
44
+ /**
45
+ * What the input step asks the selector for a math helper. A threshold reads
46
+ * one number, a difference or a ratio two, a sum and an expression several.
47
+ * A derivative reads one historised number.
48
+ */
49
+ export declare function sourcePickForMath(kind: MathSourceKind): SourcePickRequest;
@@ -5,11 +5,11 @@
5
5
  import { z } from 'zod';
6
6
  import { APPLIANCE_TEMPLATE_ID } from './appliance.js';
7
7
  import { STATISTIC_STATS } from './history-math.js';
8
- import { type ResetPeriod, type StatisticWindow } from './history-window.js';
8
+ import { type ResetPeriod, type RollingWindow, type StatisticWindow } from './history-window.js';
9
9
  import { CompositionSourceRefSchema } from '../source-ref.js';
10
10
  /** A group may name more members than an expression call (the 16-arg cap). */
11
11
  export declare const MAX_HELPER_MEMBERS: number;
12
- export declare const GROUP_TEMPLATE_IDS: readonly ['temperature', 'humidity', 'pressure', 'illuminance', 'power', 'energy', 'battery', 'numeric', 'motion', 'contact', 'leak', 'smoke', 'occupancy', 'binary', 'switch', 'light'];
12
+ export declare const GROUP_TEMPLATE_IDS: readonly ['temperature', 'humidity', 'pressure', 'illuminance', 'power', 'energy', 'battery', 'numeric', 'motion', 'contact', 'leak', 'smoke', 'occupancy', 'binary', 'switch', 'light', 'fan', 'cover', 'valve', 'lock', 'media-player', 'climate'];
13
13
  export type GroupTemplateId = (typeof GROUP_TEMPLATE_IDS)[number];
14
14
  export declare const NUMERIC_AGGREGATES: readonly ['mean', 'median', 'min', 'max', 'sum'];
15
15
  export type NumericAggregate = (typeof NUMERIC_AGGREGATES)[number];
@@ -70,7 +70,53 @@ export type IntegralHelperSpec = {
70
70
  readonly source: HelperMember;
71
71
  };
72
72
  export declare const IntegralHelperSpecSchema: z.ZodType<IntegralHelperSpec>;
73
- export type HelperSpec = GroupHelperSpec | ApplianceHelperSpec | StatisticHelperSpec | IntegralHelperSpec;
73
+ /** Math (D944 phase 3). A reading in, a reading or a yes/no out. */
74
+ export type ThresholdHelperSpec = {
75
+ readonly kind: 'threshold';
76
+ readonly source: HelperMember;
77
+ /** The output turns on once the reading is at or above this. */
78
+ readonly high: number;
79
+ /** The output turns off once the reading is at or below this. `low <= high`. */
80
+ readonly low: number;
81
+ readonly onForMs: number;
82
+ readonly offForMs: number;
83
+ };
84
+ export declare const ThresholdHelperSpecSchema: z.ZodType<ThresholdHelperSpec>;
85
+ export declare const ARITHMETIC_OPS: readonly ['sum', 'difference', 'ratio'];
86
+ export type ArithmeticOp = (typeof ARITHMETIC_OPS)[number];
87
+ export type ArithmeticHelperSpec = {
88
+ readonly kind: 'arithmetic';
89
+ readonly op: ArithmeticOp;
90
+ /** Sum: two or more. Difference and ratio: exactly two, first minus / over second. */
91
+ readonly inputs: readonly HelperMember[];
92
+ };
93
+ export declare const ArithmeticHelperSpecSchema: z.ZodType<ArithmeticHelperSpec>;
94
+ export declare const EXPRESSION_OUTPUTS: readonly ['number', 'boolean'];
95
+ export type ExpressionOutput = (typeof EXPRESSION_OUTPUTS)[number];
96
+ export interface ExpressionInput {
97
+ readonly name: string;
98
+ readonly member: HelperMember;
99
+ }
100
+ export type ExpressionHelperSpec = {
101
+ readonly kind: 'expression';
102
+ readonly expr: string;
103
+ readonly inputs: readonly ExpressionInput[];
104
+ readonly output: ExpressionOutput;
105
+ };
106
+ export declare const ExpressionHelperSpecSchema: z.ZodType<ExpressionHelperSpec>;
107
+ export declare const DERIVATIVE_UNITS: readonly ['second', 'minute', 'hour'];
108
+ export type DerivativeUnit = (typeof DERIVATIVE_UNITS)[number];
109
+ export type DerivativeHelperSpec = {
110
+ readonly kind: 'derivative';
111
+ readonly window: RollingWindow;
112
+ readonly per: DerivativeUnit;
113
+ readonly source: HelperMember;
114
+ };
115
+ export declare const DerivativeHelperSpecSchema: z.ZodType<DerivativeHelperSpec>;
116
+ export type HelperSpec = GroupHelperSpec | ApplianceHelperSpec | StatisticHelperSpec | IntegralHelperSpec | ThresholdHelperSpec | ArithmeticHelperSpec | ExpressionHelperSpec | DerivativeHelperSpec;
74
117
  export declare const HelperSpecSchema: z.ZodType<HelperSpec>;
118
+ /** The kinds the composer runs from device history, on a schedule. */
119
+ export type HistoryHelperSpec = StatisticHelperSpec | IntegralHelperSpec | DerivativeHelperSpec;
120
+ export declare function isHistoryHelper(spec: HelperSpec): spec is HistoryHelperSpec;
75
121
  /** Every member a helper reads. A group has many; the others have one. */
76
122
  export declare function helperMembers(spec: HelperSpec): readonly HelperMember[];