@enyo-energy/energy-app-sdk 1.9.0 → 1.11.0

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 (34) hide show
  1. package/README.md +70 -1
  2. package/dist/cjs/implementations/appliances/appliance-manager.cjs +2 -0
  3. package/dist/cjs/implementations/appliances/appliance-manager.d.cts +4 -0
  4. package/dist/cjs/index.cjs +1 -0
  5. package/dist/cjs/index.d.cts +1 -0
  6. package/dist/cjs/packages/energy-app-timeseries.d.cts +30 -1
  7. package/dist/cjs/types/enyo-appliance.cjs +2 -0
  8. package/dist/cjs/types/enyo-appliance.d.cts +6 -1
  9. package/dist/cjs/types/enyo-data-bus-value.cjs +4 -0
  10. package/dist/cjs/types/enyo-data-bus-value.d.cts +114 -0
  11. package/dist/cjs/types/enyo-flexibility-announcement.cjs +40 -1
  12. package/dist/cjs/types/enyo-flexibility-announcement.d.cts +74 -0
  13. package/dist/cjs/types/enyo-smart-plug-appliance.cjs +74 -0
  14. package/dist/cjs/types/enyo-smart-plug-appliance.d.cts +173 -0
  15. package/dist/cjs/types/enyo-timeseries.d.cts +91 -0
  16. package/dist/cjs/version.cjs +1 -1
  17. package/dist/cjs/version.d.cts +1 -1
  18. package/dist/implementations/appliances/appliance-manager.d.ts +4 -0
  19. package/dist/implementations/appliances/appliance-manager.js +2 -0
  20. package/dist/index.d.ts +1 -0
  21. package/dist/index.js +1 -0
  22. package/dist/packages/energy-app-timeseries.d.ts +30 -1
  23. package/dist/types/enyo-appliance.d.ts +6 -1
  24. package/dist/types/enyo-appliance.js +2 -0
  25. package/dist/types/enyo-data-bus-value.d.ts +114 -0
  26. package/dist/types/enyo-data-bus-value.js +4 -0
  27. package/dist/types/enyo-flexibility-announcement.d.ts +74 -0
  28. package/dist/types/enyo-flexibility-announcement.js +39 -0
  29. package/dist/types/enyo-smart-plug-appliance.d.ts +173 -0
  30. package/dist/types/enyo-smart-plug-appliance.js +71 -0
  31. package/dist/types/enyo-timeseries.d.ts +91 -0
  32. package/dist/version.d.ts +1 -1
  33. package/dist/version.js +1 -1
  34. package/package.json +1 -1
