@enyo-energy/energy-app-sdk 0.0.174 → 0.0.176

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 (29) hide show
  1. package/dist/cjs/implementations/appliance-command-forecast/appliance-command-forecast-validators.cjs +47 -0
  2. package/dist/cjs/implementations/appliance-command-forecast/appliance-command-forecast-validators.d.cts +23 -1
  3. package/dist/cjs/implementations/appliances/appliance-manager.cjs +27 -0
  4. package/dist/cjs/implementations/appliances/appliance-manager.d.cts +15 -0
  5. package/dist/cjs/index.cjs +2 -0
  6. package/dist/cjs/index.d.cts +2 -0
  7. package/dist/cjs/packages/energy-app-appliance-energy-manager-forecast.d.cts +21 -1
  8. package/dist/cjs/packages/energy-app-appliance.d.cts +43 -2
  9. package/dist/cjs/types/enyo-appliance-command-forecast.d.cts +76 -0
  10. package/dist/cjs/types/enyo-data-bus-value.d.cts +6 -0
  11. package/dist/cjs/types/enyo-heatpump-appliance.cjs +11 -0
  12. package/dist/cjs/types/enyo-heatpump-appliance.d.cts +15 -1
  13. package/dist/cjs/version.cjs +1 -1
  14. package/dist/cjs/version.d.cts +1 -1
  15. package/dist/implementations/appliance-command-forecast/appliance-command-forecast-validators.d.ts +23 -1
  16. package/dist/implementations/appliance-command-forecast/appliance-command-forecast-validators.js +44 -0
  17. package/dist/implementations/appliances/appliance-manager.d.ts +15 -0
  18. package/dist/implementations/appliances/appliance-manager.js +27 -0
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +2 -0
  21. package/dist/packages/energy-app-appliance-energy-manager-forecast.d.ts +21 -1
  22. package/dist/packages/energy-app-appliance.d.ts +43 -2
  23. package/dist/types/enyo-appliance-command-forecast.d.ts +76 -0
  24. package/dist/types/enyo-data-bus-value.d.ts +6 -0
  25. package/dist/types/enyo-heatpump-appliance.d.ts +15 -1
  26. package/dist/types/enyo-heatpump-appliance.js +11 -0
  27. package/dist/version.d.ts +1 -1
  28. package/dist/version.js +1 -1
  29. package/package.json +1 -1
@@ -8,6 +8,9 @@ exports.validateChargerSchedule = validateChargerSchedule;
8
8
  exports.validateBatterySchedule = validateBatterySchedule;
9
9
  exports.validateHeatpumpSchedule = validateHeatpumpSchedule;
10
10
  exports.validateHeatpumpScheduleEntry = validateHeatpumpScheduleEntry;
11
+ exports.validateHeatingRodForecast = validateHeatingRodForecast;
12
+ exports.validateHeatingRodSchedule = validateHeatingRodSchedule;
13
+ exports.validateHeatingRodScheduleEntry = validateHeatingRodScheduleEntry;
11
14
  const enyo_appliance_command_forecast_js_1 = require("../../types/enyo-appliance-command-forecast.cjs");
12
15
  const enyo_data_bus_value_js_1 = require("../../types/enyo-data-bus-value.cjs");
13
16
  /**
@@ -172,6 +175,50 @@ function validateHeatpumpScheduleEntry(entry, fieldName) {
172
175
  validateBooleanField(entry.bufferTankBoostActive, `${fieldName}.bufferTankBoostActive`);
173
176
  validateBooleanField(entry.availablePowerActive, `${fieldName}.availablePowerActive`);
174
177
  }
178
+ /**
179
+ * Validates a {@link HeatingRodForecast}. Throws on the first violation —
180
+ * the error message names the offending field / index.
181
+ *
182
+ * The forecast carries a single relative schedule; every entry is
183
+ * validated by {@link validateHeatingRodScheduleEntry}.
184
+ */
185
+ function validateHeatingRodForecast(forecast) {
186
+ if (!forecast || typeof forecast !== 'object') {
187
+ throw new ApplianceCommandForecastValidationError('HeatingRodForecast must be an object.');
188
+ }
189
+ validateMetadata(forecast);
190
+ validateHeatingRodSchedule(forecast.relativeSchedule, forecast.resolution);
191
+ }
192
+ /**
193
+ * Validates a heating rod relative schedule (the schedule used by
194
+ * {@link HeatingRodForecast.relativeSchedule}). Enforces that the
195
+ * schedule is non-empty, starts at `seconds = 0`, has entries spaced by
196
+ * exactly `resolution`, and that every per-entry value falls in the
197
+ * plausible range documented on {@link HeatingRodForecastScheduleEntry}.
198
+ */
199
+ function validateHeatingRodSchedule(entries, resolution) {
200
+ const stepSeconds = resolveResolutionSeconds(resolution);
201
+ validateNonEmptySchedule(entries, 'relativeSchedule');
202
+ for (let i = 0; i < entries.length; i++) {
203
+ validateHeatingRodScheduleEntry(entries[i], `relativeSchedule[${i}]`);
204
+ }
205
+ validateFirstEntryStartsAtZero(entries[0].seconds, 'relativeSchedule');
206
+ validateSecondsMatchResolution(entries.map((e) => e.seconds), stepSeconds, 'relativeSchedule');
207
+ }
208
+ /**
209
+ * Validates a single {@link HeatingRodForecastScheduleEntry}. Used by
210
+ * {@link validateHeatingRodSchedule} and exposed for callers that build
211
+ * entries incrementally.
212
+ */
213
+ function validateHeatingRodScheduleEntry(entry, fieldName) {
214
+ validateSecondsField(entry.seconds, `${fieldName}.seconds`);
215
+ if (entry.powerW !== undefined) {
216
+ validatePowerW(entry.powerW, `${fieldName}.powerW`);
217
+ }
218
+ validateTemperatureField(entry.temperatureC, `${fieldName}.temperatureC`);
219
+ validateBooleanField(entry.heatingActive, `${fieldName}.heatingActive`);
220
+ validateBooleanField(entry.availablePowerActive, `${fieldName}.availablePowerActive`);
221
+ }
175
222
  function validateMetadata(forecast) {
176
223
  if (!(forecast.resolution in RESOLUTION_SECONDS)) {
177
224
  throw new ApplianceCommandForecastValidationError(`resolution is invalid: ${forecast.resolution}. Allowed values: ${Object.values(enyo_appliance_command_forecast_js_1.ApplianceForecastResolutionEnum).join(', ')}.`);
@@ -1,4 +1,4 @@
1
- import { ApplianceForecastResolutionEnum, BatteryCommandForecast, BatteryCommandForecastScheduleEntry, ChargerForecast, ChargerForecastScheduleEntry, HeatpumpForecast, HeatpumpForecastScheduleEntry } from '../../types/enyo-appliance-command-forecast.cjs';
1
+ import { ApplianceForecastResolutionEnum, BatteryCommandForecast, BatteryCommandForecastScheduleEntry, ChargerForecast, ChargerForecastScheduleEntry, HeatingRodForecast, HeatingRodForecastScheduleEntry, HeatpumpForecast, HeatpumpForecastScheduleEntry } from '../../types/enyo-appliance-command-forecast.cjs';
2
2
  /**
3
3
  * Thrown when a forecast payload passed to one of the validators (or to
4
4
  * {@link EnergyAppApplianceEnergyManagerForecast.publishChargerForecast}
@@ -65,3 +65,25 @@ export declare function validateHeatpumpSchedule(entries: HeatpumpForecastSchedu
65
65
  * entries incrementally.
66
66
  */
67
67
  export declare function validateHeatpumpScheduleEntry(entry: HeatpumpForecastScheduleEntry, fieldName: string): void;
68
+ /**
69
+ * Validates a {@link HeatingRodForecast}. Throws on the first violation —
70
+ * the error message names the offending field / index.
71
+ *
72
+ * The forecast carries a single relative schedule; every entry is
73
+ * validated by {@link validateHeatingRodScheduleEntry}.
74
+ */
75
+ export declare function validateHeatingRodForecast(forecast: HeatingRodForecast): void;
76
+ /**
77
+ * Validates a heating rod relative schedule (the schedule used by
78
+ * {@link HeatingRodForecast.relativeSchedule}). Enforces that the
79
+ * schedule is non-empty, starts at `seconds = 0`, has entries spaced by
80
+ * exactly `resolution`, and that every per-entry value falls in the
81
+ * plausible range documented on {@link HeatingRodForecastScheduleEntry}.
82
+ */
83
+ export declare function validateHeatingRodSchedule(entries: HeatingRodForecastScheduleEntry[], resolution: ApplianceForecastResolutionEnum): void;
84
+ /**
85
+ * Validates a single {@link HeatingRodForecastScheduleEntry}. Used by
86
+ * {@link validateHeatingRodSchedule} and exposed for callers that build
87
+ * entries incrementally.
88
+ */
89
+ export declare function validateHeatingRodScheduleEntry(entry: HeatingRodForecastScheduleEntry, fieldName: string): void;
@@ -300,6 +300,33 @@ class ApplianceManager {
300
300
  });
301
301
  this.listenerIds.push(removedListenerId);
302
302
  }
