@enyo-energy/energy-app-sdk 1.43.0 → 1.44.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.
- package/README.md +35 -2
- package/dist/cjs/energy-app-permission.type.cjs +2 -0
- package/dist/cjs/energy-app-permission.type.d.cts +3 -1
- package/dist/cjs/energy-app.cjs +26 -0
- package/dist/cjs/energy-app.d.cts +24 -0
- package/dist/cjs/enyo-energy-app-sdk.d.cts +6 -0
- package/dist/cjs/implementations/heatpump/heatpump-curve-optimization-rooms.cjs +96 -0
- package/dist/cjs/implementations/heatpump/heatpump-curve-optimization-rooms.d.cts +65 -0
- package/dist/cjs/implementations/heatpump/heatpump-metadata-validators.cjs +1 -21
- package/dist/cjs/index.cjs +5 -0
- package/dist/cjs/index.d.cts +5 -0
- package/dist/cjs/packages/energy-app-room-temperatures.cjs +2 -0
- package/dist/cjs/packages/energy-app-room-temperatures.d.cts +51 -0
- package/dist/cjs/packages/energy-app-room.cjs +2 -0
- package/dist/cjs/packages/energy-app-room.d.cts +59 -0
- package/dist/cjs/types/enyo-heatpump-appliance.cjs +2 -1
- package/dist/cjs/types/enyo-heatpump-appliance.d.cts +12 -39
- package/dist/cjs/types/enyo-room-temperature.cjs +2 -0
- package/dist/cjs/types/enyo-room-temperature.d.cts +102 -0
- package/dist/cjs/types/enyo-room.cjs +37 -0
- package/dist/cjs/types/enyo-room.d.cts +60 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/energy-app-permission.type.d.ts +3 -1
- package/dist/energy-app-permission.type.js +2 -0
- package/dist/energy-app.d.ts +24 -0
- package/dist/energy-app.js +26 -0
- package/dist/enyo-energy-app-sdk.d.ts +6 -0
- package/dist/implementations/heatpump/heatpump-curve-optimization-rooms.d.ts +65 -0
- package/dist/implementations/heatpump/heatpump-curve-optimization-rooms.js +89 -0
- package/dist/implementations/heatpump/heatpump-metadata-validators.js +1 -21
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/packages/energy-app-room-temperatures.d.ts +51 -0
- package/dist/packages/energy-app-room-temperatures.js +1 -0
- package/dist/packages/energy-app-room.d.ts +59 -0
- package/dist/packages/energy-app-room.js +1 -0
- package/dist/types/enyo-heatpump-appliance.d.ts +12 -39
- package/dist/types/enyo-heatpump-appliance.js +2 -1
- package/dist/types/enyo-room-temperature.d.ts +102 -0
- package/dist/types/enyo-room-temperature.js +1 -0
- package/dist/types/enyo-room.d.ts +60 -0
- package/dist/types/enyo-room.js +34 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -409,6 +409,8 @@ Energy Apps use a granular permissions system to control access to system resour
|
|
|
409
409
|
- **`GridFeeRegister`** / **`GridFeeUse`**: Publish / resolve dynamic grid fees (time-variable network charges)
|
|
410
410
|
- **`CommandLog`**: Record and read back the commands apps issued to appliances
|
|
411
411
|
- **`Subscriptions`**: Read the subscriptions bought for the app on this device
|
|
412
|
+
- **`Room`**: Read the rooms of the home the customer set up in the enyo app
|
|
413
|
+
- **`RoomTemperatures`**: Read the current and past temperatures measured in those rooms
|
|
412
414
|
|
|
413
415
|
#### Site & Identity Permissions
|
|
414
416
|
|
|
@@ -1768,6 +1770,37 @@ const full = await location.getLocation(); // requires LocationC
|
|
|
1768
1770
|
if (full) console.log(`lat=${full.latitude} lon=${full.longitude}`);
|
|
1769
1771
|
```
|
|
1770
1772
|
|
|
1773
|
+
#### `useRoom(): EnergyAppRoom`
|
|
1774
|
+
|
|
1775
|
+
Read the rooms of the home, as the customer set them up in the enyo app: name, the appliances in each, the temperature the customer wants there (`targetTemperatureC`, optional — use `HEATPUMP_CURVE_OPTIMIZATION_DEFAULT_TARGET_C` = 21 °C until set) and, for the heating curve optimisation, the room's `warmth` (`EnyoRoomWarmthEnum`) and `thermostat` (`EnyoRoomThermostatEnum`). Read-only.
|
|
1776
|
+
|
|
1777
|
+
```typescript
|
|
1778
|
+
const rooms = energyApp.useRoom();
|
|
1779
|
+
|
|
1780
|
+
applyRooms(await rooms.getRooms());
|
|
1781
|
+
const circuitRooms = await rooms.getRoomsById(circuit.curveOptimization?.roomIds ?? []);
|
|
1782
|
+
rooms.listenForRoomsChanged((all) => applyRooms(all));
|
|
1783
|
+
```
|
|
1784
|
+
|
|
1785
|
+
Requires the `Room` permission.
|
|
1786
|
+
|
|
1787
|
+
#### `useRoomTemperatures(): EnergyAppRoomTemperatures`
|
|
1788
|
+
|
|
1789
|
+
Read the temperatures measured in the rooms, per sensor — a room can have several. `getCurrentRoomTemperatures(roomIds)` returns the latest reading of each sensor, `getRoomTemperatureHistory({roomIds, startDateIso, endDateIso, resolution})` the past ones in `'1m'` or `'15m'` buckets (average, min, max). There is no listener: follow the sensors named in the current values (`applianceId`, `sensorId`) via `TemperatureSensorValuesUpdateV1` on the data bus.
|
|
1790
|
+
|
|
1791
|
+
```typescript
|
|
1792
|
+
const roomTemperatures = energyApp.useRoomTemperatures();
|
|
1793
|
+
|
|
1794
|
+
const current = await roomTemperatures.getCurrentRoomTemperatures(['living', 'bath']);
|
|
1795
|
+
const history = await roomTemperatures.getRoomTemperatureHistory({
|
|
1796
|
+
roomIds: ['living', 'bath'],
|
|
1797
|
+
startDateIso: '2026-10-27T00:00:00Z',
|
|
1798
|
+
endDateIso: '2026-10-28T00:00:00Z',
|
|
1799
|
+
});
|
|
1800
|
+
```
|
|
1801
|
+
|
|
1802
|
+
Requires the `RoomTemperatures` permission.
|
|
1803
|
+
|
|
1771
1804
|
#### `useGridConnectionPoint(): EnergyAppGridConnectionPoint`
|
|
1772
1805
|
|
|
1773
1806
|
Read the site's grid connection details — main fuse rating, number of phases, the maximum allowed grid power, and the total power that load balancing may allocate to EV chargers. Use this to size dispatch envelopes and avoid violating the contractual cap.
|
|
@@ -3751,7 +3784,7 @@ Shifts the heating curve of one heating circuit in parallel — **permanently**,
|
|
|
3751
3784
|
- **Changed by hand.** If the curve read from the device differs from `initialHeatingCurve` shifted by `activeHeatingCurveOffsetK` by more than 0.5 K at any point (`isHeatingCurveManuallyChanged(initial, offsetK, read)`), store the read curve as the new `initialHeatingCurve`, set `activeHeatingCurveOffsetK` to `0` and log it in a plain sentence.
|
|
3752
3785
|
- **Alongside `HeatpumpControlV3` and `HeatpumpProgramSwitchV3`.** Boost and eco act on top; the offset is the new base.
|
|
3753
3786
|
- **Validation** (run by the base class before the handler via `checkHeatingCurveOffset`, or `validateHeatpumpHeatingCurveOffset(data, metadata)` directly): a valid index and finite `offsetK` (`Rejected`); `HeatingCurveOffset` declared (`NotSupported`); a known circuit and — unless `offsetK` is `0` — within `heatingCurveOffsetRangeK` (`Rejected`).
|
|
3754
|
-
- **Customer settings.** Whether to optimise at all, and which rooms of the home the circuit heats (`roomIds`, whether or not a room has a sensor), live in `heatingCircuits[].curveOptimization`. The
|
|
3787
|
+
- **Customer settings.** Whether to optimise at all, and which rooms of the home the circuit heats (`roomIds`, whether or not a room has a sensor), live in `heatingCircuits[].curveOptimization`. The rooms themselves come from `useRoom().getRoomsById(roomIds)`, their measured temperatures from `useRoomTemperatures()`; `curveOptimizationRooms(curveOptimization, rooms)` picks the ones the curve is judged by (the warmest rooms behind a manual thermostat, and every room with a self-regulating thermostat or none). A room at its target means the curve is just right when its thermostat is open, but only a room falling below its target shows the curve went too far behind a self-regulating one. Rooms without a sensor are left out; the room furthest below its target counts, and the curve is lowered by at most `HEATPUMP_CURVE_OPTIMIZATION_MAX_LOWERING_K` (3 K). Integrations only read them.
|
|
3755
3788
|
|
|
3756
3789
|
```typescript
|
|
3757
3790
|
protected async handleHeatpumpHeatingCurveOffset(message: EnyoDataBusSetHeatpumpHeatingCurveOffsetV1) {
|
|
@@ -3807,7 +3840,7 @@ Beyond tanks and circuits, the heatpump metadata (`EnyoHeatpumpApplianceMetadata
|
|
|
3807
3840
|
| `RoomTemperature` | `heatingCircuits[].roomTemperatureC` in `HeatpumpTemperaturesUpdateV1`; where it is measured goes in `heatingCircuits[].roomTemperatureSource` (`None` / `Internal` / `External`) and, for an enyo sensor, `roomTemperatureSensor` |
|
|
3808
3841
|
| `RoomTemperatureInput` | The heatpump accepts measured room temperatures via `SetHeatpumpRoomTemperatureV1` |
|
|
3809
3842
|
| `HeatingCurveOffset` | The heatpump's app shifts a circuit's curve via `SetHeatpumpHeatingCurveOffsetV1`. `heatingCircuits[].heatingCurveOffsetRangeK` (allowed range, must contain 0), `activeHeatingCurveOffsetK` (effective shift read back) and `initialHeatingCurve` (the curve before the first shift) |
|
|
3810
|
-
| — | `heatingCircuits[].curveOptimization` — the customer's choice for the room-temperature based curve optimisation: `enabled` (off by default)
|
|
3843
|
+
| — | `heatingCircuits[].curveOptimization` — the customer's choice for the room-temperature based curve optimisation: `enabled` (off by default) and `roomIds` (the rooms the circuit heats, see `useRoom()`). Customer-owned; integrations only read it |
|
|
3811
3844
|
| — | `building.recommendedHeatingCurve` — the curve the building actually needs, learned from the days the room held its target |
|
|
3812
3845
|
| `PvSurplusSignal` | The heatpump takes `availablePowerW` of `HeatpumpControlV3` as a PV surplus signal (e.g. Lambda register 102). Supersedes the deprecated `AvailablePowerAnnouncement` |
|
|
3813
3846
|
| `ControlV3` | The heatpump's app handles `HeatpumpControlV3` / `HeatpumpControlCancelV3` and reports `HeatpumpControlStatusV3`. The energy manager sends V3 only to heatpumps declaring it. Needs at least one overheating feature to be actionable |
|
|
@@ -69,4 +69,6 @@ var EnergyAppPermissionTypeEnum;
|
|
|
69
69
|
EnergyAppPermissionTypeEnum["VehicleIntegration"] = "VehicleIntegration";
|
|
70
70
|
EnergyAppPermissionTypeEnum["Webhook"] = "Webhook";
|
|
71
71
|
EnergyAppPermissionTypeEnum["Subscriptions"] = "Subscriptions";
|
|
72
|
+
EnergyAppPermissionTypeEnum["Room"] = "Room";
|
|
73
|
+
EnergyAppPermissionTypeEnum["RoomTemperatures"] = "RoomTemperatures";
|
|
72
74
|
})(EnergyAppPermissionTypeEnum || (exports.EnergyAppPermissionTypeEnum = EnergyAppPermissionTypeEnum = {}));
|
|
@@ -64,7 +64,9 @@ export declare enum EnergyAppPermissionTypeEnum {
|
|
|
64
64
|
Calibration = "Calibration",
|
|
65
65
|
VehicleIntegration = "VehicleIntegration",
|
|
66
66
|
Webhook = "Webhook",
|
|
67
|
-
Subscriptions = "Subscriptions"
|
|
67
|
+
Subscriptions = "Subscriptions",
|
|
68
|
+
Room = "Room",
|
|
69
|
+
RoomTemperatures = "RoomTemperatures"
|
|
68
70
|
}
|
|
69
71
|
/**
|
|
70
72
|
* String union of every permission name, derived from
|
package/dist/cjs/energy-app.cjs
CHANGED
|
@@ -552,6 +552,32 @@ class EnergyApp {
|
|
|
552
552
|
useSubscriptions() {
|
|
553
553
|
return this.energyAppSdk.useSubscriptions();
|
|
554
554
|
}
|
|
555
|
+
/**
|
|
556
|
+
* Gets the Room API for reading the rooms of the home: their name, the
|
|
557
|
+
* appliances in them, the temperature the customer wants there and, for
|
|
558
|
+
* the heating curve optimisation, their warmth and thermostat. Read the
|
|
559
|
+
* rooms with `getRooms()` or `getRoomsById()` and react to changes with
|
|
560
|
+
* `listenForRoomsChanged()`.
|
|
561
|
+
* @returns The Room API instance
|
|
562
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `Room` permission is
|
|
563
|
+
* not granted.
|
|
564
|
+
*/
|
|
565
|
+
useRoom() {
|
|
566
|
+
return this.energyAppSdk.useRoom();
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Gets the Room Temperatures API for reading the temperatures measured in
|
|
570
|
+
* the rooms of the home, per sensor: the current values with
|
|
571
|
+
* `getCurrentRoomTemperatures()` and the past ones with
|
|
572
|
+
* `getRoomTemperatureHistory()`. Follow changes via the
|
|
573
|
+
* `TemperatureSensorValuesUpdateV1` messages on the data bus.
|
|
574
|
+
* @returns The Room Temperatures API instance
|
|
575
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `RoomTemperatures`
|
|
576
|
+
* permission is not granted.
|
|
577
|
+
*/
|
|
578
|
+
useRoomTemperatures() {
|
|
579
|
+
return this.energyAppSdk.useRoomTemperatures();
|
|
580
|
+
}
|
|
555
581
|
/**
|
|
556
582
|
* Gets the current SDK version.
|
|
557
583
|
* @returns The semantic version string of the SDK
|
|
@@ -53,6 +53,8 @@ import { EnergyAppCommandLog } from "./packages/energy-app-command-log.cjs";
|
|
|
53
53
|
import { EnergyAppCascade } from "./packages/energy-app-cascade.cjs";
|
|
54
54
|
import { EnergyAppWebhook } from "./packages/energy-app-webhook.cjs";
|
|
55
55
|
import { EnergyAppSubscriptions } from "./packages/energy-app-subscriptions.cjs";
|
|
56
|
+
import { EnergyAppRoom } from "./packages/energy-app-room.cjs";
|
|
57
|
+
import { EnergyAppRoomTemperatures } from "./packages/energy-app-room-temperatures.cjs";
|
|
56
58
|
import { UseFetchOptions } from "./types/enyo-fetch.cjs";
|
|
57
59
|
/**
|
|
58
60
|
* Concrete implementation of {@link EnyoEnergyAppSdk} that delegates every call
|
|
@@ -469,6 +471,28 @@ export declare class EnergyApp implements EnyoEnergyAppSdk {
|
|
|
469
471
|
* permission is not granted.
|
|
470
472
|
*/
|
|
471
473
|
useSubscriptions(): EnergyAppSubscriptions;
|
|
474
|
+
/**
|
|
475
|
+
* Gets the Room API for reading the rooms of the home: their name, the
|
|
476
|
+
* appliances in them, the temperature the customer wants there and, for
|
|
477
|
+
* the heating curve optimisation, their warmth and thermostat. Read the
|
|
478
|
+
* rooms with `getRooms()` or `getRoomsById()` and react to changes with
|
|
479
|
+
* `listenForRoomsChanged()`.
|
|
480
|
+
* @returns The Room API instance
|
|
481
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `Room` permission is
|
|
482
|
+
* not granted.
|
|
483
|
+
*/
|
|
484
|
+
useRoom(): EnergyAppRoom;
|
|
485
|
+
/**
|
|
486
|
+
* Gets the Room Temperatures API for reading the temperatures measured in
|
|
487
|
+
* the rooms of the home, per sensor: the current values with
|
|
488
|
+
* `getCurrentRoomTemperatures()` and the past ones with
|
|
489
|
+
* `getRoomTemperatureHistory()`. Follow changes via the
|
|
490
|
+
* `TemperatureSensorValuesUpdateV1` messages on the data bus.
|
|
491
|
+
* @returns The Room Temperatures API instance
|
|
492
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `RoomTemperatures`
|
|
493
|
+
* permission is not granted.
|
|
494
|
+
*/
|
|
495
|
+
useRoomTemperatures(): EnergyAppRoomTemperatures;
|
|
472
496
|
/**
|
|
473
497
|
* Gets the current SDK version.
|
|
474
498
|
* @returns The semantic version string of the SDK
|
|
@@ -52,6 +52,8 @@ import { EnergyAppCommandLog } from "./packages/energy-app-command-log.cjs";
|
|
|
52
52
|
import { EnergyAppCascade } from "./packages/energy-app-cascade.cjs";
|
|
53
53
|
import { EnergyAppWebhook } from "./packages/energy-app-webhook.cjs";
|
|
54
54
|
import { EnergyAppSubscriptions } from "./packages/energy-app-subscriptions.cjs";
|
|
55
|
+
import { EnergyAppRoom } from "./packages/energy-app-room.cjs";
|
|
56
|
+
import { EnergyAppRoomTemperatures } from "./packages/energy-app-room-temperatures.cjs";
|
|
55
57
|
import { UseFetchOptions } from "./types/enyo-fetch.cjs";
|
|
56
58
|
export declare enum EnergyAppStateEnum {
|
|
57
59
|
Launching = "launching",
|
|
@@ -198,4 +200,8 @@ export interface EnyoEnergyAppSdk {
|
|
|
198
200
|
useWebhook: () => EnergyAppWebhook;
|
|
199
201
|
/** Get the Subscriptions API for reading the subscriptions bought for this app on this device and listening for new or changed subscriptions */
|
|
200
202
|
useSubscriptions: () => EnergyAppSubscriptions;
|
|
203
|
+
/** Get the Room API for reading the rooms of the home the customer set up in the enyo app */
|
|
204
|
+
useRoom: () => EnergyAppRoom;
|
|
205
|
+
/** Get the Room Temperatures API for reading the current and past temperatures measured in the rooms of the home */
|
|
206
|
+
useRoomTemperatures: () => EnergyAppRoomTemperatures;
|
|
201
207
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Which rooms of a heating circuit the room-temperature based heating curve
|
|
4
|
+
* optimisation is judged by. Shared by the energy manager, which lowers the
|
|
5
|
+
* curve, and the host's app, which tells the customer how to set each room's
|
|
6
|
+
* thermostat — both must agree on it.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.curveWarmthRank = curveWarmthRank;
|
|
10
|
+
exports.isManualRoomThermostat = isManualRoomThermostat;
|
|
11
|
+
exports.curveTopManualRank = curveTopManualRank;
|
|
12
|
+
exports.curveJudgedRoomIds = curveJudgedRoomIds;
|
|
13
|
+
exports.curveOptimizationRooms = curveOptimizationRooms;
|
|
14
|
+
const enyo_room_js_1 = require("../../types/enyo-room.cjs");
|
|
15
|
+
const WARMTH_RANK = {
|
|
16
|
+
[enyo_room_js_1.EnyoRoomWarmthEnum.Cool]: 0,
|
|
17
|
+
[enyo_room_js_1.EnyoRoomWarmthEnum.Normal]: 1,
|
|
18
|
+
[enyo_room_js_1.EnyoRoomWarmthEnum.Warm]: 2,
|
|
19
|
+
};
|
|
20
|
+
const MANUAL_THERMOSTATS = new Set([
|
|
21
|
+
enyo_room_js_1.EnyoRoomThermostatEnum.Steps5,
|
|
22
|
+
enyo_room_js_1.EnyoRoomThermostatEnum.Steps6,
|
|
23
|
+
enyo_room_js_1.EnyoRoomThermostatEnum.CelsiusDial,
|
|
24
|
+
]);
|
|
25
|
+
/**
|
|
26
|
+
* How much warmth a room asks for compared with the other rooms of its
|
|
27
|
+
* circuit: 0 for `cool`, 1 for `normal` (also when absent), 2 for `warm`.
|
|
28
|
+
*
|
|
29
|
+
* @param traits - The room's warmth, if known.
|
|
30
|
+
* @returns The rank.
|
|
31
|
+
*/
|
|
32
|
+
function curveWarmthRank(traits) {
|
|
33
|
+
return WARMTH_RANK[traits?.warmth ?? enyo_room_js_1.EnyoRoomWarmthEnum.Normal];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Whether a thermostat is set by hand: a dial with steps or a dial in °C.
|
|
37
|
+
* Absent counts as the common dial with steps 1–5.
|
|
38
|
+
*
|
|
39
|
+
* @param thermostat - The room's thermostat.
|
|
40
|
+
* @returns `true` for a manual thermostat.
|
|
41
|
+
*/
|
|
42
|
+
function isManualRoomThermostat(thermostat) {
|
|
43
|
+
return thermostat === undefined || MANUAL_THERMOSTATS.has(thermostat);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* How much warmth the most demanding room behind a manual thermostat asks for.
|
|
47
|
+
*
|
|
48
|
+
* @param roomIds - The rooms of the circuit.
|
|
49
|
+
* @param traitsOf - A room's warmth and thermostat.
|
|
50
|
+
* @returns The highest rank, or `undefined` when no room has a manual thermostat.
|
|
51
|
+
*/
|
|
52
|
+
function curveTopManualRank(roomIds, traitsOf) {
|
|
53
|
+
const ranks = roomIds
|
|
54
|
+
.filter((roomId) => isManualRoomThermostat(traitsOf(roomId)?.thermostat))
|
|
55
|
+
.map((roomId) => curveWarmthRank(traitsOf(roomId)));
|
|
56
|
+
return ranks.length > 0 ? Math.max(...ranks) : undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The rooms of a heating circuit the curve is judged by. One flow temperature
|
|
60
|
+
* heats every room of the circuit, so the curve has to serve the warmest wish:
|
|
61
|
+
* of the rooms with a manual thermostat, those asking for the most warmth keep
|
|
62
|
+
* it fully open and show what the curve does. Every other one is held back by
|
|
63
|
+
* its thermostat, reads the thermostat rather than the curve, and would mislead
|
|
64
|
+
* the controller. A room with no thermostat follows the curve, and one with a
|
|
65
|
+
* self-regulating thermostat holds its own target — both are always judged.
|
|
66
|
+
*
|
|
67
|
+
* @param roomIds - The rooms of the circuit.
|
|
68
|
+
* @param traitsOf - A room's warmth and thermostat.
|
|
69
|
+
* @returns The judged room IDs, in the order given.
|
|
70
|
+
*/
|
|
71
|
+
function curveJudgedRoomIds(roomIds, traitsOf) {
|
|
72
|
+
const top = curveTopManualRank(roomIds, traitsOf);
|
|
73
|
+
return roomIds.filter((roomId) => {
|
|
74
|
+
const traits = traitsOf(roomId);
|
|
75
|
+
return !isManualRoomThermostat(traits?.thermostat) || curveWarmthRank(traits) === top;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The rooms a heating circuit's curve optimisation is judged by, resolved
|
|
80
|
+
* against the rooms of the home ({@link EnergyAppRoom.getRooms} or
|
|
81
|
+
* {@link EnergyAppRoom.getRoomsById}). A room that no longer exists is
|
|
82
|
+
* dropped. Whether a judged room can be measured is up to
|
|
83
|
+
* {@link EnergyAppRoomTemperatures}.
|
|
84
|
+
*
|
|
85
|
+
* @param settings - The circuit's {@link EnyoHeatpumpApplianceHeatingCircuit.curveOptimization}.
|
|
86
|
+
* @param rooms - Every room of the home.
|
|
87
|
+
* @returns The judged rooms, in the order of `settings.roomIds`.
|
|
88
|
+
*/
|
|
89
|
+
function curveOptimizationRooms(settings, rooms) {
|
|
90
|
+
const live = (settings?.roomIds ?? []).flatMap((roomId) => {
|
|
91
|
+
const room = rooms.find((candidate) => candidate.id === roomId);
|
|
92
|
+
return room ? [room] : [];
|
|
93
|
+
});
|
|
94
|
+
const judged = curveJudgedRoomIds(live.map((room) => room.id), (roomId) => live.find((room) => room.id === roomId));
|
|
95
|
+
return live.filter((room) => judged.includes(room.id));
|
|
96
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which rooms of a heating circuit the room-temperature based heating curve
|
|
3
|
+
* optimisation is judged by. Shared by the energy manager, which lowers the
|
|
4
|
+
* curve, and the host's app, which tells the customer how to set each room's
|
|
5
|
+
* thermostat — both must agree on it.
|
|
6
|
+
*/
|
|
7
|
+
import type { EnyoHeatpumpHeatingCurveOptimizationSettings } from '../../types/enyo-heatpump-appliance.cjs';
|
|
8
|
+
import { type EnyoRoom, EnyoRoomThermostatEnum, EnyoRoomWarmthEnum } from '../../types/enyo-room.cjs';
|
|
9
|
+
/** What the curve rules need to know about a room. */
|
|
10
|
+
export interface CurveRoomTraits {
|
|
11
|
+
/** Absent: {@link EnyoRoomWarmthEnum.Normal}. */
|
|
12
|
+
warmth?: EnyoRoomWarmthEnum;
|
|
13
|
+
/** Absent: {@link EnyoRoomThermostatEnum.Steps5}. */
|
|
14
|
+
thermostat?: EnyoRoomThermostatEnum;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* How much warmth a room asks for compared with the other rooms of its
|
|
18
|
+
* circuit: 0 for `cool`, 1 for `normal` (also when absent), 2 for `warm`.
|
|
19
|
+
*
|
|
20
|
+
* @param traits - The room's warmth, if known.
|
|
21
|
+
* @returns The rank.
|
|
22
|
+
*/
|
|
23
|
+
export declare function curveWarmthRank(traits: CurveRoomTraits | undefined): number;
|
|
24
|
+
/**
|
|
25
|
+
* Whether a thermostat is set by hand: a dial with steps or a dial in °C.
|
|
26
|
+
* Absent counts as the common dial with steps 1–5.
|
|
27
|
+
*
|
|
28
|
+
* @param thermostat - The room's thermostat.
|
|
29
|
+
* @returns `true` for a manual thermostat.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isManualRoomThermostat(thermostat: EnyoRoomThermostatEnum | undefined): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* How much warmth the most demanding room behind a manual thermostat asks for.
|
|
34
|
+
*
|
|
35
|
+
* @param roomIds - The rooms of the circuit.
|
|
36
|
+
* @param traitsOf - A room's warmth and thermostat.
|
|
37
|
+
* @returns The highest rank, or `undefined` when no room has a manual thermostat.
|
|
38
|
+
*/
|
|
39
|
+
export declare function curveTopManualRank(roomIds: readonly string[], traitsOf: (roomId: string) => CurveRoomTraits | undefined): number | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* The rooms of a heating circuit the curve is judged by. One flow temperature
|
|
42
|
+
* heats every room of the circuit, so the curve has to serve the warmest wish:
|
|
43
|
+
* of the rooms with a manual thermostat, those asking for the most warmth keep
|
|
44
|
+
* it fully open and show what the curve does. Every other one is held back by
|
|
45
|
+
* its thermostat, reads the thermostat rather than the curve, and would mislead
|
|
46
|
+
* the controller. A room with no thermostat follows the curve, and one with a
|
|
47
|
+
* self-regulating thermostat holds its own target — both are always judged.
|
|
48
|
+
*
|
|
49
|
+
* @param roomIds - The rooms of the circuit.
|
|
50
|
+
* @param traitsOf - A room's warmth and thermostat.
|
|
51
|
+
* @returns The judged room IDs, in the order given.
|
|
52
|
+
*/
|
|
53
|
+
export declare function curveJudgedRoomIds(roomIds: readonly string[], traitsOf: (roomId: string) => CurveRoomTraits | undefined): string[];
|
|
54
|
+
/**
|
|
55
|
+
* The rooms a heating circuit's curve optimisation is judged by, resolved
|
|
56
|
+
* against the rooms of the home ({@link EnergyAppRoom.getRooms} or
|
|
57
|
+
* {@link EnergyAppRoom.getRoomsById}). A room that no longer exists is
|
|
58
|
+
* dropped. Whether a judged room can be measured is up to
|
|
59
|
+
* {@link EnergyAppRoomTemperatures}.
|
|
60
|
+
*
|
|
61
|
+
* @param settings - The circuit's {@link EnyoHeatpumpApplianceHeatingCircuit.curveOptimization}.
|
|
62
|
+
* @param rooms - Every room of the home.
|
|
63
|
+
* @returns The judged rooms, in the order of `settings.roomIds`.
|
|
64
|
+
*/
|
|
65
|
+
export declare function curveOptimizationRooms(settings: EnyoHeatpumpHeatingCurveOptimizationSettings | undefined, rooms: readonly EnyoRoom[]): EnyoRoom[];
|
|
@@ -80,17 +80,13 @@ function checkProgramModes(zone, prefix, errors, warnings) {
|
|
|
80
80
|
errors.push(`${prefix}: activeProgramMode "${zone.activeProgramMode}" is not a valid value`);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
-
/** Range the customer may choose for a room's `targetRoomTemperatureC`, in °C. */
|
|
84
|
-
const CURVE_OPTIMIZATION_TARGET_RANGE_C = { min: 16, max: 26 };
|
|
85
83
|
/**
|
|
86
84
|
* Validates the heating-curve-offset fields of one heating circuit
|
|
87
85
|
* (`heatingCurveOffsetRangeK`, `activeHeatingCurveOffsetK`,
|
|
88
86
|
* `curveOptimization`) and appends the problems to `errors`.
|
|
89
87
|
*
|
|
90
88
|
* Errors: the range is not finite or does not contain `0`; the active offset
|
|
91
|
-
* is not finite or lies outside the range; a room id is empty
|
|
92
|
-
* lacks its `roomId`, a sensor lacks its `applianceId` / `sensorId`, or its
|
|
93
|
-
* target lies outside 16…26 °C.
|
|
89
|
+
* is not finite or lies outside the range; a room id is empty.
|
|
94
90
|
*
|
|
95
91
|
* @param circuit - The heating circuit.
|
|
96
92
|
* @param prefix - Path prefix for the messages, e.g. `heatingCircuits[index=0]`.
|
|
@@ -124,22 +120,6 @@ function checkHeatingCurveOffset(circuit, prefix, errors) {
|
|
|
124
120
|
errors.push(`${prefix}: curveOptimization.roomIds[${i}] must be a non-empty string`);
|
|
125
121
|
}
|
|
126
122
|
});
|
|
127
|
-
(settings.rooms ?? []).forEach((room, i) => {
|
|
128
|
-
if (!room?.roomId) {
|
|
129
|
-
errors.push(`${prefix}: curveOptimization.rooms[${i}] needs a roomId`);
|
|
130
|
-
}
|
|
131
|
-
(room?.sensors ?? []).forEach((sensor, j) => {
|
|
132
|
-
if (!sensor?.applianceId || !sensor?.sensorId) {
|
|
133
|
-
errors.push(`${prefix}: curveOptimization.rooms[${i}].sensors[${j}] needs applianceId and sensorId`);
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
const target = room?.targetRoomTemperatureC;
|
|
137
|
-
if (!(isFiniteNumber(target)
|
|
138
|
-
&& target >= CURVE_OPTIMIZATION_TARGET_RANGE_C.min && target <= CURVE_OPTIMIZATION_TARGET_RANGE_C.max)) {
|
|
139
|
-
errors.push(`${prefix}: curveOptimization.rooms[${i}].targetRoomTemperatureC must lie within ` +
|
|
140
|
-
`${CURVE_OPTIMIZATION_TARGET_RANGE_C.min}…${CURVE_OPTIMIZATION_TARGET_RANGE_C.max} °C; got ${target}`);
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
123
|
}
|
|
144
124
|
/**
|
|
145
125
|
* Parses an `HH:mm` time of day into minutes since midnight.
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -110,6 +110,7 @@ __exportStar(require("./implementations/heatpump/heatpump-control-validators.cjs
|
|
|
110
110
|
__exportStar(require("./implementations/heatpump/heatpump-control-session.cjs"), exports);
|
|
111
111
|
__exportStar(require("./implementations/heatpump/heatpump-flexibility-validators.cjs"), exports);
|
|
112
112
|
__exportStar(require("./implementations/heatpump/heatpump-heating-curve-offset.cjs"), exports);
|
|
113
|
+
__exportStar(require("./implementations/heatpump/heatpump-curve-optimization-rooms.cjs"), exports);
|
|
113
114
|
__exportStar(require("./types/enyo-inverter-appliance.cjs"), exports);
|
|
114
115
|
__exportStar(require("./types/enyo-onboarding.cjs"), exports);
|
|
115
116
|
__exportStar(require("./packages/energy-app-onboarding.cjs"), exports);
|
|
@@ -193,6 +194,10 @@ __exportStar(require("./types/enyo-webhook.cjs"), exports);
|
|
|
193
194
|
__exportStar(require("./packages/energy-app-webhook.cjs"), exports);
|
|
194
195
|
__exportStar(require("./types/enyo-subscription.cjs"), exports);
|
|
195
196
|
__exportStar(require("./packages/energy-app-subscriptions.cjs"), exports);
|
|
197
|
+
__exportStar(require("./types/enyo-room.cjs"), exports);
|
|
198
|
+
__exportStar(require("./packages/energy-app-room.cjs"), exports);
|
|
199
|
+
__exportStar(require("./types/enyo-room-temperature.cjs"), exports);
|
|
200
|
+
__exportStar(require("./packages/energy-app-room-temperatures.cjs"), exports);
|
|
196
201
|
__exportStar(require("./implementations/subscriptions/define-subscription-plan.cjs"), exports);
|
|
197
202
|
__exportStar(require("./implementations/subscriptions/subscription-plan-validators.cjs"), exports);
|
|
198
203
|
__exportStar(require("./implementations/subscriptions/in-memory-subscriptions.cjs"), exports);
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -94,6 +94,7 @@ export * from './implementations/heatpump/heatpump-control-validators.cjs';
|
|
|
94
94
|
export * from './implementations/heatpump/heatpump-control-session.cjs';
|
|
95
95
|
export * from './implementations/heatpump/heatpump-flexibility-validators.cjs';
|
|
96
96
|
export * from './implementations/heatpump/heatpump-heating-curve-offset.cjs';
|
|
97
|
+
export * from './implementations/heatpump/heatpump-curve-optimization-rooms.cjs';
|
|
97
98
|
export * from './types/enyo-inverter-appliance.cjs';
|
|
98
99
|
export * from './types/enyo-onboarding.cjs';
|
|
99
100
|
export * from './packages/energy-app-onboarding.cjs';
|
|
@@ -177,6 +178,10 @@ export * from './types/enyo-webhook.cjs';
|
|
|
177
178
|
export * from './packages/energy-app-webhook.cjs';
|
|
178
179
|
export * from './types/enyo-subscription.cjs';
|
|
179
180
|
export * from './packages/energy-app-subscriptions.cjs';
|
|
181
|
+
export * from './types/enyo-room.cjs';
|
|
182
|
+
export * from './packages/energy-app-room.cjs';
|
|
183
|
+
export * from './types/enyo-room-temperature.cjs';
|
|
184
|
+
export * from './packages/energy-app-room-temperatures.cjs';
|
|
180
185
|
export * from './implementations/subscriptions/define-subscription-plan.cjs';
|
|
181
186
|
export * from './implementations/subscriptions/subscription-plan-validators.cjs';
|
|
182
187
|
export * from './implementations/subscriptions/in-memory-subscriptions.cjs';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { EnyoRoomCurrentTemperatures, EnyoRoomTemperatureHistoryRequest, EnyoRoomTemperatureHistoryResponse } from "../types/enyo-room-temperature.cjs";
|
|
2
|
+
/**
|
|
3
|
+
* Interface for reading the temperatures measured in the rooms of the home
|
|
4
|
+
* ({@link EnergyAppRoom}), current and past. A room can have several
|
|
5
|
+
* temperature sensors; each one is reported on its own.
|
|
6
|
+
*
|
|
7
|
+
* There is no listener: to follow a room's temperatures, read the current
|
|
8
|
+
* values once and then subscribe to the
|
|
9
|
+
* {@link EnyoDataBusMessageEnum.TemperatureSensorValuesUpdateV1} messages of
|
|
10
|
+
* the sensors they name ({@link EnyoRoomTemperatureSensorReading.applianceId},
|
|
11
|
+
* {@link EnyoRoomTemperatureSensorReading.sensorId}) on the data bus.
|
|
12
|
+
*
|
|
13
|
+
* Access to this API requires the `RoomTemperatures` permission
|
|
14
|
+
* ({@link EnergyAppPermissionType}).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const roomTemperatures = energyApp.useRoomTemperatures();
|
|
19
|
+
*
|
|
20
|
+
* // Current values of the rooms a heating circuit heats.
|
|
21
|
+
* const current = await roomTemperatures.getCurrentRoomTemperatures(['living', 'bath']);
|
|
22
|
+
*
|
|
23
|
+
* // The last 24 hours in 15-minute buckets.
|
|
24
|
+
* const history = await roomTemperatures.getRoomTemperatureHistory({
|
|
25
|
+
* roomIds: ['living', 'bath'],
|
|
26
|
+
* startDateIso: '2026-10-27T00:00:00Z',
|
|
27
|
+
* endDateIso: '2026-10-28T00:00:00Z',
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export interface EnergyAppRoomTemperatures {
|
|
32
|
+
/**
|
|
33
|
+
* Returns the latest reading of every temperature sensor in the given
|
|
34
|
+
* rooms. An ID without a room is left out.
|
|
35
|
+
*
|
|
36
|
+
* @param roomIds - IDs of the rooms ({@link EnyoRoom.id}) to read
|
|
37
|
+
* @returns Promise that resolves to one entry per room found, in the order of `roomIds`
|
|
38
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `RoomTemperatures` permission is not granted.
|
|
39
|
+
*/
|
|
40
|
+
getCurrentRoomTemperatures(roomIds: string[]): Promise<EnyoRoomCurrentTemperatures[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Returns the measured temperatures of the given rooms over a time
|
|
43
|
+
* interval, per sensor and bucket. The sensors are those in the room now:
|
|
44
|
+
* a sensor moved to another room brings its earlier readings along.
|
|
45
|
+
*
|
|
46
|
+
* @param request - The rooms, the interval and the bucket size
|
|
47
|
+
* @returns Promise that resolves to the history of every room found
|
|
48
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `RoomTemperatures` permission is not granted.
|
|
49
|
+
*/
|
|
50
|
+
getRoomTemperatureHistory(request: EnyoRoomTemperatureHistoryRequest): Promise<EnyoRoomTemperatureHistoryResponse>;
|
|
51
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { EnyoRoom, EnyoRoomsChangedListener } from "../types/enyo-room.cjs";
|
|
2
|
+
/**
|
|
3
|
+
* Interface for reading the rooms of the home.
|
|
4
|
+
*
|
|
5
|
+
* Rooms are set up by the customer in the enyo app: a name, the appliances in
|
|
6
|
+
* it, the temperature the customer wants there and — for the heating curve
|
|
7
|
+
* optimisation — how warm it should be compared with the other rooms of its
|
|
8
|
+
* heating circuit and which thermostat it has. Apps only read them. The
|
|
9
|
+
* temperatures measured in a room come from {@link EnergyAppRoomTemperatures}.
|
|
10
|
+
*
|
|
11
|
+
* Access to this API requires the `Room` permission
|
|
12
|
+
* ({@link EnergyAppPermissionType}).
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const rooms = energyApp.useRoom();
|
|
17
|
+
*
|
|
18
|
+
* // On boot: read the rooms.
|
|
19
|
+
* applyRooms(await rooms.getRooms());
|
|
20
|
+
*
|
|
21
|
+
* // Afterwards: react to the customer changing a room.
|
|
22
|
+
* rooms.listenForRoomsChanged((all) => applyRooms(all));
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export interface EnergyAppRoom {
|
|
26
|
+
/**
|
|
27
|
+
* Returns every room of the home.
|
|
28
|
+
*
|
|
29
|
+
* @returns Promise that resolves to the rooms, in no particular order
|
|
30
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `Room` permission is not granted.
|
|
31
|
+
*/
|
|
32
|
+
getRooms(): Promise<EnyoRoom[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the rooms with the given IDs, e.g. the
|
|
35
|
+
* {@link EnyoHeatpumpHeatingCurveOptimizationSettings.roomIds} of a
|
|
36
|
+
* heating circuit. An ID without a room — the customer removed it — is
|
|
37
|
+
* left out.
|
|
38
|
+
*
|
|
39
|
+
* @param roomIds - IDs of the rooms to return
|
|
40
|
+
* @returns Promise that resolves to the rooms found, in the order of `roomIds`
|
|
41
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `Room` permission is not granted.
|
|
42
|
+
*/
|
|
43
|
+
getRoomsById(roomIds: string[]): Promise<EnyoRoom[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Registers a listener called with every room of the home whenever the
|
|
46
|
+
* customer creates, changes or removes one.
|
|
47
|
+
*
|
|
48
|
+
* @param listener - Callback invoked with all rooms after the change
|
|
49
|
+
* @returns A listener ID that can be passed to {@link removeListener}
|
|
50
|
+
* @throws {EnergyAppPermissionNotGrantedError} If the `Room` permission is not granted.
|
|
51
|
+
*/
|
|
52
|
+
listenForRoomsChanged(listener: EnyoRoomsChangedListener): string;
|
|
53
|
+
/**
|
|
54
|
+
* Removes a listener registered with {@link listenForRoomsChanged}.
|
|
55
|
+
*
|
|
56
|
+
* @param listenerId - The ID returned when the listener was registered
|
|
57
|
+
*/
|
|
58
|
+
removeListener(listenerId: string): void;
|
|
59
|
+
}
|
|
@@ -301,6 +301,7 @@ var EnyoHeatpumpHeatingControlReferenceEnum;
|
|
|
301
301
|
*/
|
|
302
302
|
exports.HEATPUMP_CURVE_OPTIMIZATION_MAX_LOWERING_K = 3;
|
|
303
303
|
/**
|
|
304
|
-
* The target temperature of a room whose customer has not set one, in °C
|
|
304
|
+
* The target temperature of a room whose customer has not set one, in °C
|
|
305
|
+
* ({@link EnyoRoom.targetTemperatureC}).
|
|
305
306
|
*/
|
|
306
307
|
exports.HEATPUMP_CURVE_OPTIMIZATION_DEFAULT_TARGET_C = 21;
|
|
@@ -442,36 +442,10 @@ export interface EnyoHeatpumpRoomTemperatureSensorReference {
|
|
|
442
442
|
*/
|
|
443
443
|
export declare const HEATPUMP_CURVE_OPTIMIZATION_MAX_LOWERING_K = 3;
|
|
444
444
|
/**
|
|
445
|
-
* The target temperature of a room whose customer has not set one, in °C
|
|
445
|
+
* The target temperature of a room whose customer has not set one, in °C
|
|
446
|
+
* ({@link EnyoRoom.targetTemperatureC}).
|
|
446
447
|
*/
|
|
447
448
|
export declare const HEATPUMP_CURVE_OPTIMIZATION_DEFAULT_TARGET_C = 21;
|
|
448
|
-
/**
|
|
449
|
-
* One room a heating circuit heats, as the host resolves it for the heating
|
|
450
|
-
* curve optimisation: the room's target temperature and the temperature
|
|
451
|
-
* sensors assigned to that room. Read-only for apps — the host fills it from
|
|
452
|
-
* {@link EnyoHeatpumpHeatingCurveOptimizationSettings.roomIds} and the rooms
|
|
453
|
-
* the customer set up in the enyo app.
|
|
454
|
-
*/
|
|
455
|
-
export interface EnyoHeatpumpCurveOptimizationRoom {
|
|
456
|
-
/** ID of the room in the enyo app. */
|
|
457
|
-
roomId: string;
|
|
458
|
-
/** The room's name, as the customer called it — for logs and diagnostics. */
|
|
459
|
-
name?: string;
|
|
460
|
-
/**
|
|
461
|
-
* The room temperature in °C the customer wants in this room — a setpoint
|
|
462
|
-
* of the energy manager's controller, **not** written to the heatpump.
|
|
463
|
-
* {@link HEATPUMP_CURVE_OPTIMIZATION_DEFAULT_TARGET_C} until the customer
|
|
464
|
-
* sets one. Raising it means the customer is too cold there, and the
|
|
465
|
-
* energy manager reacts at once.
|
|
466
|
-
*/
|
|
467
|
-
targetRoomTemperatureC: number;
|
|
468
|
-
/**
|
|
469
|
-
* The temperature sensors assigned to this room. Empty when the room has
|
|
470
|
-
* none: such a room is part of the circuit but cannot be judged, and the
|
|
471
|
-
* energy manager leaves it out. With several, the coldest counts.
|
|
472
|
-
*/
|
|
473
|
-
sensors: EnyoHeatpumpRoomTemperatureSensorReference[];
|
|
474
|
-
}
|
|
475
449
|
/**
|
|
476
450
|
* The range of {@link EnyoDataBusSetHeatpumpHeatingCurveOffsetV1.data}
|
|
477
451
|
* `offsetK` a heating circuit accepts, in Kelvin of flow temperature relative
|
|
@@ -487,7 +461,7 @@ export interface EnyoHeatpumpHeatingCurveOffsetRange {
|
|
|
487
461
|
/**
|
|
488
462
|
* What the customer chose for the room-temperature based optimisation of one
|
|
489
463
|
* heating circuit's heating curve: the energy manager lowers the curve as far
|
|
490
|
-
* as possible without any of the
|
|
464
|
+
* as possible without any of the circuit's rooms falling below its own target,
|
|
491
465
|
* using {@link EnyoDataBusSetHeatpumpHeatingCurveOffsetV1}.
|
|
492
466
|
*
|
|
493
467
|
* **Customer-owned.** Set in the enyo app, never by an integration: the host
|
|
@@ -503,18 +477,17 @@ export interface EnyoHeatpumpHeatingCurveOptimizationSettings {
|
|
|
503
477
|
*/
|
|
504
478
|
enabled: boolean;
|
|
505
479
|
/**
|
|
506
|
-
* IDs of the rooms (
|
|
507
|
-
*
|
|
480
|
+
* IDs of the rooms ({@link EnyoRoom.id}) this circuit heats — chosen by the
|
|
481
|
+
* customer, whether or not a room has a temperature sensor. Read the rooms
|
|
482
|
+
* with {@link EnergyAppRoom.getRoomsById}; {@link curveOptimizationRooms}
|
|
483
|
+
* picks the ones the curve is judged by, and
|
|
484
|
+
* {@link EnergyAppRoomTemperatures} gives their measured temperatures. The
|
|
485
|
+
* room furthest below its target decides how low the curve may go; rooms
|
|
486
|
+
* without a sensor are left out, and without any room that has one the
|
|
487
|
+
* optimisation cannot run. The
|
|
488
|
+
* curve is lowered by at most {@link HEATPUMP_CURVE_OPTIMIZATION_MAX_LOWERING_K}.
|
|
508
489
|
*/
|
|
509
490
|
roomIds?: string[];
|
|
510
|
-
/**
|
|
511
|
-
* Those rooms resolved by the host: each with its target and its sensors.
|
|
512
|
-
* The room furthest below its target decides how low the curve may go;
|
|
513
|
-
* rooms without a sensor are left out. Without any room that has a sensor
|
|
514
|
-
* the optimisation cannot run. The curve is lowered by at most
|
|
515
|
-
* {@link HEATPUMP_CURVE_OPTIMIZATION_MAX_LOWERING_K}. Read-only for apps.
|
|
516
|
-
*/
|
|
517
|
-
rooms?: EnyoHeatpumpCurveOptimizationRoom[];
|
|
518
491
|
}
|
|
519
492
|
/**
|
|
520
493
|
* A domestic-hot-water zone of the installation.
|