@enyo-energy/energy-app-sdk 0.0.109 → 0.0.111
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 +374 -0
- package/dist/cjs/energy-app.cjs +240 -0
- package/dist/cjs/energy-app.d.cts +177 -0
- package/dist/cjs/implementations/forecasts/battery-forecast.cjs +238 -0
- package/dist/cjs/implementations/forecasts/battery-forecast.d.cts +88 -0
- package/dist/cjs/implementations/forecasts/ev-charging-forecast.cjs +215 -0
- package/dist/cjs/implementations/forecasts/ev-charging-forecast.d.cts +74 -0
- package/dist/cjs/implementations/forecasts/forecast-types.cjs +43 -0
- package/dist/cjs/implementations/forecasts/forecast-types.d.cts +120 -0
- package/dist/cjs/implementations/forecasts/forecast-utils.cjs +303 -0
- package/dist/cjs/implementations/forecasts/forecast-utils.d.cts +159 -0
- package/dist/cjs/implementations/forecasts/heatpump-consumption-forecast.cjs +216 -0
- package/dist/cjs/implementations/forecasts/heatpump-consumption-forecast.d.cts +75 -0
- package/dist/cjs/implementations/forecasts/heatpump-dhw-temperature-forecast.cjs +225 -0
- package/dist/cjs/implementations/forecasts/heatpump-dhw-temperature-forecast.d.cts +92 -0
- package/dist/cjs/implementations/forecasts/home-consumption-forecast.cjs +186 -0
- package/dist/cjs/implementations/forecasts/home-consumption-forecast.d.cts +69 -0
- package/dist/cjs/implementations/forecasts/pv-production-forecast.cjs +198 -0
- package/dist/cjs/implementations/forecasts/pv-production-forecast.d.cts +83 -0
- package/dist/cjs/index.cjs +17 -221
- package/dist/cjs/index.d.cts +17 -160
- package/dist/cjs/integrations/air-conditioning-integration-energy-app.cjs +62 -0
- package/dist/cjs/integrations/air-conditioning-integration-energy-app.d.cts +44 -0
- package/dist/cjs/integrations/energy-manager-energy-app.cjs +206 -0
- package/dist/cjs/integrations/energy-manager-energy-app.d.cts +121 -0
- package/dist/cjs/integrations/heatpump-integration-energy-app.cjs +93 -0
- package/dist/cjs/integrations/heatpump-integration-energy-app.d.cts +88 -0
- package/dist/cjs/integrations/integration-energy-app.cjs +266 -0
- package/dist/cjs/integrations/integration-energy-app.d.cts +151 -0
- package/dist/cjs/integrations/integration-types.cjs +2 -0
- package/dist/cjs/integrations/integration-types.d.cts +73 -0
- package/dist/cjs/integrations/inverter-integration-energy-app.cjs +44 -0
- package/dist/cjs/integrations/inverter-integration-energy-app.d.cts +34 -0
- package/dist/cjs/integrations/storage-integration-energy-app.cjs +64 -0
- package/dist/cjs/integrations/storage-integration-energy-app.d.cts +49 -0
- package/dist/cjs/integrations/wallbox-integration-energy-app.cjs +136 -0
- package/dist/cjs/integrations/wallbox-integration-energy-app.d.cts +113 -0
- package/dist/cjs/packages/energy-app-timeseries.d.cts +28 -1
- package/dist/cjs/types/enyo-timeseries.d.cts +45 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/energy-app.d.ts +177 -0
- package/dist/energy-app.js +236 -0
- package/dist/implementations/forecasts/battery-forecast.d.ts +88 -0
- package/dist/implementations/forecasts/battery-forecast.js +234 -0
- package/dist/implementations/forecasts/ev-charging-forecast.d.ts +74 -0
- package/dist/implementations/forecasts/ev-charging-forecast.js +211 -0
- package/dist/implementations/forecasts/forecast-types.d.ts +120 -0
- package/dist/implementations/forecasts/forecast-types.js +39 -0
- package/dist/implementations/forecasts/forecast-utils.d.ts +159 -0
- package/dist/implementations/forecasts/forecast-utils.js +284 -0
- package/dist/implementations/forecasts/heatpump-consumption-forecast.d.ts +75 -0
- package/dist/implementations/forecasts/heatpump-consumption-forecast.js +212 -0
- package/dist/implementations/forecasts/heatpump-dhw-temperature-forecast.d.ts +92 -0
- package/dist/implementations/forecasts/heatpump-dhw-temperature-forecast.js +221 -0
- package/dist/implementations/forecasts/home-consumption-forecast.d.ts +69 -0
- package/dist/implementations/forecasts/home-consumption-forecast.js +182 -0
- package/dist/implementations/forecasts/pv-production-forecast.d.ts +83 -0
- package/dist/implementations/forecasts/pv-production-forecast.js +194 -0
- package/dist/index.d.ts +17 -160
- package/dist/index.js +17 -219
- package/dist/integrations/air-conditioning-integration-energy-app.d.ts +44 -0
- package/dist/integrations/air-conditioning-integration-energy-app.js +58 -0
- package/dist/integrations/energy-manager-energy-app.d.ts +121 -0
- package/dist/integrations/energy-manager-energy-app.js +202 -0
- package/dist/integrations/heatpump-integration-energy-app.d.ts +88 -0
- package/dist/integrations/heatpump-integration-energy-app.js +89 -0
- package/dist/integrations/integration-energy-app.d.ts +151 -0
- package/dist/integrations/integration-energy-app.js +262 -0
- package/dist/integrations/integration-types.d.ts +73 -0
- package/dist/integrations/integration-types.js +1 -0
- package/dist/integrations/inverter-integration-energy-app.d.ts +34 -0
- package/dist/integrations/inverter-integration-energy-app.js +40 -0
- package/dist/integrations/storage-integration-energy-app.d.ts +49 -0
- package/dist/integrations/storage-integration-energy-app.js +60 -0
- package/dist/integrations/wallbox-integration-energy-app.d.ts +113 -0
- package/dist/integrations/wallbox-integration-energy-app.js +132 -0
- package/dist/packages/energy-app-timeseries.d.ts +28 -1
- package/dist/types/enyo-timeseries.d.ts +45 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ The official TypeScript SDK for building Energy Apps on the enyo platform. Creat
|
|
|
9
9
|
|
|
10
10
|
- [Installation](#installation)
|
|
11
11
|
- [Quick Start](#quick-start)
|
|
12
|
+
- [Choosing the Right API](#choosing-the-right-api)
|
|
12
13
|
- [Core Concepts](#core-concepts)
|
|
13
14
|
- [Energy App Lifecycle](#energy-app-lifecycle)
|
|
14
15
|
- [Package Definition](#package-definition)
|
|
@@ -22,6 +23,22 @@ The official TypeScript SDK for building Energy Apps on the enyo platform. Creat
|
|
|
22
23
|
- [User Features](#user-features)
|
|
23
24
|
- [App Intelligence](#app-intelligence)
|
|
24
25
|
- [Advanced Modbus Integration](#advanced-modbus-integration)
|
|
26
|
+
- [Device Integrations](#device-integrations)
|
|
27
|
+
- [IntegrationEnergyApp (Base Class)](#integrationenergyapp-base-class)
|
|
28
|
+
- [HeatpumpIntegrationEnergyApp](#heatpumpintegrationenergyapp)
|
|
29
|
+
- [WallboxIntegrationEnergyApp](#wallboxintegrationenergyapp)
|
|
30
|
+
- [StorageIntegrationEnergyApp](#storageintegrationenergyapp)
|
|
31
|
+
- [InverterIntegrationEnergyApp](#inverterintegrationenergyapp)
|
|
32
|
+
- [AirConditioningIntegrationEnergyApp](#airconditioningintegrationenergyapp)
|
|
33
|
+
- [EnergyManagerEnergyApp](#energymanagerenergyapp)
|
|
34
|
+
- [Forecasting](#forecasting)
|
|
35
|
+
- [ForecastConfig](#forecastconfig)
|
|
36
|
+
- [PvProductionForecast](#pvproductionforecast)
|
|
37
|
+
- [BatteryForecast](#batteryforecast)
|
|
38
|
+
- [HomeConsumptionForecast](#homeconsumptionforecast)
|
|
39
|
+
- [EvChargingForecast](#evchargingforecast)
|
|
40
|
+
- [HeatpumpConsumptionForecast](#heatpumpconsumptionforecast)
|
|
41
|
+
- [HeatpumpDhwTemperatureForecast](#heatpumpdhwtemperatureforecast)
|
|
25
42
|
- [Examples](#examples)
|
|
26
43
|
- [Basic Energy App](#basic-energy-app)
|
|
27
44
|
- [Device Integration](#device-integration)
|
|
@@ -76,6 +93,36 @@ async function startApp() {
|
|
|
76
93
|
}
|
|
77
94
|
```
|
|
78
95
|
|
|
96
|
+
## Choosing the Right API
|
|
97
|
+
|
|
98
|
+
The SDK exposes several layered building blocks. Pick the one that matches the kind of app you are building before diving into the API reference:
|
|
99
|
+
|
|
100
|
+
- **Core SDK (`EnergyApp`)** — the always-present facade for system lifecycle, storage, data bus, settings, notifications, and HTTP. Every Energy App uses it.
|
|
101
|
+
- **Modbus helpers (`EnergyAppModbusInverter` / `Battery` / `Meter`)** — vendor-agnostic, configuration-driven Modbus access for raw register polling.
|
|
102
|
+
- **Device Integrations (`*IntegrationEnergyApp`)** — *inbound* abstractions for apps that **drive a real device** (heatpump, wallbox, inverter, storage, air conditioning). They subscribe to the right data-bus commands, dispatch them to your handlers, auto-acknowledge, and expose typed `publish*` helpers for status updates.
|
|
103
|
+
- **Forecasting (`*Forecast`, `EnergyManagerEnergyApp`)** — *outbound* abstractions for apps that **predict** future PV production, consumption, battery state, EV charging load, heatpump load, or DHW tank temperature using historical timeseries plus live data-bus updates.
|
|
104
|
+
|
|
105
|
+
### Decision Matrix
|
|
106
|
+
|
|
107
|
+
| If you want to… | Use |
|
|
108
|
+
|---|---|
|
|
109
|
+
| React to system lifecycle, store data, send notifications | [`EnergyApp`](#api-reference) |
|
|
110
|
+
| Talk to a Modbus device through configuration only | [`EnergyAppModbusInverter` / `Battery` / `Meter`](#advanced-modbus-integration) |
|
|
111
|
+
| Build a **device integration** for a heatpump | [`HeatpumpIntegrationEnergyApp`](#heatpumpintegrationenergyapp) |
|
|
112
|
+
| Build a **device integration** for an EV wallbox | [`WallboxIntegrationEnergyApp`](#wallboxintegrationenergyapp) |
|
|
113
|
+
| Build a **device integration** for a battery / storage system | [`StorageIntegrationEnergyApp`](#storageintegrationenergyapp) |
|
|
114
|
+
| Build a **device integration** for a PV inverter | [`InverterIntegrationEnergyApp`](#inverterintegrationenergyapp) |
|
|
115
|
+
| Build a **device integration** for an air-conditioning unit | [`AirConditioningIntegrationEnergyApp`](#airconditioningintegrationenergyapp) |
|
|
116
|
+
| Build an **energy manager** that orchestrates many forecasters | [`EnergyManagerEnergyApp`](#energymanagerenergyapp) |
|
|
117
|
+
| Forecast PV production for a single inverter | [`PvProductionForecast`](#pvproductionforecast) |
|
|
118
|
+
| Forecast battery state-of-charge | [`BatteryForecast`](#batteryforecast) |
|
|
119
|
+
| Forecast total household consumption | [`HomeConsumptionForecast`](#homeconsumptionforecast) |
|
|
120
|
+
| Forecast EV charging demand | [`EvChargingForecast`](#evchargingforecast) |
|
|
121
|
+
| Forecast heatpump electrical consumption | [`HeatpumpConsumptionForecast`](#heatpumpconsumptionforecast) |
|
|
122
|
+
| Forecast heatpump DHW tank temperature | [`HeatpumpDhwTemperatureForecast`](#heatpumpdhwtemperatureforecast) |
|
|
123
|
+
|
|
124
|
+
> **Rule of thumb:** if your app *receives* commands and drives hardware, you want an **Integration**. If your app *produces* predictions, you want a **Forecast** (and likely an `EnergyManagerEnergyApp` to wire several together).
|
|
125
|
+
|
|
79
126
|
## Core Concepts
|
|
80
127
|
|
|
81
128
|
### Energy App Lifecycle
|
|
@@ -859,6 +906,333 @@ The Modbus implementation follows a clean, modular architecture:
|
|
|
859
906
|
|
|
860
907
|
This modular design ensures maintainability, testability, and extensibility for future enhancements.
|
|
861
908
|
|
|
909
|
+
## Device Integrations
|
|
910
|
+
|
|
911
|
+
Device Integrations are the high-level building blocks for apps that **drive a real device** — a heatpump, EV wallbox, PV inverter, battery storage system, or air-conditioning unit. Each integration class hides the data-bus plumbing for its appliance type so you only implement the business logic that physically controls the device.
|
|
912
|
+
|
|
913
|
+
### ✨ What the integration framework does for you
|
|
914
|
+
|
|
915
|
+
- **Subscribes** to the relevant `*CommandV1` data-bus messages for the appliance type.
|
|
916
|
+
- **Dispatches** each command to the async handler you register.
|
|
917
|
+
- **Auto-acknowledges** every command via a `CommandAcknowledgeV1` response containing your `Accepted` / `Rejected` / `NotSupported` answer.
|
|
918
|
+
- **Handles broadcast `GridOperatorPowerLimitationV1`** (§14a EnWG) and routes it once per managed appliance.
|
|
919
|
+
- **Manages lifecycle** — auto-starts on construction and auto-stops on shutdown by default.
|
|
920
|
+
- **Exposes typed `publish*` helpers** so your handler implementations can broadcast status updates back to the system without hand-building messages.
|
|
921
|
+
|
|
922
|
+
### 🚀 Quick Start
|
|
923
|
+
|
|
924
|
+
```typescript
|
|
925
|
+
import {
|
|
926
|
+
HeatpumpIntegrationEnergyApp,
|
|
927
|
+
EnyoSourceEnum,
|
|
928
|
+
EnyoCommandAcknowledgeAnswerEnum,
|
|
929
|
+
ApplianceManager,
|
|
930
|
+
} from '@enyo-energy/energy-app-sdk';
|
|
931
|
+
|
|
932
|
+
class MyHeatpumpApp extends HeatpumpIntegrationEnergyApp {
|
|
933
|
+
constructor(applianceManager: ApplianceManager) {
|
|
934
|
+
super({ source: EnyoSourceEnum.Device, applianceManager });
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
protected async handleHeatpumpOverheating(message) {
|
|
938
|
+
await driveOverheating(message.data);
|
|
939
|
+
return { answer: EnyoCommandAcknowledgeAnswerEnum.Accepted };
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
protected async handleHeatpumpAvailablePowerAnnouncement(message) {
|
|
943
|
+
await scaleHeatpumpToEnvelope(message.data);
|
|
944
|
+
return { answer: EnyoCommandAcknowledgeAnswerEnum.Accepted };
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
protected async handleGridOperatorPowerLimitation(message, applianceId) {
|
|
948
|
+
await applyGridLimit(applianceId, message.data);
|
|
949
|
+
return { applianceId, answer: EnyoCommandAcknowledgeAnswerEnum.Accepted };
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
### IntegrationEnergyApp (Base Class)
|
|
955
|
+
|
|
956
|
+
`IntegrationEnergyApp` is the abstract base every device integration extends. It owns the data-bus subscription/acknowledgment loop and the broadcast routing so subclasses only declare *what* commands they care about and *how* to fulfil them.
|
|
957
|
+
|
|
958
|
+
**Constructor options (`IntegrationEnergyAppOptions`)**
|
|
959
|
+
|
|
960
|
+
| Field | Type | Default | Purpose |
|
|
961
|
+
|---|---|---|---|
|
|
962
|
+
| `source` | `EnyoSourceEnum` | required | Source identifier for outbound messages (typically `Device`). |
|
|
963
|
+
| `applianceManager` | `ApplianceManager` | optional | Lookup all appliances of the integration's `managedApplianceType`. |
|
|
964
|
+
| `applianceIds` | `string[]` | optional | Explicit list of appliance IDs to manage. Overrides the manager-based lookup. |
|
|
965
|
+
| `autoStart` | `boolean` | `true` | Subscribe to the data bus immediately after construction. |
|
|
966
|
+
| `autoStopOnShutdown` | `boolean` | `true` | Register an SDK shutdown hook to release listeners. |
|
|
967
|
+
|
|
968
|
+
**Lifecycle**
|
|
969
|
+
|
|
970
|
+
- `start(): void` — idempotent; registers all command handlers via the subclass's `registerHandlers()`.
|
|
971
|
+
- `stop(): void` — releases listeners and disposes the outbound command handler.
|
|
972
|
+
|
|
973
|
+
**For subclass authors**
|
|
974
|
+
|
|
975
|
+
- `protected abstract registerHandlers(): void` — call `registerCommandHandler(messageType, handler)` for each command you want to receive.
|
|
976
|
+
- `protected abstract handleGridOperatorPowerLimitation(message, applianceId)` — handle the §14a EnWG broadcast per managed appliance.
|
|
977
|
+
- `protected abstract get managedApplianceType(): EnyoApplianceTypeEnum` — used to resolve appliance IDs when no explicit list is given.
|
|
978
|
+
|
|
979
|
+
### HeatpumpIntegrationEnergyApp
|
|
980
|
+
|
|
981
|
+
Drives a heatpump. Manages building / DHW overheating commands and grid-power-availability announcements.
|
|
982
|
+
|
|
983
|
+
- **Subscribed commands:** `HeatpumpOverheatingV1`, `HeatpumpAvailablePowerAnnouncementV1`, `GridOperatorPowerLimitationV1` (broadcast)
|
|
984
|
+
- **Implement:** `handleHeatpumpOverheating`, `handleHeatpumpAvailablePowerAnnouncement`, `handleGridOperatorPowerLimitation`
|
|
985
|
+
- **Publish helpers:**
|
|
986
|
+
- `publishHeatpumpValuesUpdate(applianceId, values)` — operation mode, electrical and thermal power, energies.
|
|
987
|
+
- `publishHeatpumpTemperatures(applianceId, temperatures)` — outdoor, flow, return, DHW tanks, heating circuits, buffer tank.
|
|
988
|
+
|
|
989
|
+
### WallboxIntegrationEnergyApp
|
|
990
|
+
|
|
991
|
+
Drives an EV wallbox / charger. Has the richest command surface of all integrations.
|
|
992
|
+
|
|
993
|
+
- **Subscribed commands:** `StartChargeV1`, `StopChargeV1`, `PauseChargingV1`, `ResumeChargingV1`, `ChangeChargingPowerV1`, `SetChargingScheduleV1`, `ResetChargerV1`, `RebootChargerV1`, `RequestChargerLogsV1`, `ClearChargingProfilesV1`, `GridOperatorPowerLimitationV1` (broadcast)
|
|
994
|
+
- **Implement:** one `handle*` method per command listed above plus `handleGridOperatorPowerLimitation`.
|
|
995
|
+
- **Publish helpers:**
|
|
996
|
+
- `publishChargingStarted(applianceId, data)` / `publishChargingStopped(applianceId, data)`
|
|
997
|
+
- `publishChargingMeterValues(applianceId, data)` — periodic meter values during a session.
|
|
998
|
+
- `publishMaxChargingPowerChanged(applianceId, maxChargingPowerKw)` — e.g. on thermal derating.
|
|
999
|
+
- `publishChargerStatusChanged(applianceId, data)` — OCPP-style status changes.
|
|
1000
|
+
|
|
1001
|
+
```typescript
|
|
1002
|
+
class MyWallbox extends WallboxIntegrationEnergyApp {
|
|
1003
|
+
constructor(applianceManager: ApplianceManager) {
|
|
1004
|
+
super({ source: EnyoSourceEnum.Device, applianceManager });
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
protected async handleStartCharge(message) {
|
|
1008
|
+
const txId = await this.driver.start(message.data);
|
|
1009
|
+
this.publishChargingStarted(message.applianceId, { transactionId: txId });
|
|
1010
|
+
return { answer: EnyoCommandAcknowledgeAnswerEnum.Accepted };
|
|
1011
|
+
}
|
|
1012
|
+
// ... other handlers
|
|
1013
|
+
}
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
### StorageIntegrationEnergyApp
|
|
1017
|
+
|
|
1018
|
+
Drives a battery / storage system. Controls grid-charging windows and discharge limits.
|
|
1019
|
+
|
|
1020
|
+
- **Subscribed commands:** `StartStorageGridChargeV1`, `StopStorageGridChargeV1`, `SetStorageDischargeLimitV1`, `GridOperatorPowerLimitationV1` (broadcast)
|
|
1021
|
+
- **Implement:** `handleStartStorageGridCharge`, `handleStopStorageGridCharge`, `handleSetStorageDischargeLimit`, `handleGridOperatorPowerLimitation`.
|
|
1022
|
+
- **Publish helpers:**
|
|
1023
|
+
- `publishBatteryValuesUpdate(applianceId, data)` — state, power, SoC.
|
|
1024
|
+
- `publishMaxDischargePowerChanged(applianceId, maxDischargePowerKw)` — discharge-limit changes.
|
|
1025
|
+
|
|
1026
|
+
### InverterIntegrationEnergyApp
|
|
1027
|
+
|
|
1028
|
+
Drives a PV inverter. Controls grid feed-in limits and publishes electrical metrics.
|
|
1029
|
+
|
|
1030
|
+
- **Subscribed commands:** `SetInverterFeedInLimitV1`, `GridOperatorPowerLimitationV1` (broadcast)
|
|
1031
|
+
- **Implement:** `handleSetInverterFeedInLimit` (`data.feedInLimitW` may be `null` to clear), `handleGridOperatorPowerLimitation`.
|
|
1032
|
+
- **Publish helpers:**
|
|
1033
|
+
- `publishInverterValuesUpdate(applianceId, data)` — DC strings, AC voltages, total PV power, operating state.
|
|
1034
|
+
|
|
1035
|
+
### AirConditioningIntegrationEnergyApp
|
|
1036
|
+
|
|
1037
|
+
Drives an air-conditioning unit. Starts and stops heating or cooling modes.
|
|
1038
|
+
|
|
1039
|
+
- **Subscribed commands:** `StartAirConditioningV1`, `StopAirConditioningV1`, `GridOperatorPowerLimitationV1` (broadcast)
|
|
1040
|
+
- **Implement:** `handleStartAirConditioning` (mode is `Heating` or `Cooling`), `handleStopAirConditioning`, `handleGridOperatorPowerLimitation`.
|
|
1041
|
+
- **Publish helpers:**
|
|
1042
|
+
- `publishAirConditioningValues(applianceId, values)` — current operation mode and electrical consumption.
|
|
1043
|
+
- `publishAirConditioningTemperatures(applianceId, data)` — current and target temperatures per room.
|
|
1044
|
+
|
|
1045
|
+
### EnergyManagerEnergyApp
|
|
1046
|
+
|
|
1047
|
+
`EnergyManagerEnergyApp` is the **counterpart** to the device integrations: instead of receiving commands, it produces forecasts. It is the recommended entry point when your app needs **multiple forecasters** wired together — it lazily creates each forecaster on first request, caches it, and disposes them all on shutdown.
|
|
1048
|
+
|
|
1049
|
+
**Constructor**
|
|
1050
|
+
|
|
1051
|
+
```typescript
|
|
1052
|
+
new EnergyManagerEnergyApp({
|
|
1053
|
+
source: EnyoSourceEnum.Device,
|
|
1054
|
+
forecastConfig?: ForecastConfig, // applied to every forecaster unless overridden per call
|
|
1055
|
+
autoStopOnShutdown?: boolean, // default true
|
|
1056
|
+
});
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
**Lazy forecaster factories** — each returns a ready-to-use forecaster (history loaded, live listeners attached):
|
|
1060
|
+
|
|
1061
|
+
- `getPvProductionForecast(applianceId, config?)`
|
|
1062
|
+
- `getBatteryForecast(applianceId, config?)`
|
|
1063
|
+
- `getHomeConsumptionForecast(config?)` — system-wide, no appliance ID
|
|
1064
|
+
- `getEvChargingForecast(applianceId, config?)`
|
|
1065
|
+
- `getHeatpumpConsumptionForecast(applianceId, config?)`
|
|
1066
|
+
- `getHeatpumpDhwTemperatureForecast(applianceId, config?)`
|
|
1067
|
+
|
|
1068
|
+
**Lifecycle**
|
|
1069
|
+
|
|
1070
|
+
- `stop(): void` — disposes every cached forecaster.
|
|
1071
|
+
|
|
1072
|
+
```typescript
|
|
1073
|
+
const manager = new EnergyManagerEnergyApp({ source: EnyoSourceEnum.Device });
|
|
1074
|
+
|
|
1075
|
+
const pv = await manager.getPvProductionForecast('inverter-1');
|
|
1076
|
+
const battery = await manager.getBatteryForecast('battery-1');
|
|
1077
|
+
|
|
1078
|
+
const pvForecast = pv.getForecast();
|
|
1079
|
+
const batteryForecast = battery.getForecast();
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
## Forecasting
|
|
1083
|
+
|
|
1084
|
+
The forecasting module provides 24-hour predictions across the energy domains the SDK already understands (PV, battery, home consumption, EV charging, heatpump consumption, DHW temperature). Every forecaster follows the same lifecycle and shares the same configuration shape, so once you've used one you've used them all.
|
|
1085
|
+
|
|
1086
|
+
### ✨ Common pattern
|
|
1087
|
+
|
|
1088
|
+
1. Construct the forecaster with the SDK app, the appliance ID (where applicable), and an optional `ForecastConfig`.
|
|
1089
|
+
2. `await initialize()` — pulls historical timeseries and subscribes to live data-bus updates.
|
|
1090
|
+
3. Call `getForecast()` whenever you need a fresh prediction (cheap; uses in-memory state).
|
|
1091
|
+
4. Optionally call `publishForecast()` to manually push to the data bus (or rely on auto-publish).
|
|
1092
|
+
5. `dispose()` to release listeners on shutdown.
|
|
1093
|
+
|
|
1094
|
+
All forecasters compute **same-weekday recency-weighted averages** at 15-minute resolution and optionally smooth the first ~2 hours toward recent actuals. `PvProductionForecast` is the exception — sun position is weekday-independent, so it weights all days equally.
|
|
1095
|
+
|
|
1096
|
+
### ForecastConfig
|
|
1097
|
+
|
|
1098
|
+
The shared configuration applied to every forecaster.
|
|
1099
|
+
|
|
1100
|
+
| Field | Type | Default | Purpose |
|
|
1101
|
+
|---|---|---|---|
|
|
1102
|
+
| `historyDays` | `number` | `7` | Lookback window for historical timeseries. |
|
|
1103
|
+
| `resolution` | `'1m' \| '15m'` | `'15m'` | Slot granularity for both history and forecast. |
|
|
1104
|
+
| `horizonHours` | `number` | `24` | How far ahead to forecast. |
|
|
1105
|
+
| `alignToRecentActuals` | `boolean` | `true` | Smoothly join the first ~2 forecast hours to recent observations. |
|
|
1106
|
+
| `publishToBus` | `boolean` | `true` | Auto-publish to the data bus on every refresh. |
|
|
1107
|
+
|
|
1108
|
+
> **Per-forecaster overrides:** `PvProductionForecast` defaults to **4 days** (sun-driven, recency matters most). `BatteryForecast`, `EvChargingForecast`, and `HomeConsumptionForecast` default to **14 days** (strongly weekday-cyclic).
|
|
1109
|
+
|
|
1110
|
+
All forecasters return a `BaseForecast<D>`-shaped object:
|
|
1111
|
+
|
|
1112
|
+
```typescript
|
|
1113
|
+
{
|
|
1114
|
+
generatedAtIso: string; // ISO timestamp of computation
|
|
1115
|
+
data: {
|
|
1116
|
+
resolution: '1m' | '15m';
|
|
1117
|
+
entries: Array<{ startIso: string; /* per-class fields */ }>;
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
### PvProductionForecast
|
|
1123
|
+
|
|
1124
|
+
Forecasts the AC power output of a single PV inverter.
|
|
1125
|
+
|
|
1126
|
+
```typescript
|
|
1127
|
+
new PvProductionForecast(app, applianceId, { source: EnyoSourceEnum.Device, config? });
|
|
1128
|
+
```
|
|
1129
|
+
|
|
1130
|
+
- **Output per slot:** `{ powerW: number; powerWh: number }`
|
|
1131
|
+
- **History default:** 4 days, all-day weighting.
|
|
1132
|
+
- **Live source:** `InverterValuesUpdateV1`.
|
|
1133
|
+
|
|
1134
|
+
### BatteryForecast
|
|
1135
|
+
|
|
1136
|
+
Forecasts state-of-charge (and derived stored energy) for a single battery.
|
|
1137
|
+
|
|
1138
|
+
```typescript
|
|
1139
|
+
new BatteryForecast(app, applianceId, {
|
|
1140
|
+
source: EnyoSourceEnum.Device,
|
|
1141
|
+
config?: { ratedCapacityWh?: number, ...ForecastConfig }
|
|
1142
|
+
});
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
- **Output per slot:** `{ socPercent: number; capacityWh: number }` (SoC clamped to `[0, 100]`).
|
|
1146
|
+
- **History default:** 14 days.
|
|
1147
|
+
- **Notable config:** `ratedCapacityWh` is auto-loaded from the appliance metadata if omitted.
|
|
1148
|
+
- **Live source:** `BatteryValuesUpdateV1`.
|
|
1149
|
+
|
|
1150
|
+
### HomeConsumptionForecast
|
|
1151
|
+
|
|
1152
|
+
Forecasts total household electrical consumption — system-wide, no appliance ID.
|
|
1153
|
+
|
|
1154
|
+
```typescript
|
|
1155
|
+
new HomeConsumptionForecast(app, { source: EnyoSourceEnum.Device, config? });
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
- **Output per slot:** `{ powerW: number; powerWh: number }`
|
|
1159
|
+
- **History default:** 14 days (household routines are strongly weekday-cyclic).
|
|
1160
|
+
- **Live source:** `AggregatedStateUpdateV1`.
|
|
1161
|
+
|
|
1162
|
+
### EvChargingForecast
|
|
1163
|
+
|
|
1164
|
+
Forecasts EV charging power for a single charger.
|
|
1165
|
+
|
|
1166
|
+
```typescript
|
|
1167
|
+
new EvChargingForecast(app, applianceId, { source: EnyoSourceEnum.Device, config? });
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
- **Output per slot:** `{ powerW: number; powerWh: number }`
|
|
1171
|
+
- **History default:** 14 days.
|
|
1172
|
+
- **Live source:** `ChargingMeterValuesUpdateV1`.
|
|
1173
|
+
|
|
1174
|
+
### HeatpumpConsumptionForecast
|
|
1175
|
+
|
|
1176
|
+
Forecasts the electrical consumption of a heatpump (heating + cooling combined).
|
|
1177
|
+
|
|
1178
|
+
```typescript
|
|
1179
|
+
new HeatpumpConsumptionForecast(app, applianceId, { source: EnyoSourceEnum.Device, config? });
|
|
1180
|
+
```
|
|
1181
|
+
|
|
1182
|
+
- **Output per slot:** `{ powerW: number; powerWh: number }`
|
|
1183
|
+
- **History default:** 7 days.
|
|
1184
|
+
- **Live source:** `HeatpumpValuesUpdateV1`.
|
|
1185
|
+
- **Note:** does not adjust for forecasted weather; layer COP-based correction on top if you need that.
|
|
1186
|
+
|
|
1187
|
+
### HeatpumpDhwTemperatureForecast
|
|
1188
|
+
|
|
1189
|
+
Forecasts the temperature of a heatpump's domestic-hot-water tank.
|
|
1190
|
+
|
|
1191
|
+
```typescript
|
|
1192
|
+
new HeatpumpDhwTemperatureForecast(app, applianceId, {
|
|
1193
|
+
source: EnyoSourceEnum.Device,
|
|
1194
|
+
config?: { dhwTankIndex?: number, ...ForecastConfig }
|
|
1195
|
+
});
|
|
1196
|
+
```
|
|
1197
|
+
|
|
1198
|
+
- **Output per slot:** `{ temperatureC: number }` (rounded to 0.1 °C).
|
|
1199
|
+
- **History default:** 7 days.
|
|
1200
|
+
- **Notable config:** `dhwTankIndex` selects a specific tank (zero-based); omit to average across all tanks.
|
|
1201
|
+
- **Live source:** heatpump temperature timeseries / live updates.
|
|
1202
|
+
|
|
1203
|
+
### 🚀 Common usage example
|
|
1204
|
+
|
|
1205
|
+
```typescript
|
|
1206
|
+
import {
|
|
1207
|
+
PvProductionForecast,
|
|
1208
|
+
BatteryForecast,
|
|
1209
|
+
EnyoSourceEnum,
|
|
1210
|
+
} from '@enyo-energy/energy-app-sdk';
|
|
1211
|
+
|
|
1212
|
+
const pv = new PvProductionForecast(energyApp, 'inverter-1', {
|
|
1213
|
+
source: EnyoSourceEnum.Device,
|
|
1214
|
+
});
|
|
1215
|
+
const battery = new BatteryForecast(energyApp, 'battery-1', {
|
|
1216
|
+
source: EnyoSourceEnum.Device,
|
|
1217
|
+
config: { ratedCapacityWh: 10_000 },
|
|
1218
|
+
});
|
|
1219
|
+
|
|
1220
|
+
await Promise.all([pv.initialize(), battery.initialize()]);
|
|
1221
|
+
|
|
1222
|
+
energyApp.useInterval().createInterval('15m', () => {
|
|
1223
|
+
const pvNext24h = pv.getForecast();
|
|
1224
|
+
const batteryNext24h = battery.getForecast();
|
|
1225
|
+
runDispatch(pvNext24h, batteryNext24h);
|
|
1226
|
+
});
|
|
1227
|
+
|
|
1228
|
+
energyApp.onShutdown(async () => {
|
|
1229
|
+
pv.dispose();
|
|
1230
|
+
battery.dispose();
|
|
1231
|
+
});
|
|
1232
|
+
```
|
|
1233
|
+
|
|
1234
|
+
> **Tip:** if your app needs more than one forecaster, prefer [`EnergyManagerEnergyApp`](#energymanagerenergyapp) — it manages construction, caching, and disposal for you.
|
|
1235
|
+
|
|
862
1236
|
## Examples
|
|
863
1237
|
|
|
864
1238
|
### Basic Energy App
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EnergyApp = void 0;
|
|
4
|
+
const version_js_1 = require("./version.cjs");
|
|
5
|
+
/**
|
|
6
|
+
* Concrete implementation of {@link EnyoEnergyAppSdk} that delegates every call
|
|
7
|
+
* to the runtime-provided `energyAppSdkInstance` global.
|
|
8
|
+
*
|
|
9
|
+
* This class is the canonical entry point for an energy app: an integrator
|
|
10
|
+
* instantiates one `EnergyApp`, then either consumes its `use*()` accessors
|
|
11
|
+
* directly or extends one of the specialized abstract integration classes
|
|
12
|
+
* (e.g. `HeatpumpIntegrationEnergyApp`) which build on top of this class.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const app = new EnergyApp();
|
|
17
|
+
* app.register((packageName, version, channel, deviceId) => {
|
|
18
|
+
* // perform initialization
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
class EnergyApp {
|
|
23
|
+
energyAppSdk;
|
|
24
|
+
constructor() {
|
|
25
|
+
// in our runtime, there is an instance of energyAppSdk available which needs to be used here
|
|
26
|
+
// if the energyAppSdk is not available, instantiate a mocked version for local development
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
if (energyAppSdkInstance === undefined || energyAppSdkInstance === null) {
|
|
29
|
+
throw new Error('Missing energyAppSdk instance');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
this.energyAppSdk = energyAppSdkInstance;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
isSystemOnline() {
|
|
37
|
+
return this.energyAppSdk.isSystemOnline();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Registers a listener that gets called when the network status changes.
|
|
41
|
+
* @param listener - Callback invoked with `true` when the system goes online, `false` when it goes offline
|
|
42
|
+
* @returns A unique listener ID that can be used to remove the listener
|
|
43
|
+
*/
|
|
44
|
+
onNetworkStatusChanged(listener) {
|
|
45
|
+
return this.energyAppSdk.onNetworkStatusChanged(listener);
|
|
46
|
+
}
|
|
47
|
+
updateEnergyAppState(state) {
|
|
48
|
+
this.energyAppSdk.updateEnergyAppState(state);
|
|
49
|
+
}
|
|
50
|
+
register(callback) {
|
|
51
|
+
// This registers the package with the enyo system
|
|
52
|
+
this.energyAppSdk.register(callback);
|
|
53
|
+
}
|
|
54
|
+
onShutdown(callback) {
|
|
55
|
+
process.on('beforeExit', async (code) => {
|
|
56
|
+
await callback();
|
|
57
|
+
});
|
|
58
|
+
process.on('exit', async (code) => {
|
|
59
|
+
await callback();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
useFetch() {
|
|
63
|
+
return this.energyAppSdk.useFetch();
|
|
64
|
+
}
|
|
65
|
+
useInterval() {
|
|
66
|
+
return this.energyAppSdk.useInterval();
|
|
67
|
+
}
|
|
68
|
+
useModbus() {
|
|
69
|
+
return this.energyAppSdk.useModbus();
|
|
70
|
+
}
|
|
71
|
+
useNetworkDevices() {
|
|
72
|
+
return this.energyAppSdk.useNetworkDevices();
|
|
73
|
+
}
|
|
74
|
+
useStorage() {
|
|
75
|
+
return this.energyAppSdk.useStorage();
|
|
76
|
+
}
|
|
77
|
+
useAppliances() {
|
|
78
|
+
return this.energyAppSdk.useAppliances();
|
|
79
|
+
}
|
|
80
|
+
useDataBus() {
|
|
81
|
+
return this.energyAppSdk.useDataBus();
|
|
82
|
+
}
|
|
83
|
+
useOcpp() {
|
|
84
|
+
return this.energyAppSdk.useOcpp();
|
|
85
|
+
}
|
|
86
|
+
useVehicle() {
|
|
87
|
+
return this.energyAppSdk.useVehicle();
|
|
88
|
+
}
|
|
89
|
+
useChargingCard() {
|
|
90
|
+
return this.energyAppSdk.useChargingCard();
|
|
91
|
+
}
|
|
92
|
+
useCharge() {
|
|
93
|
+
return this.energyAppSdk.useCharge();
|
|
94
|
+
}
|
|
95
|
+
useAuthentication() {
|
|
96
|
+
return this.energyAppSdk.useAuthentication();
|
|
97
|
+
}
|
|
98
|
+
useSettings() {
|
|
99
|
+
return this.energyAppSdk.useSettings();
|
|
100
|
+
}
|
|
101
|
+
useElectricityPrices() {
|
|
102
|
+
return this.energyAppSdk.useElectricityPrices();
|
|
103
|
+
}
|
|
104
|
+
useNotification() {
|
|
105
|
+
return this.energyAppSdk.useNotification();
|
|
106
|
+
}
|
|
107
|
+
useOnboarding() {
|
|
108
|
+
return this.energyAppSdk.useOnboarding();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Gets the Secret Manager API for retrieving secrets from the developer organization.
|
|
112
|
+
* Provides methods to fetch secrets that have been configured in the developer org's secret store.
|
|
113
|
+
* @returns The Secret Manager API instance
|
|
114
|
+
*/
|
|
115
|
+
useSecretManager() {
|
|
116
|
+
return this.energyAppSdk.useSecretManager();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Gets the Location API for retrieving device location information.
|
|
120
|
+
* Provides methods to fetch location with varying levels of detail based on permissions.
|
|
121
|
+
* @returns The Location API instance
|
|
122
|
+
*/
|
|
123
|
+
useLocation() {
|
|
124
|
+
return this.energyAppSdk.useLocation();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Gets the Timeseries API for querying historical energy data.
|
|
128
|
+
* Provides methods to retrieve aggregated timeseries data with 15-minute bucket granularity
|
|
129
|
+
* for various energy metrics including PV production, battery state, meter values, and grid power.
|
|
130
|
+
* @returns The Timeseries API instance
|
|
131
|
+
*/
|
|
132
|
+
useTimeseries() {
|
|
133
|
+
return this.energyAppSdk.useTimeseries();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Gets the Energy Manager API for retrieving information about the active energy manager.
|
|
137
|
+
* Provides methods to check the current energy manager and its supported features.
|
|
138
|
+
* @returns The Energy Manager API instance
|
|
139
|
+
*/
|
|
140
|
+
useEnergyManager() {
|
|
141
|
+
return this.energyAppSdk.useEnergyManager();
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Gets the Electricity Tariff API for managing electricity tariffs.
|
|
145
|
+
* Provides methods to register, retrieve, and remove electricity tariffs
|
|
146
|
+
* used for energy pricing and consumption calculations.
|
|
147
|
+
* @returns The Electricity Tariff API instance
|
|
148
|
+
*/
|
|
149
|
+
useElectricityTariff() {
|
|
150
|
+
return this.energyAppSdk.useElectricityTariff();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Gets the Weather Forecasting API for managing weather forecast providers and retrieving weather forecasts.
|
|
154
|
+
* Provides methods to register/deregister weather forecast providers, list available providers,
|
|
155
|
+
* and fetch weather forecasts by zip code or coordinates.
|
|
156
|
+
* @returns The Weather Forecasting API instance
|
|
157
|
+
*/
|
|
158
|
+
useWeatherForecasting() {
|
|
159
|
+
return this.energyAppSdk.useWeatherForecasting();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Gets the PV Forecasting API for managing PV forecast providers and retrieving PV forecasts.
|
|
163
|
+
* Provides methods to register/deregister PV forecast providers and fetch power production forecasts.
|
|
164
|
+
* @returns The PV Forecasting API instance
|
|
165
|
+
*/
|
|
166
|
+
usePvForecasting() {
|
|
167
|
+
return this.energyAppSdk.usePvForecasting();
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Gets the PV System API for managing PV system registrations and configurations.
|
|
171
|
+
* Provides methods to register, retrieve, update, and remove PV systems
|
|
172
|
+
* including DC string orientations, peak power, associated appliances, and feature flags.
|
|
173
|
+
* @returns The PV System API instance
|
|
174
|
+
*/
|
|
175
|
+
usePvSystem() {
|
|
176
|
+
return this.energyAppSdk.usePvSystem();
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Gets the Sequence Generator API for generating unique sequential numbers per named sequence.
|
|
180
|
+
* Each sequence is identified by a string name and maintains its own independent counter.
|
|
181
|
+
* @returns The Sequence Generator API instance
|
|
182
|
+
*/
|
|
183
|
+
useSequenceGenerator() {
|
|
184
|
+
return this.energyAppSdk.useSequenceGenerator();
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Gets the Modbus RTU serial communication API.
|
|
188
|
+
* Provides methods to connect to Modbus RTU devices over serial ports
|
|
189
|
+
* and read/write registers using slave IDs.
|
|
190
|
+
* @returns The Modbus RTU API instance
|
|
191
|
+
*/
|
|
192
|
+
useModbusRtu() {
|
|
193
|
+
return this.energyAppSdk.useModbusRtu();
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Gets the EEbus API for SHIP/SPINE device communication.
|
|
197
|
+
* Provides device pairing and discovery, low-level SPINE data access,
|
|
198
|
+
* and high-level convenience methods for power management and device classification.
|
|
199
|
+
* Supports both appliance and energy manager roles for bidirectional communication.
|
|
200
|
+
* @returns The EEbus API instance
|
|
201
|
+
*/
|
|
202
|
+
useEebus() {
|
|
203
|
+
return this.energyAppSdk.useEebus();
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Gets the MQTT communication API.
|
|
207
|
+
* Provides methods to connect to the SDK-provided internal MQTT broker
|
|
208
|
+
* or external custom brokers for publishing and subscribing to topics.
|
|
209
|
+
* @returns The MQTT API instance
|
|
210
|
+
*/
|
|
211
|
+
useMqtt() {
|
|
212
|
+
return this.energyAppSdk.useMqtt();
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Gets the Diagnostics API for submitting energy manager diagnostics data.
|
|
216
|
+
* Allows energy managers to report current state, forecast, and control plan
|
|
217
|
+
* for internal processing and analysis.
|
|
218
|
+
* @returns The Diagnostics API instance
|
|
219
|
+
*/
|
|
220
|
+
useDiagnostics() {
|
|
221
|
+
return this.energyAppSdk.useDiagnostics();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Gets the Learning Phase API for registering and tracking learning phases.
|
|
225
|
+
* Provides methods to register new learning phases, check their status,
|
|
226
|
+
* and retrieve learning phase history for the package or specific appliances.
|
|
227
|
+
* @returns The Learning Phase API instance
|
|
228
|
+
*/
|
|
229
|
+
useLearningPhase() {
|
|
230
|
+
return this.energyAppSdk.useLearningPhase();
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Gets the current SDK version.
|
|
234
|
+
* @returns The semantic version string of the SDK
|
|
235
|
+
*/
|
|
236
|
+
getSdkVersion() {
|
|
237
|
+
return (0, version_js_1.getSdkVersion)();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
exports.EnergyApp = EnergyApp;
|