303
+ /**
304
+ * Subscribes to newly-created appliances. Fires only when an appliance is
305
+ * first created, not on subsequent updates. The optional
306
+ * {@link EnyoApplianceCreatedFilter filter} controls scope (own package,
307
+ * all appliances, or only externally-created) and category — `scope: 'all'`
308
+ * and `scope: 'external'` require the `AllAppliances` permission.
309
+ *
310
+ * @param listener - Invoked with each newly-created appliance
311
+ * @param filter - Optional scope/category filter; defaults to `{ scope: 'own' }`
312
+ * @returns An unsubscribe function. Any still-active subscription is also
313
+ * cleaned up automatically on {@link dispose}.
314
+ * @throws {ApplianceManagerDisposedError} when called after {@link dispose}
315
+ */
316
+ onApplianceCreated(listener, filter) {
317
+ this.throwIfDisposed();
318
+ const applianceService = this.energyApp.useAppliances();
319
+ const listenerId = applianceService.listenForApplianceCreated((appliance) => {
320
+ if (this.disposed)
321
+ return;
322
+ return listener(appliance);
323
+ }, filter);
324
+ this.listenerIds.push(listenerId);
325
+ return () => {
326
+ applianceService.removeListener(listenerId);
327
+ this.listenerIds = this.listenerIds.filter(id => id !== listenerId);
328
+ };
329
+ }
303
330
  /**
304
331
  * Clears the internal cache without touching the SDK.
305
332
  */
@@ -1,6 +1,7 @@
1
1
  import { EnergyApp } from "../../index.cjs";
2
2
  import type { EnyoNetworkDevice } from "../../types/enyo-network-device.cjs";
3
3
  import { EnyoAppliance, EnyoApplianceAvailableFeaturesEnum, EnyoApplianceConnectionType, EnyoApplianceMetadata, EnyoApplianceName, EnyoApplianceStateEnum, EnyoApplianceTopology, EnyoApplianceTypeEnum } from "../../types/enyo-appliance.cjs";
4
+ import type { EnyoApplianceCreatedFilter } from "../../packages/energy-app-appliance.cjs";
4
5
  import type { EnyoChargerApplianceMetadata } from "../../types/enyo-charger-appliance.cjs";
5
6
  import type { EnyoHeatpumpApplianceMetadata } from "../../types/enyo-heatpump-appliance.cjs";
6
7
  import type { EnyoBatteryApplianceMetadata } from "../../types/enyo-battery-appliance.cjs";