package/README.md CHANGED
@@ -84,6 +84,7 @@ The official TypeScript SDK for building Energy Apps on the enyo platform. Creat
84
84
  - [Basic Energy App](#basic-energy-app)
85
85
  - [Device Integration](#device-integration)
86
86
  - [Data Bus Messaging](#data-bus-messaging)
87
+ - [Announcing Appliance Flexibility](#announcing-appliance-flexibility)
87
88
  - [Settings Management](#settings-management)
88
89
  - [Troubleshooting](#troubleshooting)
89
90
  - [External Libraries](#external-libraries)
@@ -1494,7 +1495,7 @@ Publishers need `PvSystemRegister`; consumers need `PvSystemUse`.
1494
1495
 
1495
1496
  #### `useTimeseries(): EnergyAppTimeseries`
1496
1497
 
1497
- Query historical 15-minute aggregated data across the energy domain (PV production, battery SoC / power, meter values, grid power, home consumption, heatpump electrical / thermal, air-conditioning, temperature sensors). Some endpoints also support 1-minute resolution.
1498
+ Query historical 15-minute aggregated data across the energy domain (PV production, battery SoC / power, meter values, grid power, home consumption, heatpump electrical / thermal, air-conditioning, temperature sensors, smart plugs). Some endpoints also support 1-minute resolution.
1498
1499
 
1499
1500
  ```typescript
1500
1501
  const ts = energyApp.useTimeseries();
@@ -3529,6 +3530,74 @@ energyApp.register(async (packageName, version) => {
3529
3530
  });
3530
3531
  ```
3531
3532
 
3533
+ #### Announcing Appliance Flexibility
3534
+
3535
+ An appliance tells the rest of the system how much energy it can shift, and
3536
+ until when, with `ApplianceFlexibilityAnnouncementV1`. Optionally it can also say
3537
+ **how much watt for what** — which part of the system the energy would go into —
3538
+ so the consumer of the announcement can reason about the demand behind the number
3539
+ instead of treating it as one opaque block.
3540
+
3541
+ The breakdown is a list of `EnyoFlexibilityTargetPower` entries under
3542
+ `data.flexibility.context.targets`. Each entry names a `EnyoFlexibilityTargetEnum`
3543
+ target, the power that share would draw in Watts, and optionally the share of the
3544
+ announced energy in kWh.
3545
+
3546
+ `EnyoFlexibilityTargetEnum` is an open vocabulary. Today it covers
3547
+ `domesticHotWater`, `bufferTank`, and `heating`, since thermal appliances are the
3548
+ first to split their draw — but it is not limited to thermal targets, and further
3549
+ members may describe non-thermal ones. Treat an unknown value as "some other
3550
+ target" rather than assuming it is a heat sink.
3551
+
3552
+ ```typescript
3553
+ import {
3554
+ EnergyApp,
3555
+ EnyoFlexibilityTargetEnum,
3556
+ } from '@enyo-energy/energy-app-sdk';
3557
+
3558
+ const energyApp = new EnergyApp();
3559
+ const dataBus = energyApp.useDataBus();
3560
+
3561
+ dataBus.sendMessage([{
3562
+ type: 'message',
3563
+ message: 'ApplianceFlexibilityAnnouncementV1',
3564
+ applianceId: 'heatpump-1',
3565
+ data: {
3566
+ flexibility: {
3567
+ // Authoritative total: 4 kWh can be shifted until 14:00.
3568
+ kWh: 4,
3569
+ availableUntilIsoTimestamp: '2025-10-01T14:00:00Z',
3570
+ // Optional: what those 4 kWh are for, and at which power.
3571
+ context: {
3572
+ targets: [
3573
+ {
3574
+ target: EnyoFlexibilityTargetEnum.DomesticHotWater,
3575
+ powerW: 1500,
3576
+ kWh: 2.5,
3577
+ },
3578
+ {
3579
+ target: EnyoFlexibilityTargetEnum.BufferTank,
3580
+ powerW: 800,
3581
+ kWh: 1.5,
3582
+ },
3583
+ ],
3584
+ },
3585
+ },
3586
+ },
3587
+ }]);
3588
+ ```
3589
+
3590
+ Notes:
3591
+
3592
+ - `context` is entirely optional — existing publishers that only send `kWh` and
3593
+ `availableUntilIsoTimestamp` stay valid.
3594
+ - The breakdown may be **partial**: its entries do not have to sum to `kWh` or to
3595
+ the appliance's full draw. Only `kWh` is authoritative.
3596
+ - A given target should appear at most once per breakdown.
3597
+ - The same breakdown is available on category-level announcements via
3598
+ `context.targets` on `EnyoFlexibilityAnnouncementContext`, so the
3599
+ per-appliance and aggregated surfaces stay in step.
3600
+
3532
3601
  ### Settings Management
3533
3602
 
3534
3603
  Dynamic configuration with user interface:
@@ -60,6 +60,7 @@ const MERGEABLE_METADATA_KEYS = [
60
60
  'temperatureSensor',
61
61
  'airConditioning',
62
62
  'heatingRod',
63
+ 'smartPlug',
63
64
  ];
64
65
  /**
65
66
  * Manages appliances in the energy system with configurable identification strategies.
@@ -209,6 +210,7 @@ class ApplianceManager {
209
210
  temperatureSensor: appliance.temperatureSensor,
210
211
  airConditioning: appliance.airConditioning,
211
212
  heatingRod: appliance.heatingRod,
213
+ smartPlug: appliance.smartPlug,
212
214
  // Conditionally spread the two optional top-level fields that are NOT
213
215
  // covered by MERGEABLE_METADATA_KEYS. If they were always materialized
214
216
  // as explicit keys, an omitted (undefined) value would clobber the
@@ -10,6 +10,7 @@ import type { EnyoMeterAppliance } from "../../types/enyo-meter-appliance.cjs";
10
10
  import type { EnyoTemperatureSensorApplianceMetadata } from "../../types/enyo-temperature-sensor-appliance.cjs";
11
11
  import type { EnyoAirConditioningApplianceMetadata } from "../../types/enyo-air-conditioning-appliance.cjs";
12
12
  import type { EnyoHeatingRodApplianceMetadata } from "../../types/enyo-heating-rod-appliance.cjs";
13
+ import type { EnyoSmartPlugApplianceMetadata } from "../../types/enyo-smart-plug-appliance.cjs";
13
14
  import { IdentifierStrategy } from "./identifier-strategies.cjs";
14
15
  /**
15
16
  * Thrown when {@link ApplianceManager.createOrUpdateAppliance} is called with
@@ -62,6 +63,7 @@ export interface ApplianceConfig {
62
63
  temperatureSensor?: EnyoTemperatureSensorApplianceMetadata;
63
64
  airConditioning?: EnyoAirConditioningApplianceMetadata;
64
65
  heatingRod?: EnyoHeatingRodApplianceMetadata;
66
+ smartPlug?: EnyoSmartPlugApplianceMetadata;
65
67
  availableFeatures?: EnyoApplianceAvailableFeaturesEnum[];
66
68
  /**
67
69
  * Optional identifier of the cloud-deployed energy app package that manages
@@ -437,6 +439,8 @@ export interface PartialEnyoAppliance {
437
439
  airConditioning?: Partial<EnyoAirConditioningApplianceMetadata>;
438
440
  /** Optional Metadata of the Appliance if of type HeatingRod */
439
441
  heatingRod?: Partial<EnyoHeatingRodApplianceMetadata>;
442
+ /** Optional Metadata of the Appliance if of type SmartPlug */
443
+ smartPlug?: Partial<EnyoSmartPlugApplianceMetadata>;
440
444
  /** Optional custom name for the appliance, defined by the user */
441
445
  customName?: string;
442
446
  /**
@@ -86,6 +86,7 @@ __exportStar(require("./types/enyo-configuration-manager.cjs"), exports);
86
86
  __exportStar(require("./packages/energy-app-configuration-manager.cjs"), exports);
87
87
  __exportStar(require("./types/enyo-air-conditioning-appliance.cjs"), exports);
88
88
  __exportStar(require("./types/enyo-heating-rod-appliance.cjs"), exports);
89
+ __exportStar(require("./types/enyo-smart-plug-appliance.cjs"), exports);
89
90
  __exportStar(require("./types/enyo-charger-appliance.cjs"), exports);
90
91
  __exportStar(require("./types/enyo-charging-card.cjs"), exports);
91
92
  __exportStar(require("./packages/energy-app-charging-card.cjs"), exports);
@@ -70,6 +70,7 @@ export * from './types/enyo-configuration-manager.cjs';
70
70
  export * from './packages/energy-app-configuration-manager.cjs';
71
71
  export * from './types/enyo-air-conditioning-appliance.cjs';
72
72
  export * from './types/enyo-heating-rod-appliance.cjs';
73
+ export * from './types/enyo-smart-plug-appliance.cjs';
73
74
  export * from './types/enyo-charger-appliance.cjs';
74
75
  export * from './types/enyo-charging-card.cjs';
75
76
  export * from './packages/energy-app-charging-card.cjs';
@@ -1,4 +1,4 @@
1
- import { DataBusMessageQueryRequest, DataBusMessageQueryResponse, PvProductionTimeseriesRequest, PvProductionTimeseriesResponse, BatterySocTimeseriesRequest, BatterySocTimeseriesResponse, BatteryPowerTimeseriesRequest, BatteryPowerTimeseriesResponse, MeterValuesTimeseriesRequest, MeterValuesTimeseriesResponse, GridPowerTimeseriesRequest, GridPowerTimeseriesResponse, HomeConsumptionTimeseriesRequest, HomeConsumptionTimeseriesResponse, HeatpumpTemperatureTimeseriesRequest, HeatpumpTemperatureTimeseriesResponse, HeatpumpPowerTimeseriesRequest, HeatpumpPowerTimeseriesResponse, TemperatureSensorTimeseriesRequest, TemperatureSensorTimeseriesResponse, AirConditioningPowerTimeseriesRequest, AirConditioningPowerTimeseriesResponse, AirConditioningTemperatureTimeseriesRequest, AirConditioningTemperatureTimeseriesResponse } from "../types/enyo-timeseries.cjs";
1
+ import { DataBusMessageQueryRequest, DataBusMessageQueryResponse, PvProductionTimeseriesRequest, PvProductionTimeseriesResponse, BatterySocTimeseriesRequest, BatterySocTimeseriesResponse, BatteryPowerTimeseriesRequest, BatteryPowerTimeseriesResponse, MeterValuesTimeseriesRequest, MeterValuesTimeseriesResponse, GridPowerTimeseriesRequest, GridPowerTimeseriesResponse, HomeConsumptionTimeseriesRequest, HomeConsumptionTimeseriesResponse, HeatpumpTemperatureTimeseriesRequest, HeatpumpTemperatureTimeseriesResponse, HeatpumpPowerTimeseriesRequest, HeatpumpPowerTimeseriesResponse, TemperatureSensorTimeseriesRequest, TemperatureSensorTimeseriesResponse, AirConditioningPowerTimeseriesRequest, AirConditioningPowerTimeseriesResponse, AirConditioningTemperatureTimeseriesRequest, AirConditioningTemperatureTimeseriesResponse, SmartPlugTimeseriesRequest, SmartPlugTimeseriesResponse } from "../types/enyo-timeseries.cjs";
2
2
  /**
3
3
  * Interface for querying historical energy data with configurable bucket granularity.
4
4
  * Provides methods to retrieve aggregated timeseries data for various energy metrics
@@ -253,4 +253,33 @@ export interface EnergyAppTimeseries {
253
253
  * ```
254
254
  */
255
255
  getAirConditioningTemperatureTimeseries(request: AirConditioningTemperatureTimeseriesRequest): Promise<AirConditioningTemperatureTimeseriesResponse>;
256
+ /**
257
+ * Retrieves smart plug timeseries data aggregated in time buckets.
258
+ *
259
+ * Every bucket carries the aggregate across all included plugs
260
+ * (`smartPlugPowerW` / `Wh`) plus a per-plug breakdown, since a plug measures
261
+ * an arbitrary load and the total alone does not say which load ran. The
262
+ * response additionally summarises each plug across the full period.
263
+ *
264
+ * Per-plug fields are optional because plug capabilities differ: a
265
+ * measure-only plug reports power but no runtime, a switch-only plug reports
266
+ * runtime (`onDurationMinutes`, `switchCount`) but no power.
267
+ *
268
+ * @param request - The query parameters including date range and optional appliance filter
269
+ * @returns Promise resolving to smart plug entries with the total and per-plug summaries
270
+ *
271
+ * @example
272
+ * ```typescript
273
+ * const response = await timeseries.getSmartPlugTimeseries({
274
+ * startDateIso: '2024-01-01T00:00:00Z',
275
+ * endDateIso: '2024-01-02T00:00:00Z'
276
+ * });
277
+ * console.log(`Total plug consumption: ${response.totalSmartPlugPowerWh} Wh`);
278
+ * response.plugs.forEach(plug => {
279
+ * console.log(`${plug.applianceId}: ${plug.totalPowerWh ?? 0} Wh, ` +
280
+ * `on for ${plug.totalOnDurationMinutes ?? 0} min`);
281
+ * });
282
+ * ```
283
+ */
284
+ getSmartPlugTimeseries(request: SmartPlugTimeseriesRequest): Promise<SmartPlugTimeseriesResponse>;
256
285
  }
@@ -11,6 +11,8 @@ var EnyoApplianceTypeEnum;
11
11
  EnyoApplianceTypeEnum["AirConditioning"] = "AirConditioning";
12
12
  EnyoApplianceTypeEnum["TemperatureSensor"] = "TemperatureSensor";
13
13
  EnyoApplianceTypeEnum["HeatingRod"] = "HeatingRod";
14
+ /** Switchable socket / relay channel powering an arbitrary load (e.g. a Shelly channel) */
15
+ EnyoApplianceTypeEnum["SmartPlug"] = "SmartPlug";
14
16
  })(EnyoApplianceTypeEnum || (exports.EnyoApplianceTypeEnum = EnyoApplianceTypeEnum = {}));
15
17
  var EnyoApplianceStateEnum;
16
18
  (function (EnyoApplianceStateEnum) {
@@ -8,6 +8,7 @@ import { EnyoMeterAppliance } from "./enyo-meter-appliance.cjs";
8
8
  import { EnyoTemperatureSensorApplianceMetadata } from "./enyo-temperature-sensor-appliance.cjs";
9
9
  import { EnyoAirConditioningApplianceMetadata } from "./enyo-air-conditioning-appliance.cjs";
10
10
  import { EnyoHeatingRodApplianceMetadata } from "./enyo-heating-rod-appliance.cjs";
11
+ import { EnyoSmartPlugApplianceMetadata } from "./enyo-smart-plug-appliance.cjs";
11
12
  export declare enum EnyoApplianceTypeEnum {
12
13
  Inverter = "Inverter",
13
14
  Charger = "Charger",
@@ -16,7 +17,9 @@ export declare enum EnyoApplianceTypeEnum {
16
17
  Heatpump = "Heatpump",
17
18
  AirConditioning = "AirConditioning",
18
19
  TemperatureSensor = "TemperatureSensor",
19
- HeatingRod = "HeatingRod"
20
+ HeatingRod = "HeatingRod",
21
+ /** Switchable socket / relay channel powering an arbitrary load (e.g. a Shelly channel) */
22
+ SmartPlug = "SmartPlug"
20
23
  }
21
24
  export interface EnyoApplianceName {
22
25
  language: EnergyAppPackageLanguage;
@@ -270,6 +273,8 @@ export interface EnyoAppliance {
270
273
  airConditioning?: EnyoAirConditioningApplianceMetadata;
271
274
  /** Optional Metadata of the Appliance if of type HeatingRod */
272
275
  heatingRod?: EnyoHeatingRodApplianceMetadata;
276
+ /** Optional Metadata of the Appliance if of type SmartPlug */
277
+ smartPlug?: EnyoSmartPlugApplianceMetadata;
273
278
  /** Optional custom name for the appliance, defined by the user */
274
279
  customName?: string;
275
280
  /**
@@ -280,6 +280,10 @@ var EnyoDataBusMessageEnum;
280
280
  EnyoDataBusMessageEnum["SetHeatingRodAvailablePowerV2"] = "SetHeatingRodAvailablePowerV2";
281
281
  /** V2 control command: prescribe a single-setpoint control (mode + direction + power) to a battery/storage appliance. */
282
282
  EnyoDataBusMessageEnum["SetStorageControlV2"] = "SetStorageControlV2";
283
+ /** Live values of a smart plug: relay state, power draw and energy meter reading. */
284
+ EnyoDataBusMessageEnum["SmartPlugValuesUpdateV1"] = "SmartPlugValuesUpdateV1";
285
+ /** Control command: switch a smart plug / relay channel on or off. */
286
+ EnyoDataBusMessageEnum["SetSmartPlugSwitchV1"] = "SetSmartPlugSwitchV1";
283
287
  EnyoDataBusMessageEnum["EnergyAppStartedV1"] = "EnergyAppStartedV1";
284
288
  })(EnyoDataBusMessageEnum || (exports.EnyoDataBusMessageEnum = EnyoDataBusMessageEnum = {}));
285
289
  /**
@@ -7,6 +7,8 @@ import { PreviewChargingSchedule, PreviewChargingScheduleCostComparison, Preview
7
7
  import { EnyoEnergyPrices } from "./enyo-energy-prices.cjs";
8
8
  import { EnyoCurrencyEnum } from "./enyo-currency.cjs";
9
9
  import { EnyoHeatpumpApplianceModeEnum } from "./enyo-heatpump-appliance.cjs";
10
+ import type { EnyoFlexibilityTargetPower } from "./enyo-flexibility-announcement.cjs";
11
+ import { EnyoSmartPlugApplianceStateEnum } from "./enyo-smart-plug-appliance.cjs";
10
12
  import { EnyoAirConditioningApplianceModeEnum, EnyoAirConditioningOptimizationModeEnum } from "./enyo-air-conditioning-appliance.cjs";
11
13
  import { EnergyAppPackageCategory } from "../energy-app-package-definition.cjs";
12
14
  import { EnyoPackageConfigurationTranslatedValue } from "./enyo-settings.cjs";
@@ -344,6 +346,10 @@ export declare enum EnyoDataBusMessageEnum {
344
346
  SetHeatingRodAvailablePowerV2 = "SetHeatingRodAvailablePowerV2",
345
347
  /** V2 control command: prescribe a single-setpoint control (mode + direction + power) to a battery/storage appliance. */
346
348
  SetStorageControlV2 = "SetStorageControlV2",
349
+ /** Live values of a smart plug: relay state, power draw and energy meter reading. */
350
+ SmartPlugValuesUpdateV1 = "SmartPlugValuesUpdateV1",
351
+ /** Control command: switch a smart plug / relay channel on or off. */
352
+ SetSmartPlugSwitchV1 = "SetSmartPlugSwitchV1",
347
353
  EnergyAppStartedV1 = "EnergyAppStartedV1"
348
354
  }
349
355
  export type EnyoDataBusMessageResolution = '1s' | '10s' | '30s' | '1m' | '15m' | '1h' | '1d' | 'dynamic';
@@ -574,6 +580,36 @@ export interface EnyoDataBusInverterValuesV1 extends EnyoDataBusMessage {
574
580
  gridOperatorLimit?: EnyoGridOperatorLimit;
575
581
  };
576
582
  }
583
+ /**
584
+ * An appliance announces how much energy it can shift, and until when.
585
+ *
586
+ * Optionally it can also say *what the energy is for and at which power* via
587
+ * `data.flexibility.context.targets` — e.g. a heat pump splitting its draw
588
+ * between the domestic hot water tank, the heating buffer tank, and the space
589
+ * heating circuit. That breakdown is additive context for the decision maker;
590
+ * `kWh` remains the authoritative total.
591
+ *
592
+ * @example
593
+ * ```typescript
594
+ * dataBus.sendMessage([{
595
+ * type: 'message',
596
+ * message: EnyoDataBusMessageEnum.ApplianceFlexibilityAnnouncementV1,
597
+ * applianceId: 'heatpump-1',
598
+ * data: {
599
+ * flexibility: {
600
+ * kWh: 4,
601
+ * availableUntilIsoTimestamp: '2025-10-01T14:00:00Z',
602
+ * context: {
603
+ * targets: [
604
+ * {target: EnyoFlexibilityTargetEnum.DomesticHotWater, powerW: 1500, kWh: 2.5},
605
+ * {target: EnyoFlexibilityTargetEnum.BufferTank, powerW: 800, kWh: 1.5},
606
+ * ],
607
+ * },
608
+ * },
609
+ * },
610
+ * }]);
611
+ * ```
612
+ */
577
613
  export interface EnyoDataBusApplianceFlexibilityAnnouncementV1 extends EnyoDataBusMessage {
578
614
  type: 'message';
579
615
  message: EnyoDataBusMessageEnum.ApplianceFlexibilityAnnouncementV1;
@@ -584,6 +620,19 @@ export interface EnyoDataBusApplianceFlexibilityAnnouncementV1 extends EnyoDataB
584
620
  kWh: number;
585
621
  /** Defines until the kWh flexibility can be shifted. If for Example 10 kWh can be shifted until 2025-10-01T14:00:00 (current time 2025-10-01T10:00:00), the control can shift the 10 kWh in the next 4 hours */
586
622
  availableUntilIsoTimestamp: string;
623
+ /**
624
+ * Optional extra context for the consumer of this announcement.
625
+ * Nested so further context keys can be added without changing the
626
+ * message shape again.
627
+ */
628
+ context?: {
629
+ /**
630
+ * Breakdown of what the announced flexibility is for and at which
631
+ * power. May be partial — entries need not sum to the appliance's
632
+ * full draw — and a given target SHOULD appear at most once.
633
+ */
634
+ targets: EnyoFlexibilityTargetPower[];
635
+ };
587
636
  };
588
637
  };
589
638
  }
@@ -2429,3 +2478,68 @@ export interface EnyoDataBusVehicleSocUpdateV1 extends EnyoDataBusMessage {
2429
2478
  batterySizeKwh?: number;
2430
2479
  };
2431
2480
  }
2481
+ /**
2482
+ * Live values of a smart plug / switchable relay channel, published by the
2483
+ * integration that owns the appliance.
2484
+ *
2485
+ * Send this whenever the relay state or the measured power changes, so an
2486
+ * energy manager can account for the load and decide whether to switch the plug
2487
+ * via {@link EnyoDataBusSetSmartPlugSwitchV1}.
2488
+ */
2489
+ export interface EnyoDataBusSmartPlugValuesV1 extends EnyoDataBusMessage {
2490
+ type: 'message';
2491
+ message: EnyoDataBusMessageEnum.SmartPlugValuesUpdateV1;
2492
+ /** ID of the smart plug appliance that delivered these values */
2493
+ applianceId: string;
2494
+ data: {
2495
+ /**
2496
+ * Current relay state of the plug. Omit when the integration cannot
2497
+ * determine it — `undefined` means "not known", which is not the same
2498
+ * as {@link EnyoSmartPlugApplianceStateEnum.Off}.
2499
+ */
2500
+ state?: EnyoSmartPlugApplianceStateEnum;
2501
+ /**
2502
+ * Current active power drawn by the connected load in Watt. Normally
2503
+ * positive (a plug powers a consumer). Omit when the plug cannot
2504
+ * measure it — do not send `0` as a stand-in for "unknown", since a
2505
+ * consumer cannot tell that apart from "nothing is drawing power".
2506
+ */
2507
+ powerW?: number;
2508
+ /** Cumulative energy meter reading of the plug in Watt hours */
2509
+ meterValueWh?: number;
2510
+ /** Voltage measured at the plug in V, when reported */
2511
+ voltageV?: number;
2512
+ /** Current measured at the plug in A, when reported */
2513
+ currentA?: number;
2514
+ };
2515
+ }
2516
+ /**
2517
+ * Command switching a smart plug / relay channel on or off.
2518
+ *
2519
+ * Only valid for appliances that list
2520
+ * {@link EnyoSmartPlugApplianceAvailableFeaturesEnum.Switching} and whose
2521
+ * metadata does not set `controlAllowed: false`. The receiving integration
2522
+ * should answer with an {@link EnyoDataBusCommandAcknowledgeV1} message
2523
+ * referencing this message's `id`, and reflect the resulting relay state in the
2524
+ * next {@link EnyoDataBusSmartPlugValuesV1}.
2525
+ */
2526
+ export interface EnyoDataBusSetSmartPlugSwitchV1 extends EnyoDataBusMessage {
2527
+ type: 'message';
2528
+ message: EnyoDataBusMessageEnum.SetSmartPlugSwitchV1;
2529
+ /** ID of the smart plug appliance to switch */
2530
+ applianceId: string;
2531
+ data: {
2532
+ /** Target relay state: `On` closes the relay, `Off` opens it */
2533
+ state: EnyoSmartPlugApplianceStateEnum;
2534
+ /**
2535
+ * Minimum time in minutes the requested state should be held before the
2536
+ * plug may be switched again, to protect the connected load from
2537
+ * short-cycling. When omitted, the integration should fall back to the
2538
+ * appliance's `minOnDurationMinutes` / `minOffDurationMinutes`
2539
+ * metadata, and otherwise switch immediately.
2540
+ */
2541
+ minDurationMinutes?: number;
2542
+ /** Optional reason why this command was issued */
2543
+ reason?: EnyoDataBusCommandReason;
2544
+ };
2545
+ }
@@ -14,7 +14,7 @@
14
14
  // deliberately uses TS enums — the values below are the exact on-the-wire
15
15
  // strings, so the enums stay wire-compatible while giving callers named members.
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.EnyoCategoryFlexibilityGrantStatusEnum = exports.EnyoFlexibilityOptimizationModeEnum = exports.EnyoFlexibilityTimingTargetEnum = exports.EnyoFlexibilityAirConditioningTargetTypeEnum = exports.EnyoFlexibilityHeatpumpTargetTypeEnum = exports.EnyoFlexibilityAnnouncementTypeEnum = void 0;
17
+ exports.EnyoCategoryFlexibilityGrantStatusEnum = exports.EnyoFlexibilityOptimizationModeEnum = exports.EnyoFlexibilityTimingTargetEnum = exports.EnyoFlexibilityAirConditioningTargetTypeEnum = exports.EnyoFlexibilityTargetEnum = exports.EnyoFlexibilityHeatpumpTargetTypeEnum = exports.EnyoFlexibilityAnnouncementTypeEnum = void 0;
18
18
  // ─── Vocabulary enums ───────────────────────────────────────
19
19
  /** Discriminant tag for the four flexibility-announcement variants. */
20
20
  var EnyoFlexibilityAnnouncementTypeEnum;
@@ -32,6 +32,13 @@ var EnyoFlexibilityAnnouncementTypeEnum;
32
32
  * What a heat pump's flexibility is aimed at — gives the decision maker extra
33
33
  * context on the demand behind a heat-pump announcement. `Cooling` is reserved
34
34
  * for a future cooling mode and is not emitted yet.
35
+ *
36
+ * This enum describes the *mode* a heat pump runs in. To say what the announced
37
+ * energy is for — and how much power goes to each target — use
38
+ * {@link EnyoFlexibilityTargetEnum} together with
39
+ * {@link EnyoFlexibilityTargetPower}. The overlap between the two
40
+ * (`heating` / `dhw`) is intentional: both vocabularies stay wire-stable on
41
+ * their own.
35
42
  */
36
43
  var EnyoFlexibilityHeatpumpTargetTypeEnum;
37
44
  (function (EnyoFlexibilityHeatpumpTargetTypeEnum) {
@@ -39,6 +46,38 @@ var EnyoFlexibilityHeatpumpTargetTypeEnum;
39
46
  EnyoFlexibilityHeatpumpTargetTypeEnum["Cooling"] = "cooling";
40
47
  EnyoFlexibilityHeatpumpTargetTypeEnum["Dhw"] = "dhw";
41
48
  })(EnyoFlexibilityHeatpumpTargetTypeEnum || (exports.EnyoFlexibilityHeatpumpTargetTypeEnum = EnyoFlexibilityHeatpumpTargetTypeEnum = {}));
49
+ /**
50
+ * What an announced share of flexibility is physically aimed at — the open
51
+ * vocabulary behind the "how much watt for what" breakdown carried by
52
+ * {@link EnyoFlexibilityTargetPower}.
53
+ *
54
+ * The members present today all describe heat sinks, because thermal appliances
55
+ * are the first ones to split their draw. The enum is deliberately **not**
56
+ * scoped to thermal loads though: further members may describe non-thermal
57
+ * targets (a vehicle battery, a stationary storage, a dedicated household
58
+ * circuit) as other appliance types start announcing a breakdown. Consumers
59
+ * should therefore treat an unknown value as "some other target" rather than
60
+ * assuming every value maps to a heat sink.
61
+ *
62
+ * Broader than {@link EnyoFlexibilityHeatpumpTargetTypeEnum}, which names the
63
+ * *mode* a heat pump runs in: this enum adds the heating buffer tank, is not
64
+ * heat-pump specific (a heating rod announces against the same sinks), and
65
+ * carries no `cooling` member — cooling is a run mode, not a target.
66
+ *
67
+ * Values match the vocabulary used elsewhere in the SDK for the same physical
68
+ * parts (e.g. `domesticHotWater` and `bufferTank...` in the timeseries types),
69
+ * so a consumer can correlate an announcement with measured values without a
70
+ * mapping table.
71
+ */
72
+ var EnyoFlexibilityTargetEnum;
73
+ (function (EnyoFlexibilityTargetEnum) {
74
+ /** Domestic hot water tank. */
75
+ EnyoFlexibilityTargetEnum["DomesticHotWater"] = "domesticHotWater";
76
+ /** Heating buffer / storage tank. */
77
+ EnyoFlexibilityTargetEnum["BufferTank"] = "bufferTank";
78
+ /** Space heating circuit. */
79
+ EnyoFlexibilityTargetEnum["Heating"] = "heating";
80
+ })(EnyoFlexibilityTargetEnum || (exports.EnyoFlexibilityTargetEnum = EnyoFlexibilityTargetEnum = {}));
42
81
  /**
43
82
  * What an air-conditioning unit's flexibility is aimed at — extra context for
44
83
  * the decision maker. Cooling-only today; a heating variant may follow.
@@ -24,12 +24,50 @@ export declare enum EnyoFlexibilityAnnouncementTypeEnum {
24
24
  * What a heat pump's flexibility is aimed at — gives the decision maker extra
25
25
  * context on the demand behind a heat-pump announcement. `Cooling` is reserved
26
26
  * for a future cooling mode and is not emitted yet.
27
+ *
28
+ * This enum describes the *mode* a heat pump runs in. To say what the announced
29
+ * energy is for — and how much power goes to each target — use
30
+ * {@link EnyoFlexibilityTargetEnum} together with
31
+ * {@link EnyoFlexibilityTargetPower}. The overlap between the two
32
+ * (`heating` / `dhw`) is intentional: both vocabularies stay wire-stable on
33
+ * their own.
27
34
  */
28
35
  export declare enum EnyoFlexibilityHeatpumpTargetTypeEnum {
29
36
  Heating = "heating",
30
37
  Cooling = "cooling",
31
38
  Dhw = "dhw"
32
39
  }
40
+ /**
41
+ * What an announced share of flexibility is physically aimed at — the open
42
+ * vocabulary behind the "how much watt for what" breakdown carried by
43
+ * {@link EnyoFlexibilityTargetPower}.
44
+ *
45
+ * The members present today all describe heat sinks, because thermal appliances
46
+ * are the first ones to split their draw. The enum is deliberately **not**
47
+ * scoped to thermal loads though: further members may describe non-thermal
48
+ * targets (a vehicle battery, a stationary storage, a dedicated household
49
+ * circuit) as other appliance types start announcing a breakdown. Consumers
50
+ * should therefore treat an unknown value as "some other target" rather than
51
+ * assuming every value maps to a heat sink.
52
+ *
53
+ * Broader than {@link EnyoFlexibilityHeatpumpTargetTypeEnum}, which names the
54
+ * *mode* a heat pump runs in: this enum adds the heating buffer tank, is not
55
+ * heat-pump specific (a heating rod announces against the same sinks), and
56
+ * carries no `cooling` member — cooling is a run mode, not a target.
57
+ *
58
+ * Values match the vocabulary used elsewhere in the SDK for the same physical
59
+ * parts (e.g. `domesticHotWater` and `bufferTank...` in the timeseries types),
60
+ * so a consumer can correlate an announcement with measured values without a
61
+ * mapping table.
62
+ */
63
+ export declare enum EnyoFlexibilityTargetEnum {
64
+ /** Domestic hot water tank. */
65
+ DomesticHotWater = "domesticHotWater",
66
+ /** Heating buffer / storage tank. */
67
+ BufferTank = "bufferTank",
68
+ /** Space heating circuit. */
69
+ Heating = "heating"
70
+ }
33
71
  /**
34
72
  * What an air-conditioning unit's flexibility is aimed at — extra context for
35
73
  * the decision maker. Cooling-only today; a heating variant may follow.
@@ -60,6 +98,35 @@ export declare enum EnyoFlexibilityOptimizationModeEnum {
60
98
  PvSurplusPreferred = "pv-surplus-preferred",
61
99
  PriceLimit = "price-limit"
62
100
  }
101
+ /**
102
+ * How much power the announced flexibility would draw for one target — one
103
+ * entry of the "how much watt for what" breakdown behind an announcement.
104
+ *
105
+ * Purely informational context: the announcement's own energy figure stays
106
+ * authoritative. A breakdown may be partial — its entries need not sum to the
107
+ * appliance's full draw — but a given {@link target} SHOULD appear at most once
108
+ * per breakdown.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // A heat pump that would put 1500 W into the DHW tank and 800 W into heating
113
+ * const targets: EnyoFlexibilityTargetPower[] = [
114
+ * {target: EnyoFlexibilityTargetEnum.DomesticHotWater, powerW: 1500, kWh: 2.5},
115
+ * {target: EnyoFlexibilityTargetEnum.Heating, powerW: 800},
116
+ * ];
117
+ * ```
118
+ */
119
+ export interface EnyoFlexibilityTargetPower {
120
+ /** What this share is for. */
121
+ target: EnyoFlexibilityTargetEnum;
122
+ /** Electrical power this share would draw, in Watts. Non-negative. */
123
+ powerW: number;
124
+ /**
125
+ * Share of the announced energy attributable to this target, in kWh.
126
+ * Optional — omit when only the power split is known.
127
+ */
128
+ kWh?: number;
129
+ }
63
130
  /** Discrete power band the solver may pick from: [minWatt, maxWatt] in stepWatt steps. */
64
131
  export interface EnyoFlexibilityPowerBand {
65
132
  /** Lower bound of the band, in Watts. Non-negative. */
@@ -125,6 +192,13 @@ export interface EnyoFlexibilityAnnouncementContext {
125
192
  heatpumpTargetType?: EnyoFlexibilityHeatpumpTargetTypeEnum;
126
193
  /** For air-conditioning announcements: what the flexibility is aimed at. */
127
194
  airConditioningTargetType?: EnyoFlexibilityAirConditioningTargetTypeEnum;
195
+ /**
196
+ * How much power the announced flexibility would draw per target — "how much
197
+ * watt for what". Keeps the category surface in step with the per-appliance
198
+ * announcement, which carries the same breakdown under
199
+ * `data.flexibility.context.targets`.
200
+ */
201
+ targets?: EnyoFlexibilityTargetPower[];
128
202
  /**
129
203
  * For storage announcements: the round-trip cost of cycling the battery, in
130
204
  * EUR per kWh. The floor a discharge has to beat to be worth licensing.
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnyoSmartPlugApplianceIconEnum = exports.EnyoSmartPlugApplianceStateEnum = exports.EnyoSmartPlugApplianceAvailableFeaturesEnum = void 0;
4
+ /**
5
+ * Capabilities a smart plug / switchable relay appliance may support. A plug
6
+ * that only reports power without being switchable lists {@link Power} alone;
7
+ * one that can only be switched lists {@link Switching} alone.
8
+ */
9
+ var EnyoSmartPlugApplianceAvailableFeaturesEnum;
10
+ (function (EnyoSmartPlugApplianceAvailableFeaturesEnum) {
11
+ /** If the plug can be switched on and off by the energy manager or an automation */
12
+ EnyoSmartPlugApplianceAvailableFeaturesEnum["Switching"] = "Switching";
13
+ /** If the plug measures the active power (W) drawn by the connected load */
14
+ EnyoSmartPlugApplianceAvailableFeaturesEnum["Power"] = "Power";
15
+ /** If the plug reports a cumulative energy meter reading (Wh) for the connected load */
16
+ EnyoSmartPlugApplianceAvailableFeaturesEnum["EnergyMetering"] = "EnergyMetering";
17
+ })(EnyoSmartPlugApplianceAvailableFeaturesEnum || (exports.EnyoSmartPlugApplianceAvailableFeaturesEnum = EnyoSmartPlugApplianceAvailableFeaturesEnum = {}));
18
+ /**
19
+ * Relay state of a smart plug channel.
20
+ */
21
+ var EnyoSmartPlugApplianceStateEnum;
22
+ (function (EnyoSmartPlugApplianceStateEnum) {
23
+ /** The relay is closed — the connected load is powered */
24
+ EnyoSmartPlugApplianceStateEnum["On"] = "On";
25
+ /** The relay is open — the connected load is not powered */
26
+ EnyoSmartPlugApplianceStateEnum["Off"] = "Off";
27
+ })(EnyoSmartPlugApplianceStateEnum || (exports.EnyoSmartPlugApplianceStateEnum = EnyoSmartPlugApplianceStateEnum = {}));
28
+ /**
29
+ * Icon suggested for a smart plug appliance in end-user surfaces. Describes the
30
+ * load connected to the plug rather than the plug itself, so a user recognises
31
+ * "Dishwasher" instead of "Shelly channel 1".
32
+ *
33
+ * Purely presentational — consumers must not derive control behaviour from it.
34
+ * When omitted, or when a consumer does not know the member, it should fall
35
+ * back to a generic plug icon.
36
+ */
37
+ var EnyoSmartPlugApplianceIconEnum;
38
+ (function (EnyoSmartPlugApplianceIconEnum) {
39
+ /** Generic socket / unspecified load */
40
+ EnyoSmartPlugApplianceIconEnum["SmartPlug"] = "SmartPlug";
41
+ EnyoSmartPlugApplianceIconEnum["Dishwasher"] = "Dishwasher";
42
+ EnyoSmartPlugApplianceIconEnum["WashingMachine"] = "WashingMachine";
43
+ EnyoSmartPlugApplianceIconEnum["Dryer"] = "Dryer";
44
+ EnyoSmartPlugApplianceIconEnum["Refrigerator"] = "Refrigerator";
45
+ EnyoSmartPlugApplianceIconEnum["Freezer"] = "Freezer";
46
+ EnyoSmartPlugApplianceIconEnum["Oven"] = "Oven";
47
+ EnyoSmartPlugApplianceIconEnum["CoffeeMachine"] = "CoffeeMachine";
48
+ /** Kettle, toaster and other small kitchen appliances */
49
+ EnyoSmartPlugApplianceIconEnum["KitchenAppliance"] = "KitchenAppliance";
50
+ /** TV, hi-fi, console and other entertainment loads */
51
+ EnyoSmartPlugApplianceIconEnum["Entertainment"] = "Entertainment";
52
+ /** Desktop, server, network equipment */
53
+ EnyoSmartPlugApplianceIconEnum["Computer"] = "Computer";
54
+ EnyoSmartPlugApplianceIconEnum["Lighting"] = "Lighting";
55
+ /** Pool pump or pool filter system */
56
+ EnyoSmartPlugApplianceIconEnum["PoolPump"] = "PoolPump";
57
+ /** Circulation, well or sump pump */
58
+ EnyoSmartPlugApplianceIconEnum["Pump"] = "Pump";
59
+ /** Electric water heater / boiler */
60
+ EnyoSmartPlugApplianceIconEnum["WaterHeater"] = "WaterHeater";
61
+ /** Portable electric heater */
62
+ EnyoSmartPlugApplianceIconEnum["Heater"] = "Heater";
63
+ /** Fan or ventilation unit */
64
+ EnyoSmartPlugApplianceIconEnum["Fan"] = "Fan";
65
+ EnyoSmartPlugApplianceIconEnum["Aquarium"] = "Aquarium";
66
+ /** Garden, irrigation or greenhouse equipment */
67
+ EnyoSmartPlugApplianceIconEnum["Garden"] = "Garden";
68
+ /** Workshop machinery and power tools */
69
+ EnyoSmartPlugApplianceIconEnum["Workshop"] = "Workshop";
70
+ /** Car / e-bike charging via a plain socket */
71
+ EnyoSmartPlugApplianceIconEnum["Charging"] = "Charging";
72
+ /** Known load that none of the other members describe */
73
+ EnyoSmartPlugApplianceIconEnum["Other"] = "Other";
74
+ })(EnyoSmartPlugApplianceIconEnum || (exports.EnyoSmartPlugApplianceIconEnum = EnyoSmartPlugApplianceIconEnum = {}));