@@ -203,6 +204,20 @@ export declare class ApplianceManager {
203
204
  * Subscribes to appliance update and removal events to keep the cache in sync.
204
205
  */
205
206
  private subscribeToEvents;
207
+ /**
208
+ * Subscribes to newly-created appliances. Fires only when an appliance is
209
+ * first created, not on subsequent updates. The optional
210
+ * {@link EnyoApplianceCreatedFilter filter} controls scope (own package,
211
+ * all appliances, or only externally-created) and category — `scope: 'all'`
212
+ * and `scope: 'external'` require the `AllAppliances` permission.
213
+ *
214
+ * @param listener - Invoked with each newly-created appliance
215
+ * @param filter - Optional scope/category filter; defaults to `{ scope: 'own' }`
216
+ * @returns An unsubscribe function. Any still-active subscription is also
217
+ * cleaned up automatically on {@link dispose}.
218
+ * @throws {ApplianceManagerDisposedError} when called after {@link dispose}
219
+ */
220
+ onApplianceCreated(listener: (appliance: EnyoAppliance) => void | Promise<void>, filter?: EnyoApplianceCreatedFilter): () => void;
206
221
  /**
207
222
  * Clears the internal cache without touching the SDK.
208
223
  */
@@ -29,6 +29,8 @@ __exportStar(require("./types/enyo-energy-prices.cjs"), exports);
29
29
  __exportStar(require("./types/enyo-notification.cjs"), exports);
30
30
  __exportStar(require("./types/enyo-secret-manager.cjs"), exports);
31
31
  __exportStar(require("./types/enyo-location.cjs"), exports);
32
+ __exportStar(require("./types/enyo-appliance.cjs"), exports);
33
+ __exportStar(require("./packages/energy-app-appliance.cjs"), exports);
32
34
  __exportStar(require("./implementations/appliances/appliance-manager.cjs"), exports);
33
35
  __exportStar(require("./implementations/appliances/identifier-strategies.cjs"), exports);
34
36
  __exportStar(require("./implementations/network-devices/network-access-guard.cjs"), exports);
@@ -13,6 +13,8 @@ export * from './types/enyo-energy-prices.cjs';
13
13
  export * from './types/enyo-notification.cjs';
14
14
  export * from './types/enyo-secret-manager.cjs';
15
15
  export * from './types/enyo-location.cjs';
16
+ export * from './types/enyo-appliance.cjs';
17
+ export * from './packages/energy-app-appliance.cjs';
16
18
  export * from './implementations/appliances/appliance-manager.cjs';
17
19
  export * from './implementations/appliances/identifier-strategies.cjs';
18
20
  export * from './implementations/network-devices/network-access-guard.cjs';
@@ -1,4 +1,4 @@
1
- import { BatteryCommandForecast, ChargerForecast, HeatpumpForecast } from '../types/enyo-appliance-command-forecast.cjs';
1
+ import { BatteryCommandForecast, ChargerForecast, HeatingRodForecast, HeatpumpForecast } from '../types/enyo-appliance-command-forecast.cjs';
2
2
  /**
3
3
  * SDK accessor for the **Appliance Energy-Manager Forecast** package.
4
4
  *
@@ -16,6 +16,10 @@ import { BatteryCommandForecast, ChargerForecast, HeatpumpForecast } from '../ty
16
16
  * carry the forecasted DHW / room / buffer-tank temperatures together
17
17
  * with planned boost / pre-heating flags and the available-power
18
18
  * announcement at each slot ({@link HeatpumpForecast}).
19
+ * - **Heating rods** — a single relative schedule whose entries carry
20
+ * the forecasted target temperature together with the planned heating
21
+ * flag and the available-power announcement at each slot
22
+ * ({@link HeatingRodForecast}).
19
23
  *
20
24
  * Every forecast optionally carries
21
25
  * {@link ApplianceForecastEstimatedSavings} so downstream consumers can
@@ -85,4 +89,20 @@ export interface EnergyAppApplianceEnergyManagerForecast {
85
89
  * is malformed.
86
90
  */
87
91
  publishHeatpumpForecast(applianceId: string, forecast: HeatpumpForecast): Promise<void>;
92
+ /**
93
+ * Publishes the command-plan forecast for a heating rod (immersion
94
+ * element). The forecast carries a single relative schedule whose
95
+ * entries pack the forecasted target temperature together with the
96
+ * planned heating flag and the available-power announcement at each
97
+ * slot.
98
+ *
99
+ * Validates {@link forecast} against the invariants documented on
100
+ * {@link HeatingRodForecast}.
101
+ *
102
+ * @param applianceId - The heating rod appliance the forecast applies to.
103
+ * @param forecast - The command-plan forecast and its metadata.
104
+ * @throws {ApplianceCommandForecastValidationError} If the forecast
105
+ * is malformed.
106
+ */
107
+ publishHeatingRodForecast(applianceId: string, forecast: HeatingRodForecast): Promise<void>;
88
108
  }
@@ -1,4 +1,30 @@
1
- import { EnyoAppliance } from "../types/enyo-appliance.cjs";
1
+ import { EnyoAppliance, EnyoApplianceTypeEnum } from "../types/enyo-appliance.cjs";
2
+ /**
3
+ * Ownership scope for an appliance-created subscription.
4
+ * - `'own'`: appliances created by your own package.
5
+ * - `'all'`: every appliance created system-wide.
6
+ * - `'external'`: only appliances created by *other* packages (all minus own).
7
+ */
8
+ export type EnyoApplianceCreatedScope = 'own' | 'all' | 'external';
9
+ /**
10
+ * Optional filter controlling which appliance-created events a listener receives.
11
+ * When omitted, defaults to `scope: 'own'` and no category restriction.
12
+ */
13
+ export interface EnyoApplianceCreatedFilter {
14
+ /**
15
+ * Ownership scope of the subscription:
16
+ * - `'own'` (default): appliances created by your own package.
17
+ * - `'all'`: every appliance created system-wide. Requires the `AllAppliances` permission.
18
+ * - `'external'`: only appliances created by *other* packages (all minus own). Requires the `AllAppliances` permission.
19
+ */
20
+ scope?: EnyoApplianceCreatedScope;
21
+ /**
22
+ * When set, the listener only fires for appliances whose
23
+ * {@link EnyoApplianceTypeEnum category} is included in this list. When
24
+ * omitted, appliances of every category are delivered.
25
+ */
26
+ types?: EnyoApplianceTypeEnum[];
27
+ }
2
28
  /**
3
29
  * Interface for managing appliances in enyo packages.
4
30
  * Provides CRUD operations for appliance registration and management.
@@ -26,9 +52,24 @@ export interface EnergyAppAppliance {
26
52
  * @returns A unique listener ID that can be used to remove the listener
27
53
  */
28
54
  listenForApplianceRemoved: (listener: (applianceId: string) => void | Promise<void>) => string;
55
+ /**
56
+ * Listen for newly-created appliances. Fires only when an appliance is
57
+ * first created — not on subsequent updates (use
58
+ * {@link listenForApplianceUpdated} for those).
59
+ *
60
+ * The optional {@link EnyoApplianceCreatedFilter filter} controls scope and
61
+ * category: by default only your own package's creations are delivered;
62
+ * `scope: 'all'` and `scope: 'external'` observe appliances created by other
63
+ * packages and require the `AllAppliances` permission.
64
+ *
65
+ * @param listener - Callback invoked with each newly-created appliance
66
+ * @param filter - Optional scope/category filter; defaults to `{ scope: 'own' }`
67
+ * @returns A unique listener ID that can be used to remove the listener
68
+ */
69
+ listenForApplianceCreated: (listener: (appliance: EnyoAppliance) => void | Promise<void>, filter?: EnyoApplianceCreatedFilter) => string;
29
70
  /**
30
71
  * Removes a previously registered listener.
31
- * @param listenerId - The ID returned by listenForApplianceUpdated or listenForApplianceRemoved
72
+ * @param listenerId - The ID returned by listenForApplianceUpdated, listenForApplianceRemoved, or listenForApplianceCreated
32
73
  */
33
74
  removeListener: (listenerId: string) => void;
34
75
  }
@@ -354,3 +354,79 @@ export interface HeatpumpForecast extends ApplianceForecastMetadata {
354
354
  */
355
355
  relativeSchedule: HeatpumpForecastScheduleEntry[];
356
356
  }
357
+ /**
358
+ * One entry of a heating rod's relative schedule.
359
+ *
360
+ * The entry packs every per-slot piece of information the energy-manager
361
+ * forecast carries for a heating rod (immersion element): the forecasted
362
+ * target temperature, the planned heating flag, and the available-power
363
+ * announcement. The setpoint becomes active {@link seconds} after the
364
+ * forecast becomes effective and stays active until the next entry's
365
+ * `seconds` is reached.
366
+ *
367
+ * Every field other than {@link seconds} is optional — an entry may
368
+ * describe only the temperature, only the flag, only power, or any
369
+ * combination. A field that is omitted carries no information for that
370
+ * slot (it is **not** "set to zero / false"); the previous entry's value
371
+ * should be treated as still in effect.
372
+ */
373
+ export interface HeatingRodForecastScheduleEntry {
374
+ /**
375
+ * Seconds from the moment the forecast becomes effective at which
376
+ * this entry becomes active. `0` for the first entry; subsequent
377
+ * entries must be strictly increasing.
378
+ */
379
+ seconds: number;
380
+ /**
381
+ * Planned available electrical power in Watts the energy manager
382
+ * intends to make available to the heating rod during this slot. The
383
+ * heating rod is free to consume up to this value — and free to
384
+ * consume less if it cannot use it all. Non-negative when present.
385
+ */
386
+ powerW?: number;
387
+ /**
388
+ * Forecasted target temperature in °C at this slot (the temperature
389
+ * the heating rod is driving its tank / buffer toward). Plausible
390
+ * range: [-50, 150].
391
+ */
392
+ temperatureC?: number;
393
+ /**
394
+ * Whether the heating rod is planned to be actively heating during
395
+ * this slot — `true` while the publisher intends to drive the tank
396
+ * up, `false` (or omitted) otherwise.
397
+ */
398
+ heatingActive?: boolean;
399
+ /**
400
+ * Whether the publisher is announcing available power for this slot
401
+ * — `true` when the energy-manager decision for the slot is
402
+ * "available power", meaning {@link powerW} doubles as the
403
+ * available-power offer to the heating rod (the heating rod is free
404
+ * to consume up to that value), `false` (or omitted) otherwise.
405
+ *
406
+ * This flag is independent of {@link heatingActive} and may coexist
407
+ * with it when the publisher offers available power while a heating
408
+ * window is also planned.
409
+ */
410
+ availablePowerActive?: boolean;
411
+ }
412
+ /**
413
+ * Forecasted command plan for a heating rod appliance, published via
414
+ * {@link EnergyAppApplianceEnergyManagerForecast.publishHeatingRodForecast}.
415
+ *
416
+ * A heating rod forecast is a **single** relative schedule whose entries
417
+ * carry every per-slot piece of information at once (forecasted target
418
+ * temperature, heating flag, available-power announcement). One entry per
419
+ * slot keeps the temperature trajectory and the heating decisions aligned
420
+ * by construction.
421
+ *
422
+ * The schedule must be sorted ascending by `seconds` and start at
423
+ * `seconds = 0` so the appliance has an authoritative "right now" entry.
424
+ */
425
+ export interface HeatingRodForecast extends ApplianceForecastMetadata {
426
+ /**
427
+ * Relative schedule of forecast entries. Sorted ascending by
428
+ * `seconds`, starting at `seconds = 0`. Must contain at least one
429
+ * entry.
430
+ */
431
+ relativeSchedule: HeatingRodForecastScheduleEntry[];
432
+ }
@@ -625,6 +625,12 @@ export interface EnyoDataBusAggregatedStateValuesV1 extends EnyoDataBusMessage {
625
625
  gridPowerPhase2W?: number;
626
626
  /** Grid power on phase L3 (in Watt). Negative: grid feed in, positive: grid consumption */
627
627
  gridPowerPhase3W?: number;
628
+ /**
629
+ * Time resolution of the aggregated grid power values (e.g. the sampling
630
+ * interval the `gridPowerW` / `gridPowerPhaseXW` values were measured at).
631
+ * Use `'dynamic'` when the values are forwarded as events occur.
632
+ */
633
+ gridPowerResolution: EnyoDataBusMessageResolution;
628
634
  gridConsumptionW?: number;
629
635
  gridFeedInW?: number;
630
636
  homeConsumptionW?: number;
@@ -19,12 +19,23 @@ var EnyoHeatpumpApplianceAvailableFeaturesEnum;
19
19
  EnyoHeatpumpApplianceAvailableFeaturesEnum["Power"] = "Power";
20
20
  /** If the heatpump is ready for calibration (i.e. has all prerequisites in place to start a calibration run) */
21
21
  EnyoHeatpumpApplianceAvailableFeaturesEnum["ReadyForCalibration"] = "ReadyForCalibration";
22
+ /** If the heatpump supports cooling (reversible heatpump) */
23
+ EnyoHeatpumpApplianceAvailableFeaturesEnum["Cooling"] = "Cooling";
22
24
  })(EnyoHeatpumpApplianceAvailableFeaturesEnum || (exports.EnyoHeatpumpApplianceAvailableFeaturesEnum = EnyoHeatpumpApplianceAvailableFeaturesEnum = {}));
25
+ /**
26
+ * The current operating state of a heatpump.
27
+ */
23
28
  var EnyoHeatpumpApplianceModeEnum;
24
29
  (function (EnyoHeatpumpApplianceModeEnum) {
30
+ /** The heatpump is idle (not actively heating, cooling, or producing hot water) */
25
31
  EnyoHeatpumpApplianceModeEnum["Idle"] = "Idle";
32
+ /** The heatpump is actively heating */
26
33
  EnyoHeatpumpApplianceModeEnum["Heating"] = "Heating";
34
+ /** The heatpump is actively cooling (reversible heatpumps only) */
35
+ EnyoHeatpumpApplianceModeEnum["Cooling"] = "Cooling";
36
+ /** The heatpump is actively producing domestic hot water */
27
37
  EnyoHeatpumpApplianceModeEnum["DomesticHotWater"] = "DomesticHotWater";
38
+ /** The heatpump is running in emergency operation */
28
39
  EnyoHeatpumpApplianceModeEnum["EmergencyOperation"] = "EmergencyOperation";
29
40
  })(EnyoHeatpumpApplianceModeEnum || (exports.EnyoHeatpumpApplianceModeEnum = EnyoHeatpumpApplianceModeEnum = {}));
30
41
  /**
@@ -14,12 +14,23 @@ export declare enum EnyoHeatpumpApplianceAvailableFeaturesEnum {
14
14
  /** If the heatpump reports power values (e.g. electrical power consumption in watts) */
15
15
  Power = "Power",
16
16
  /** If the heatpump is ready for calibration (i.e. has all prerequisites in place to start a calibration run) */
17
- ReadyForCalibration = "ReadyForCalibration"
17
+ ReadyForCalibration = "ReadyForCalibration",
18
+ /** If the heatpump supports cooling (reversible heatpump) */
19
+ Cooling = "Cooling"
18
20
  }
21
+ /**
22
+ * The current operating state of a heatpump.
23
+ */
19
24
  export declare enum EnyoHeatpumpApplianceModeEnum {
25
+ /** The heatpump is idle (not actively heating, cooling, or producing hot water) */
20
26
  Idle = "Idle",
27
+ /** The heatpump is actively heating */
21
28
  Heating = "Heating",
29
+ /** The heatpump is actively cooling (reversible heatpumps only) */
30
+ Cooling = "Cooling",
31
+ /** The heatpump is actively producing domestic hot water */
22
32
  DomesticHotWater = "DomesticHotWater",
33
+ /** The heatpump is running in emergency operation */
23
34
  EmergencyOperation = "EmergencyOperation"
24
35
  }
25
36
  /**
@@ -51,7 +62,10 @@ export interface EnyoHeatpumpApplianceCompressor {
51
62
  }
52
63
  export interface EnyoHeatpumpApplianceHeatingCircuit {
53
64
  index: number;
65
+ /** Target room temperature setpoint when heating (in °C) */
54
66
  targetRoomTemperatureC?: number;
67
+ /** Target room temperature setpoint when cooling (in °C). Only meaningful for cooling-capable heatpumps. */
68
+ targetCoolingRoomTemperatureC?: number;
55
69
  }
56
70
  export interface EnyoHeatpumpApplianceMetadata {
57
71
  availableFeatures: EnyoHeatpumpApplianceAvailableFeaturesEnum[];
@@ -9,7 +9,7 @@ exports.getSdkVersion = getSdkVersion;
9
9
  /**
10
10
  * Current version of the enyo Energy App SDK.
11
11
  */
12
- exports.SDK_VERSION = '0.0.174';
12
+ exports.SDK_VERSION = '0.0.176';
13
13
  /**
14
14
  * Gets the current SDK version.
15
15
  * @returns The semantic version string of the SDK
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export declare const SDK_VERSION = "0.0.174";
8
+ export declare const SDK_VERSION = "0.0.176";
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
@@ -1,4 +1,4 @@
1
- import { ApplianceForecastResolutionEnum, BatteryCommandForecast, BatteryCommandForecastScheduleEntry, ChargerForecast, ChargerForecastScheduleEntry, HeatpumpForecast, HeatpumpForecastScheduleEntry } from '../../types/enyo-appliance-command-forecast.js';
1
+ import { ApplianceForecastResolutionEnum, BatteryCommandForecast, BatteryCommandForecastScheduleEntry, ChargerForecast, ChargerForecastScheduleEntry, HeatingRodForecast, HeatingRodForecastScheduleEntry, HeatpumpForecast, HeatpumpForecastScheduleEntry } from '../../types/enyo-appliance-command-forecast.js';
2
2
  /**
3
3
  * Thrown when a forecast payload passed to one of the validators (or to
4
4
  * {@link EnergyAppApplianceEnergyManagerForecast.publishChargerForecast}
@@ -65,3 +65,25 @@ export declare function validateHeatpumpSchedule(entries: HeatpumpForecastSchedu
65
65
  * entries incrementally.
66
66
  */
67
67
  export declare function validateHeatpumpScheduleEntry(entry: HeatpumpForecastScheduleEntry, fieldName: string): void;
68
+ /**
69
+ * Validates a {@link HeatingRodForecast}. Throws on the first violation —
70
+ * the error message names the offending field / index.
71
+ *
72
+ * The forecast carries a single relative schedule; every entry is
73
+ * validated by {@link validateHeatingRodScheduleEntry}.
74
+ */
75
+ export declare function validateHeatingRodForecast(forecast: HeatingRodForecast): void;
76
+ /**
77
+ * Validates a heating rod relative schedule (the schedule used by
78
+ * {@link HeatingRodForecast.relativeSchedule}). Enforces that the
79
+ * schedule is non-empty, starts at `seconds = 0`, has entries spaced by
80
+ * exactly `resolution`, and that every per-entry value falls in the
81
+ * plausible range documented on {@link HeatingRodForecastScheduleEntry}.
82
+ */
83
+ export declare function validateHeatingRodSchedule(entries: HeatingRodForecastScheduleEntry[], resolution: ApplianceForecastResolutionEnum): void;
84
+ /**
85
+ * Validates a single {@link HeatingRodForecastScheduleEntry}. Used by
86
+ * {@link validateHeatingRodSchedule} and exposed for callers that build
87
+ * entries incrementally.
88
+ */
89
+ export declare function validateHeatingRodScheduleEntry(entry: HeatingRodForecastScheduleEntry, fieldName: string): void;
@@ -161,6 +161,50 @@ export function validateHeatpumpScheduleEntry(entry, fieldName) {
161
161
  validateBooleanField(entry.bufferTankBoostActive, `${fieldName}.bufferTankBoostActive`);
162
162
  validateBooleanField(entry.availablePowerActive, `${fieldName}.availablePowerActive`);
163
163
  }
164
+ /**
165
+ * Validates a {@link HeatingRodForecast}. Throws on the first violation —
166
+ * the error message names the offending field / index.
167
+ *
168
+ * The forecast carries a single relative schedule; every entry is
169
+ * validated by {@link validateHeatingRodScheduleEntry}.
170
+ */
171
+ export function validateHeatingRodForecast(forecast) {
172
+ if (!forecast || typeof forecast !== 'object') {
173
+ throw new ApplianceCommandForecastValidationError('HeatingRodForecast must be an object.');
174
+ }
175
+ validateMetadata(forecast);
176
+ validateHeatingRodSchedule(forecast.relativeSchedule, forecast.resolution);
177
+ }
178
+ /**
179
+ * Validates a heating rod relative schedule (the schedule used by
180
+ * {@link HeatingRodForecast.relativeSchedule}). Enforces that the
181
+ * schedule is non-empty, starts at `seconds = 0`, has entries spaced by
182
+ * exactly `resolution`, and that every per-entry value falls in the
183
+ * plausible range documented on {@link HeatingRodForecastScheduleEntry}.
184
+ */
185
+ export function validateHeatingRodSchedule(entries, resolution) {
186
+ const stepSeconds = resolveResolutionSeconds(resolution);
187
+ validateNonEmptySchedule(entries, 'relativeSchedule');
188
+ for (let i = 0; i < entries.length; i++) {
189
+ validateHeatingRodScheduleEntry(entries[i], `relativeSchedule[${i}]`);
190
+ }
191
+ validateFirstEntryStartsAtZero(entries[0].seconds, 'relativeSchedule');
192
+ validateSecondsMatchResolution(entries.map((e) => e.seconds), stepSeconds, 'relativeSchedule');
193
+ }
194
+ /**
195
+ * Validates a single {@link HeatingRodForecastScheduleEntry}. Used by
196
+ * {@link validateHeatingRodSchedule} and exposed for callers that build
197
+ * entries incrementally.
198
+ */
199
+ export function validateHeatingRodScheduleEntry(entry, fieldName) {
200
+ validateSecondsField(entry.seconds, `${fieldName}.seconds`);
201
+ if (entry.powerW !== undefined) {
202
+ validatePowerW(entry.powerW, `${fieldName}.powerW`);
203
+ }
204
+ validateTemperatureField(entry.temperatureC, `${fieldName}.temperatureC`);
205
+ validateBooleanField(entry.heatingActive, `${fieldName}.heatingActive`);
206
+ validateBooleanField(entry.availablePowerActive, `${fieldName}.availablePowerActive`);
207
+ }
164
208
  function validateMetadata(forecast) {
165
209
  if (!(forecast.resolution in RESOLUTION_SECONDS)) {
166
210
  throw new ApplianceCommandForecastValidationError(`resolution is invalid: ${forecast.resolution}. Allowed values: ${Object.values(ApplianceForecastResolutionEnum).join(', ')}.`);
@@ -1,6 +1,7 @@
1
1
  import { EnergyApp } from "../../index.js";
2
2
  import type { EnyoNetworkDevice } from "../../types/enyo-network-device.js";
3
3
  import { EnyoAppliance, EnyoApplianceAvailableFeaturesEnum, EnyoApplianceConnectionType, EnyoApplianceMetadata, EnyoApplianceName, EnyoApplianceStateEnum, EnyoApplianceTopology, EnyoApplianceTypeEnum } from "../../types/enyo-appliance.js";
4
+ import type { EnyoApplianceCreatedFilter } from "../../packages/energy-app-appliance.js";
4
5
  import type { EnyoChargerApplianceMetadata } from "../../types/enyo-charger-appliance.js";
5
6
  import type { EnyoHeatpumpApplianceMetadata } from "../../types/enyo-heatpump-appliance.js";
6
7
  import type { EnyoBatteryApplianceMetadata } from "../../types/enyo-battery-appliance.js";
@@ -203,6 +204,20 @@ export declare class ApplianceManager {
203
204
  * Subscribes to appliance update and removal events to keep the cache in sync.
204
205
  */
205
206
  private subscribeToEvents;
207
+ /**
208
+ * Subscribes to newly-created appliances. Fires only when an appliance is
209
+ * first created, not on subsequent updates. The optional
210
+ * {@link EnyoApplianceCreatedFilter filter} controls scope (own package,
211
+ * all appliances, or only externally-created) and category — `scope: 'all'`
212
+ * and `scope: 'external'` require the `AllAppliances` permission.
213
+ *
214
+ * @param listener - Invoked with each newly-created appliance
215
+ * @param filter - Optional scope/category filter; defaults to `{ scope: 'own' }`
216
+ * @returns An unsubscribe function. Any still-active subscription is also
217
+ * cleaned up automatically on {@link dispose}.
218
+ * @throws {ApplianceManagerDisposedError} when called after {@link dispose}
219
+ */
220
+ onApplianceCreated(listener: (appliance: EnyoAppliance) => void | Promise<void>, filter?: EnyoApplianceCreatedFilter): () => void;
206
221
  /**
207
222
  * Clears the internal cache without touching the SDK.
208
223
  */
@@ -294,6 +294,33 @@ export class ApplianceManager {
294
294
  });
295
295
  this.listenerIds.push(removedListenerId);
296
296
  }
297
+ /**
298
+ * Subscribes to newly-created appliances. Fires only when an appliance is
299
+ * first created, not on subsequent updates. The optional
300
+ * {@link EnyoApplianceCreatedFilter filter} controls scope (own package,
301
+ * all appliances, or only externally-created) and category — `scope: 'all'`
302
+ * and `scope: 'external'` require the `AllAppliances` permission.
303
+ *
304
+ * @param listener - Invoked with each newly-created appliance
305
+ * @param filter - Optional scope/category filter; defaults to `{ scope: 'own' }`
306
+ * @returns An unsubscribe function. Any still-active subscription is also
307
+ * cleaned up automatically on {@link dispose}.
308
+ * @throws {ApplianceManagerDisposedError} when called after {@link dispose}
309
+ */
310
+ onApplianceCreated(listener, filter) {
311
+ this.throwIfDisposed();
312
+ const applianceService = this.energyApp.useAppliances();
313
+ const listenerId = applianceService.listenForApplianceCreated((appliance) => {
314
+ if (this.disposed)
315
+ return;
316
+ return listener(appliance);
317
+ }, filter);
318
+ this.listenerIds.push(listenerId);
319
+ return () => {
320
+ applianceService.removeListener(listenerId);
321
+ this.listenerIds = this.listenerIds.filter(id => id !== listenerId);
322
+ };
323
+ }
297
324
  /**
298
325
  * Clears the internal cache without touching the SDK.
299
326
  */
package/dist/index.d.ts CHANGED
@@ -13,6 +13,8 @@ export * from './types/enyo-energy-prices.js';
13
13
  export * from './types/enyo-notification.js';
14
14
  export * from './types/enyo-secret-manager.js';
15
15
  export * from './types/enyo-location.js';
16
+ export * from './types/enyo-appliance.js';
17
+ export * from './packages/energy-app-appliance.js';
16
18
  export * from './implementations/appliances/appliance-manager.js';
17
19
  export * from './implementations/appliances/identifier-strategies.js';
18
20
  export * from './implementations/network-devices/network-access-guard.js';
package/dist/index.js CHANGED
@@ -13,6 +13,8 @@ export * from './types/enyo-energy-prices.js';
13
13
  export * from './types/enyo-notification.js';
14
14
  export * from './types/enyo-secret-manager.js';
15
15
  export * from './types/enyo-location.js';
16
+ export * from './types/enyo-appliance.js';
17
+ export * from './packages/energy-app-appliance.js';
16
18
  export * from './implementations/appliances/appliance-manager.js';
17
19
  export * from './implementations/appliances/identifier-strategies.js';
18
20
  export * from './implementations/network-devices/network-access-guard.js';
@@ -1,4 +1,4 @@
1
- import { BatteryCommandForecast, ChargerForecast, HeatpumpForecast } from '../types/enyo-appliance-command-forecast.js';
1
+ import { BatteryCommandForecast, ChargerForecast, HeatingRodForecast, HeatpumpForecast } from '../types/enyo-appliance-command-forecast.js';
2
2
  /**
3
3
  * SDK accessor for the **Appliance Energy-Manager Forecast** package.
4
4
  *
@@ -16,6 +16,10 @@ import { BatteryCommandForecast, ChargerForecast, HeatpumpForecast } from '../ty
16
16
  * carry the forecasted DHW / room / buffer-tank temperatures together
17
17
  * with planned boost / pre-heating flags and the available-power
18
18
  * announcement at each slot ({@link HeatpumpForecast}).
19
+ * - **Heating rods** — a single relative schedule whose entries carry
20
+ * the forecasted target temperature together with the planned heating
21
+ * flag and the available-power announcement at each slot
22
+ * ({@link HeatingRodForecast}).
19
23
  *
20
24
  * Every forecast optionally carries
21
25
  * {@link ApplianceForecastEstimatedSavings} so downstream consumers can
@@ -85,4 +89,20 @@ export interface EnergyAppApplianceEnergyManagerForecast {
85
89
  * is malformed.
86
90
  */
87
91
  publishHeatpumpForecast(applianceId: string, forecast: HeatpumpForecast): Promise<void>;
92
+ /**
93
+ * Publishes the command-plan forecast for a heating rod (immersion
94
+ * element). The forecast carries a single relative schedule whose
95
+ * entries pack the forecasted target temperature together with the
96
+ * planned heating flag and the available-power announcement at each
97
+ * slot.
98
+ *
99
+ * Validates {@link forecast} against the invariants documented on
100
+ * {@link HeatingRodForecast}.
101
+ *
102
+ * @param applianceId - The heating rod appliance the forecast applies to.
103
+ * @param forecast - The command-plan forecast and its metadata.
104
+ * @throws {ApplianceCommandForecastValidationError} If the forecast
105
+ * is malformed.
106
+ */
107
+ publishHeatingRodForecast(applianceId: string, forecast: HeatingRodForecast): Promise<void>;
88
108
  }
@@ -1,4 +1,30 @@
1
- import { EnyoAppliance } from "../types/enyo-appliance.js";
1
+ import { EnyoAppliance, EnyoApplianceTypeEnum } from "../types/enyo-appliance.js";
2
+ /**
3
+ * Ownership scope for an appliance-created subscription.
4
+ * - `'own'`: appliances created by your own package.
5
+ * - `'all'`: every appliance created system-wide.
6
+ * - `'external'`: only appliances created by *other* packages (all minus own).
7
+ */
8
+ export type EnyoApplianceCreatedScope = 'own' | 'all' | 'external';
9
+ /**
10
+ * Optional filter controlling which appliance-created events a listener receives.
11
+ * When omitted, defaults to `scope: 'own'` and no category restriction.
12
+ */
13
+ export interface EnyoApplianceCreatedFilter {
14
+ /**
15
+ * Ownership scope of the subscription:
16
+ * - `'own'` (default): appliances created by your own package.
17
+ * - `'all'`: every appliance created system-wide. Requires the `AllAppliances` permission.
18
+ * - `'external'`: only appliances created by *other* packages (all minus own). Requires the `AllAppliances` permission.
19
+ */
20
+ scope?: EnyoApplianceCreatedScope;
21
+ /**
22
+ * When set, the listener only fires for appliances whose
23
+ * {@link EnyoApplianceTypeEnum category} is included in this list. When
24
+ * omitted, appliances of every category are delivered.
25
+ */
26
+ types?: EnyoApplianceTypeEnum[];
27
+ }
2
28
  /**
3
29
  * Interface for managing appliances in enyo packages.
4
30
  * Provides CRUD operations for appliance registration and management.
@@ -26,9 +52,24 @@ export interface EnergyAppAppliance {
26
52
  * @returns A unique listener ID that can be used to remove the listener
27
53
  */
28
54
  listenForApplianceRemoved: (listener: (applianceId: string) => void | Promise<void>) => string;
55
+ /**
56
+ * Listen for newly-created appliances. Fires only when an appliance is
57
+ * first created — not on subsequent updates (use
58
+ * {@link listenForApplianceUpdated} for those).
59
+ *
60
+ * The optional {@link EnyoApplianceCreatedFilter filter} controls scope and
61
+ * category: by default only your own package's creations are delivered;
62
+ * `scope: 'all'` and `scope: 'external'` observe appliances created by other
63
+ * packages and require the `AllAppliances` permission.
64
+ *
65
+ * @param listener - Callback invoked with each newly-created appliance
66
+ * @param filter - Optional scope/category filter; defaults to `{ scope: 'own' }`
67
+ * @returns A unique listener ID that can be used to remove the listener
68
+ */
69
+ listenForApplianceCreated: (listener: (appliance: EnyoAppliance) => void | Promise<void>, filter?: EnyoApplianceCreatedFilter) => string;
29
70
  /**
30
71
  * Removes a previously registered listener.
31
- * @param listenerId - The ID returned by listenForApplianceUpdated or listenForApplianceRemoved
72
+ * @param listenerId - The ID returned by listenForApplianceUpdated, listenForApplianceRemoved, or listenForApplianceCreated
32
73
  */
33
74
  removeListener: (listenerId: string) => void;
34
75
  }
@@ -354,3 +354,79 @@ export interface HeatpumpForecast extends ApplianceForecastMetadata {
354
354
  */
355
355
  relativeSchedule: HeatpumpForecastScheduleEntry[];
356
356
  }
357
+ /**
358
+ * One entry of a heating rod's relative schedule.
359
+ *
360
+ * The entry packs every per-slot piece of information the energy-manager
361
+ * forecast carries for a heating rod (immersion element): the forecasted
362
+ * target temperature, the planned heating flag, and the available-power
363
+ * announcement. The setpoint becomes active {@link seconds} after the
364
+ * forecast becomes effective and stays active until the next entry's
365
+ * `seconds` is reached.
366
+ *
367
+ * Every field other than {@link seconds} is optional — an entry may
368
+ * describe only the temperature, only the flag, only power, or any
369
+ * combination. A field that is omitted carries no information for that
370
+ * slot (it is **not** "set to zero / false"); the previous entry's value
371
+ * should be treated as still in effect.
372
+ */
373
+ export interface HeatingRodForecastScheduleEntry {
374
+ /**
375
+ * Seconds from the moment the forecast becomes effective at which
376
+ * this entry becomes active. `0` for the first entry; subsequent
377
+ * entries must be strictly increasing.
378
+ */
379
+ seconds: number;
380
+ /**
381
+ * Planned available electrical power in Watts the energy manager
382
+ * intends to make available to the heating rod during this slot. The
383
+ * heating rod is free to consume up to this value — and free to
384
+ * consume less if it cannot use it all. Non-negative when present.
385
+ */
386
+ powerW?: number;
387
+ /**
388
+ * Forecasted target temperature in °C at this slot (the temperature
389
+ * the heating rod is driving its tank / buffer toward). Plausible
390
+ * range: [-50, 150].
391
+ */
392
+ temperatureC?: number;
393
+ /**
394
+ * Whether the heating rod is planned to be actively heating during
395
+ * this slot — `true` while the publisher intends to drive the tank
396
+ * up, `false` (or omitted) otherwise.
397
+ */
398
+ heatingActive?: boolean;
399
+ /**
400
+ * Whether the publisher is announcing available power for this slot
401
+ * — `true` when the energy-manager decision for the slot is
402
+ * "available power", meaning {@link powerW} doubles as the
403
+ * available-power offer to the heating rod (the heating rod is free
404
+ * to consume up to that value), `false` (or omitted) otherwise.
405
+ *
406
+ * This flag is independent of {@link heatingActive} and may coexist
407
+ * with it when the publisher offers available power while a heating
408
+ * window is also planned.
409
+ */
410
+ availablePowerActive?: boolean;
411
+ }
412
+ /**
413
+ * Forecasted command plan for a heating rod appliance, published via
414
+ * {@link EnergyAppApplianceEnergyManagerForecast.publishHeatingRodForecast}.
415
+ *
416
+ * A heating rod forecast is a **single** relative schedule whose entries
417
+ * carry every per-slot piece of information at once (forecasted target
418
+ * temperature, heating flag, available-power announcement). One entry per
419
+ * slot keeps the temperature trajectory and the heating decisions aligned
420
+ * by construction.
421
+ *
422
+ * The schedule must be sorted ascending by `seconds` and start at
423
+ * `seconds = 0` so the appliance has an authoritative "right now" entry.
424
+ */
425
+ export interface HeatingRodForecast extends ApplianceForecastMetadata {
426
+ /**
427
+ * Relative schedule of forecast entries. Sorted ascending by
428
+ * `seconds`, starting at `seconds = 0`. Must contain at least one
429
+ * entry.
430
+ */
431
+ relativeSchedule: HeatingRodForecastScheduleEntry[];
432
+ }
@@ -625,6 +625,12 @@ export interface EnyoDataBusAggregatedStateValuesV1 extends EnyoDataBusMessage {
625
625
  gridPowerPhase2W?: number;
626
626
  /** Grid power on phase L3 (in Watt). Negative: grid feed in, positive: grid consumption */
627
627
  gridPowerPhase3W?: number;
628
+ /**
629
+ * Time resolution of the aggregated grid power values (e.g. the sampling
630
+ * interval the `gridPowerW` / `gridPowerPhaseXW` values were measured at).
631
+ * Use `'dynamic'` when the values are forwarded as events occur.
632
+ */
633
+ gridPowerResolution: EnyoDataBusMessageResolution;
628
634
  gridConsumptionW?: number;
629
635
  gridFeedInW?: number;
630
636
  homeConsumptionW?: number;
@@ -14,12 +14,23 @@ export declare enum EnyoHeatpumpApplianceAvailableFeaturesEnum {
14
14
  /** If the heatpump reports power values (e.g. electrical power consumption in watts) */
15
15
  Power = "Power",
16
16
  /** If the heatpump is ready for calibration (i.e. has all prerequisites in place to start a calibration run) */
17
- ReadyForCalibration = "ReadyForCalibration"
17
+ ReadyForCalibration = "ReadyForCalibration",
18
+ /** If the heatpump supports cooling (reversible heatpump) */
19
+ Cooling = "Cooling"
18
20
  }
21
+ /**
22
+ * The current operating state of a heatpump.
23
+ */
19
24
  export declare enum EnyoHeatpumpApplianceModeEnum {
25
+ /** The heatpump is idle (not actively heating, cooling, or producing hot water) */
20
26
  Idle = "Idle",
27
+ /** The heatpump is actively heating */
21
28
  Heating = "Heating",
29
+ /** The heatpump is actively cooling (reversible heatpumps only) */
30
+ Cooling = "Cooling",
31
+ /** The heatpump is actively producing domestic hot water */
22
32
  DomesticHotWater = "DomesticHotWater",
33
+ /** The heatpump is running in emergency operation */
23
34
  EmergencyOperation = "EmergencyOperation"
24
35
  }
25
36
  /**
@@ -51,7 +62,10 @@ export interface EnyoHeatpumpApplianceCompressor {
51
62
  }
52
63
  export interface EnyoHeatpumpApplianceHeatingCircuit {
53
64
  index: number;
65
+ /** Target room temperature setpoint when heating (in °C) */
54
66
  targetRoomTemperatureC?: number;
67
+ /** Target room temperature setpoint when cooling (in °C). Only meaningful for cooling-capable heatpumps. */
68
+ targetCoolingRoomTemperatureC?: number;
55
69
  }
56
70
  export interface EnyoHeatpumpApplianceMetadata {
57
71
  availableFeatures: EnyoHeatpumpApplianceAvailableFeaturesEnum[];
@@ -16,12 +16,23 @@ export var EnyoHeatpumpApplianceAvailableFeaturesEnum;
16
16
  EnyoHeatpumpApplianceAvailableFeaturesEnum["Power"] = "Power";
17
17
  /** If the heatpump is ready for calibration (i.e. has all prerequisites in place to start a calibration run) */
18
18
  EnyoHeatpumpApplianceAvailableFeaturesEnum["ReadyForCalibration"] = "ReadyForCalibration";
19
+ /** If the heatpump supports cooling (reversible heatpump) */
20
+ EnyoHeatpumpApplianceAvailableFeaturesEnum["Cooling"] = "Cooling";
19
21
  })(EnyoHeatpumpApplianceAvailableFeaturesEnum || (EnyoHeatpumpApplianceAvailableFeaturesEnum = {}));
22
+ /**
23
+ * The current operating state of a heatpump.
24
+ */
20
25
  export var EnyoHeatpumpApplianceModeEnum;
21
26
  (function (EnyoHeatpumpApplianceModeEnum) {
27
+ /** The heatpump is idle (not actively heating, cooling, or producing hot water) */
22
28
  EnyoHeatpumpApplianceModeEnum["Idle"] = "Idle";
29
+ /** The heatpump is actively heating */
23
30
  EnyoHeatpumpApplianceModeEnum["Heating"] = "Heating";
31
+ /** The heatpump is actively cooling (reversible heatpumps only) */
32
+ EnyoHeatpumpApplianceModeEnum["Cooling"] = "Cooling";
33
+ /** The heatpump is actively producing domestic hot water */
24
34
  EnyoHeatpumpApplianceModeEnum["DomesticHotWater"] = "DomesticHotWater";
35
+ /** The heatpump is running in emergency operation */
25
36
  EnyoHeatpumpApplianceModeEnum["EmergencyOperation"] = "EmergencyOperation";
26
37
  })(EnyoHeatpumpApplianceModeEnum || (EnyoHeatpumpApplianceModeEnum = {}));
27
38
  /**
package/dist/version.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export declare const SDK_VERSION = "0.0.174";
8
+ export declare const SDK_VERSION = "0.0.176";
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
package/dist/version.js CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export const SDK_VERSION = '0.0.174';
8
+ export const SDK_VERSION = '0.0.176';
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enyo-energy/energy-app-sdk",
3
- "version": "0.0.174",
3
+ "version": "0.0.176",
4
4
  "description": "enyo Energy App SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",