@enyo-energy/energy-app-sdk 0.0.132 → 0.0.134
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 +513 -11
- package/dist/cjs/energy-app.cjs +10 -0
- package/dist/cjs/energy-app.d.cts +9 -0
- package/dist/cjs/enyo-energy-app-sdk.d.cts +3 -0
- package/dist/cjs/implementations/appliances/appliance-manager.cjs +400 -235
- package/dist/cjs/implementations/appliances/appliance-manager.d.cts +228 -70
- package/dist/cjs/implementations/appliances/in-memory-appliance-manager.cjs +15 -14
- package/dist/cjs/implementations/appliances/in-memory-appliance-manager.d.cts +3 -10
- package/dist/cjs/implementations/network-devices/network-access-guard.cjs +69 -35
- package/dist/cjs/implementations/network-devices/network-access-guard.d.cts +31 -6
- package/dist/cjs/implementations/network-devices/network-device-manager.cjs +208 -36
- package/dist/cjs/implementations/network-devices/network-device-manager.d.cts +143 -23
- package/dist/cjs/implementations/ocpp/ocpp16.cjs +1 -0
- package/dist/cjs/implementations/ocpp/ocpp16.d.cts +1 -0
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.d.cts +2 -0
- package/dist/cjs/integrations/wallbox-integration-energy-app.d.cts +4 -2
- package/dist/cjs/packages/energy-app-configuration-manager.cjs +2 -0
- package/dist/cjs/packages/energy-app-configuration-manager.d.cts +56 -0
- package/dist/cjs/types/enyo-charger-appliance.cjs +2 -0
- package/dist/cjs/types/enyo-charger-appliance.d.cts +3 -1
- package/dist/cjs/types/enyo-configuration-manager.cjs +2 -0
- package/dist/cjs/types/enyo-configuration-manager.d.cts +84 -0
- package/dist/cjs/types/enyo-data-bus-value.d.cts +8 -2
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/energy-app.d.ts +9 -0
- package/dist/energy-app.js +10 -0
- package/dist/enyo-energy-app-sdk.d.ts +3 -0
- package/dist/implementations/appliances/appliance-manager.d.ts +228 -70
- package/dist/implementations/appliances/appliance-manager.js +396 -234
- package/dist/implementations/appliances/in-memory-appliance-manager.d.ts +3 -10
- package/dist/implementations/appliances/in-memory-appliance-manager.js +15 -14
- package/dist/implementations/network-devices/network-access-guard.d.ts +31 -6
- package/dist/implementations/network-devices/network-access-guard.js +69 -35
- package/dist/implementations/network-devices/network-device-manager.d.ts +143 -23
- package/dist/implementations/network-devices/network-device-manager.js +206 -35
- package/dist/implementations/ocpp/ocpp16.d.ts +1 -0
- package/dist/implementations/ocpp/ocpp16.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/integrations/wallbox-integration-energy-app.d.ts +4 -2
- package/dist/packages/energy-app-configuration-manager.d.ts +56 -0
- package/dist/packages/energy-app-configuration-manager.js +1 -0
- package/dist/types/enyo-charger-appliance.d.ts +3 -1
- package/dist/types/enyo-charger-appliance.js +2 -0
- package/dist/types/enyo-configuration-manager.d.ts +84 -0
- package/dist/types/enyo-configuration-manager.js +1 -0
- package/dist/types/enyo-data-bus-value.d.ts +8 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,11 +22,17 @@ The official TypeScript SDK for building Energy Apps on the enyo platform. Creat
|
|
|
22
22
|
- [Energy Resources](#energy-resources)
|
|
23
23
|
- [User Features](#user-features)
|
|
24
24
|
- [App Intelligence](#app-intelligence)
|
|
25
|
+
- [Networking & Protocols](#networking--protocols)
|
|
26
|
+
- [Location & Site](#location--site)
|
|
27
|
+
- [Energy Domain APIs](#energy-domain-apis)
|
|
28
|
+
- [Operational Utilities](#operational-utilities)
|
|
25
29
|
- [Advanced Modbus Integration](#advanced-modbus-integration)
|
|
30
|
+
- [Appliance Management](#appliance-management)
|
|
26
31
|
- [Network Devices & Access Recovery](#network-devices--access-recovery)
|
|
27
32
|
- [NetworkAccessGuard](#networkaccessguard)
|
|
28
33
|
- [NetworkDeviceManager](#networkdevicemanager)
|
|
29
34
|
- [Startup pattern](#startup-pattern)
|
|
35
|
+
- [Retry Framework](#retry-framework)
|
|
30
36
|
- [Device Integrations](#device-integrations)
|
|
31
37
|
- [IntegrationEnergyApp (Base Class)](#integrationenergyapp-base-class)
|
|
32
38
|
- [HeatpumpIntegrationEnergyApp](#heatpumpintegrationenergyapp)
|
|
@@ -124,6 +130,25 @@ The SDK exposes several layered building blocks. Pick the one that matches the k
|
|
|
124
130
|
| Forecast EV charging demand | [`EvChargingForecast`](#evchargingforecast) |
|
|
125
131
|
| Forecast heatpump electrical consumption | [`HeatpumpConsumptionForecast`](#heatpumpconsumptionforecast) |
|
|
126
132
|
| Forecast heatpump DHW tank temperature | [`HeatpumpDhwTemperatureForecast`](#heatpumpdhwtemperatureforecast) |
|
|
133
|
+
| Talk to an EEBUS / SHIP / SPINE device | [`useEebus()`](#useeebus-energyappeebus) |
|
|
134
|
+
| Speak MQTT (SDK broker or external) | [`useMqtt()`](#usemqtt-energyappmqtt) |
|
|
135
|
+
| Scan or talk to Bluetooth LE peripherals | [`useBluetooth()`](#usebluetooth-energyappbluetooth) |
|
|
136
|
+
| Send/receive UDP datagrams | [`useUdp()`](#useudp-energyappudp) |
|
|
137
|
+
| Read serial Modbus RTU | [`useModbusRtu()`](#usemodbusrtu-energyappmodbusrtu) |
|
|
138
|
+
| List known WiFi SSIDs in range | [`useWifi()`](#usewifi-energyappwifi) |
|
|
139
|
+
| Query historical timeseries (PV, battery, meter, …) | [`useTimeseries()`](#usetimeseries-energyapptimeseries) |
|
|
140
|
+
| Read site location (zip or coordinates) | [`useLocation()`](#uselocation-energyapplocation) |
|
|
141
|
+
| Read grid connection point (fuse, phases, max power) | [`useGridConnectionPoint()`](#usegridconnectionpoint-energyappgridconnectionpoint) |
|
|
142
|
+
| Retrieve secrets from the developer org secret store | [`useSecretManager()`](#usesecretmanager-energyappsecretmanager) |
|
|
143
|
+
| Submit energy-manager diagnostics | [`useDiagnostics()`](#usediagnostics-energyappdiagnostics) |
|
|
144
|
+
| Register a weather / PV / dynamic-price forecast provider | [`useWeatherForecasting()`](#useweatherforecasting-energyappweatherforecasting) / [`usePvForecasting()`](#usepvforecasting-energyapppvforecasting) / [`useDynamicPriceForecast()`](#usedynamicpriceforecast-energyappdynamicpriceforecast) |
|
|
145
|
+
| Manage electricity tariffs (default tariff, price per kWh) | [`useElectricityTariff()`](#useelectricitytariff-energyappelectricitytariff) |
|
|
146
|
+
| Register a PV system (kWp, DC strings, orientation) | [`usePvSystem()`](#usepvsystem-energyapppvsystem) |
|
|
147
|
+
| Discover capabilities of the active energy manager | [`useEnergyManager()`](#useenergymanager-energyappenergymanager) |
|
|
148
|
+
| Drive a multi-step onboarding flow | [`useOnboarding()`](#useonboarding-energyapponboarding) |
|
|
149
|
+
| Allocate process-local sequential IDs | [`useSequenceGenerator()`](#usesequencegenerator-energyappsequencegenerator) |
|
|
150
|
+
| Manage retries with circuit-breaker semantics | [`RetryManager`](#retry-framework) |
|
|
151
|
+
| Keep an `applianceId` cache in sync with the SDK | [`ApplianceManager`](#appliance-management) |
|
|
127
152
|
|
|
128
153
|
> **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).
|
|
129
154
|
|
|
@@ -229,9 +254,14 @@ const packageDef = defineEnergyAppPackage({
|
|
|
229
254
|
- `Meter`: Energy metering applications
|
|
230
255
|
- `EnergyManagement`: Overall energy optimization
|
|
231
256
|
- `HeatPump`: Heat pump control systems
|
|
257
|
+
- `AirConditioning`: Air-conditioning units
|
|
232
258
|
- `BatteryStorage`: Battery management
|
|
233
259
|
- `ClimateControl`: HVAC and climate systems
|
|
234
|
-
- `
|
|
260
|
+
- `DynamicElectricityTariff`: Dynamic / spot-price tariff providers
|
|
261
|
+
- `StaticElectricityTariff`: Fixed-price tariff providers
|
|
262
|
+
- `TemperatureSensor`: Standalone temperature sensors
|
|
263
|
+
- `SmartPlug`: Smart-plug appliances
|
|
264
|
+
- `Other`: Anything not covered above
|
|
235
265
|
|
|
236
266
|
### Permissions System
|
|
237
267
|
|
|
@@ -260,6 +290,42 @@ Energy Apps use a granular permissions system to control access to system resour
|
|
|
260
290
|
- **`Vehicle`**: Access vehicle information
|
|
261
291
|
- **`Charge`**: Manage charging sessions
|
|
262
292
|
|
|
293
|
+
#### Command Permissions
|
|
294
|
+
|
|
295
|
+
- **`InverterControlCommands`**: Send inverter control commands (e.g. feed-in limit)
|
|
296
|
+
- **`BatteryControlCommands`**: Send battery / storage control commands
|
|
297
|
+
- **`ChargerControlCommands`**: Send wallbox / charger control commands
|
|
298
|
+
|
|
299
|
+
#### Networking & Protocol Permissions
|
|
300
|
+
|
|
301
|
+
- **`ModbusRtu`**: Communicate over Modbus RTU (serial)
|
|
302
|
+
- **`EebusDeviceManagement`**: Pair / discover / connect EEBUS devices
|
|
303
|
+
- **`EebusDataAccess`**: Read EEBUS use-case data
|
|
304
|
+
- **`EebusControl`**: Send EEBUS control commands (write features)
|
|
305
|
+
- **`Mqtt`**: Connect to the internal SDK MQTT broker or external brokers
|
|
306
|
+
- **`Bluetooth`**: Scan and talk to BLE peripherals
|
|
307
|
+
- **`Wifi`**: List known WiFi SSIDs
|
|
308
|
+
- **`Udp`**: Bind UDP sockets and exchange datagrams
|
|
309
|
+
- **`ChildProcess`**: Spawn child processes from the runtime
|
|
310
|
+
|
|
311
|
+
#### Data & Domain Permissions
|
|
312
|
+
|
|
313
|
+
- **`Timeseries`**: Query historical timeseries data
|
|
314
|
+
- **`EnergyPrices`**: Read current and forecast electricity prices
|
|
315
|
+
- **`ElectricityTariff`**: Manage electricity tariffs
|
|
316
|
+
- **`EnergyManager`**: Run as the active energy manager
|
|
317
|
+
- **`EnergyManagerInfo`**: Read information about the active energy manager
|
|
318
|
+
- **`WeatherForecastRegister`** / **`WeatherForecastUse`**: Publish / consume weather forecasts
|
|
319
|
+
- **`PvForecastRegister`** / **`PvForecastUse`**: Publish / consume PV forecasts
|
|
320
|
+
- **`DynamicPriceForecastRegister`** / **`DynamicPriceForecastUse`**: Publish / consume dynamic-price forecasts
|
|
321
|
+
- **`PvSystemRegister`** / **`PvSystemUse`**: Register / read PV system configuration
|
|
322
|
+
|
|
323
|
+
#### Site & Identity Permissions
|
|
324
|
+
|
|
325
|
+
- **`LocationZipCode`**: Read the site's zip-code-level location
|
|
326
|
+
- **`LocationCoordinates`**: Read the site's full coordinates
|
|
327
|
+
- **`SecretManager`**: Read developer-org secrets
|
|
328
|
+
|
|
263
329
|
#### Internet Access
|
|
264
330
|
|
|
265
331
|
- **`RestrictedInternetAccess`**: Access specific internet domains only
|
|
@@ -268,20 +334,30 @@ Energy Apps use a granular permissions system to control access to system resour
|
|
|
268
334
|
|
|
269
335
|
### Lifecycle Management
|
|
270
336
|
|
|
271
|
-
#### `register(callback: (packageName: string, version: number) => void)`
|
|
337
|
+
#### `register(callback: (packageName: string, version: number, channel: EnyoPackageChannel, deviceId: string) => void | Promise<void>)`
|
|
272
338
|
|
|
273
|
-
Register a callback that executes when your Energy App starts
|
|
339
|
+
Register a callback that executes when your Energy App starts. The callback receives the package name, version, release channel (`stable` / `beta` / …), and the device ID the package is running on. It may be `async`.
|
|
274
340
|
|
|
275
341
|
```typescript
|
|
276
|
-
energyApp.register((packageName, version) => {
|
|
277
|
-
console.log(`${packageName} v${version} is now running`);
|
|
342
|
+
energyApp.register(async (packageName, version, channel, deviceId) => {
|
|
343
|
+
console.log(`${packageName} v${version} on ${channel} (device ${deviceId}) is now running`);
|
|
278
344
|
// Initialize your app here
|
|
279
345
|
});
|
|
280
346
|
```
|
|
281
347
|
|
|
282
|
-
#### `
|
|
348
|
+
#### `onNetworkStatusChanged(listener: (online: boolean) => void | Promise<void>): string`
|
|
349
|
+
|
|
350
|
+
Subscribe to system-online transitions. Returns a listener ID. Pairs well with [`isSystemOnline()`](#issystemonline-boolean) for first-state, then deltas:
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
const listenerId = energyApp.onNetworkStatusChanged((online) => {
|
|
354
|
+
console.log(online ? 'System back online' : 'System went offline');
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
#### `onShutdown(callback: () => void | Promise<void>)`
|
|
283
359
|
|
|
284
|
-
Register cleanup logic for graceful shutdown
|
|
360
|
+
Register cleanup logic for graceful shutdown. The callback may be sync or async; it runs on Node `beforeExit` **and** `exit`.
|
|
285
361
|
|
|
286
362
|
```typescript
|
|
287
363
|
energyApp.onShutdown(async () => {
|
|
@@ -480,7 +556,7 @@ const intervalId = interval.createInterval('30s', (clockId) => {
|
|
|
480
556
|
interval.stopInterval(intervalId);
|
|
481
557
|
```
|
|
482
558
|
|
|
483
|
-
**Available intervals**: `'10s'`, `'30s'`, `'1m'`, `'5m'`, `'1hr'`
|
|
559
|
+
**Available intervals**: `'1s'`, `'5s'`, `'10s'`, `'30s'`, `'1m'`, `'5m'`, `'1hr'` (defined by the `IntervalDuration` type — any other string is rejected).
|
|
484
560
|
|
|
485
561
|
### Energy Resources
|
|
486
562
|
|
|
@@ -616,6 +692,50 @@ settings.listenForSettingsChanges((settingName, newValue) => {
|
|
|
616
692
|
const allSettings = await settings.getSettingsConfig();
|
|
617
693
|
```
|
|
618
694
|
|
|
695
|
+
#### `useConfigurationManager(): EnergyAppConfigurationManager`
|
|
696
|
+
|
|
697
|
+
Register **internal**, non user-facing configurations for your package and react to value changes. Unlike `useSettings()`, configurations registered here are NOT rendered in the Energy App UI — they are intended for values the package itself reads and writes at runtime (e.g. internal feature toggles, tuning parameters, calibration values) and need to be persisted across restarts.
|
|
698
|
+
|
|
699
|
+
Each configuration is addressed by a unique `key` and is either of type `number` (with optional `minValue` / `maxValue` / `step` constraints) or `select` (with a fixed list of allowed `selectOptions`).
|
|
700
|
+
|
|
701
|
+
```typescript
|
|
702
|
+
const configManager = energyApp.useConfigurationManager();
|
|
703
|
+
|
|
704
|
+
// Register the full set of internal configurations in a single call
|
|
705
|
+
await configManager.registerConfigurations([
|
|
706
|
+
{
|
|
707
|
+
key: 'pollIntervalMs',
|
|
708
|
+
type: 'number',
|
|
709
|
+
defaultValue: 5000,
|
|
710
|
+
numberOptions: { minValue: 1000, maxValue: 60000, step: 1000 }
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
key: 'logLevel',
|
|
714
|
+
type: 'select',
|
|
715
|
+
defaultValue: 'info',
|
|
716
|
+
selectOptions: [
|
|
717
|
+
{ value: 'debug' },
|
|
718
|
+
{ value: 'info' },
|
|
719
|
+
{ value: 'warn' },
|
|
720
|
+
{ value: 'error' }
|
|
721
|
+
]
|
|
722
|
+
}
|
|
723
|
+
]);
|
|
724
|
+
|
|
725
|
+
// Read the current (or default) value for a configuration
|
|
726
|
+
const pollInterval = await configManager.getConfiguration('pollIntervalMs');
|
|
727
|
+
|
|
728
|
+
// React to value changes
|
|
729
|
+
configManager.onConfigurationChanged(event => {
|
|
730
|
+
console.log(
|
|
731
|
+
`Configuration ${event.key} changed from ${event.previousValue} to ${event.newValue}`
|
|
732
|
+
);
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
// Remove configurations (e.g. on cleanup or after a migration)
|
|
736
|
+
await configManager.unregisterConfigurations(['logLevel']);
|
|
737
|
+
```
|
|
738
|
+
|
|
619
739
|
#### `useElectricityPrices(): EnergyAppElectricityPrices`
|
|
620
740
|
|
|
621
741
|
Access electricity pricing information:
|
|
@@ -722,6 +842,301 @@ await learningPhase.completeLearningPhase(heatpumpPhaseId);
|
|
|
722
842
|
await learningPhase.removeLearningPhase(phaseId);
|
|
723
843
|
```
|
|
724
844
|
|
|
845
|
+
### Networking & Protocols
|
|
846
|
+
|
|
847
|
+
#### `useEebus(): EnergyAppEebus`
|
|
848
|
+
|
|
849
|
+
Talk to EEBUS / SHIP / SPINE devices. The returned facade exposes four sub-interfaces:
|
|
850
|
+
|
|
851
|
+
- `devices` — SHIP-level lifecycle: discovery, pairing, connection.
|
|
852
|
+
- `identity` — Node Identification (NID), observable identity, supported use-case discovery.
|
|
853
|
+
- `useCases` — typed use-case clients (LPC, LPP, MGCP, MPC, OHPCF).
|
|
854
|
+
- `spine` — low-level SPINE escape hatch for features not yet wrapped.
|
|
855
|
+
|
|
856
|
+
```typescript
|
|
857
|
+
const eebus = energyApp.useEebus();
|
|
858
|
+
|
|
859
|
+
const discovered = await eebus.devices.getDiscoveredDevices();
|
|
860
|
+
const device = await eebus.devices.pairDevice(discovered[0].ski);
|
|
861
|
+
|
|
862
|
+
const identity = await eebus.identity.get(device.ski);
|
|
863
|
+
const useCases = await eebus.identity.getSupportedUseCases(device.ski);
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
Requires the `EebusDeviceManagement` permission for the calls above. `EebusDataAccess` / `EebusControl` gate reads and writes on use-case features.
|
|
867
|
+
|
|
868
|
+
#### `useMqtt(): EnergyAppMqtt`
|
|
869
|
+
|
|
870
|
+
Connect to the internal SDK MQTT broker or an external broker, publish, subscribe, and observe connection status.
|
|
871
|
+
|
|
872
|
+
```typescript
|
|
873
|
+
const mqtt = energyApp.useMqtt();
|
|
874
|
+
const client = await mqtt.connectToSdkBroker();
|
|
875
|
+
|
|
876
|
+
await client.subscribe('sensors/+/temperature');
|
|
877
|
+
client.onTopic('sensors/+/temperature', (payload) => {
|
|
878
|
+
console.log('Sensor reading:', payload.toString());
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
await client.publish('control/pump', 'on', /* qos */ 1, /* retain */ false);
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
For external brokers use `connectToExternalBroker(brokerUrl, options)`. Requires the `Mqtt` permission.
|
|
885
|
+
|
|
886
|
+
#### `useBluetooth(): EnergyAppBluetooth`
|
|
887
|
+
|
|
888
|
+
Scan for BLE peripherals and perform GATT read / write / notify against them.
|
|
889
|
+
|
|
890
|
+
```typescript
|
|
891
|
+
const ble = energyApp.useBluetooth();
|
|
892
|
+
|
|
893
|
+
const devices = await ble.scan({ durationMs: 5000 });
|
|
894
|
+
|
|
895
|
+
await ble.withDevice(devices[0].address, async (session) => {
|
|
896
|
+
const value = await session.read('1800', '2a00');
|
|
897
|
+
await session.write('180a', '2a29', new TextEncoder().encode('hi'));
|
|
898
|
+
});
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
Notifications can be consumed three ways from the session: `notifications(svc, ch).onValue(cb)` (push), `.next(timeoutMs)` (pull-once), or `.values()` (async iterator). Requires the `Bluetooth` permission.
|
|
902
|
+
|
|
903
|
+
#### `useUdp(): EnergyAppUdp`
|
|
904
|
+
|
|
905
|
+
Bind UDP sockets and exchange datagrams. Lazily instantiates a single server instance and reuses it on subsequent calls; the permission gate runs on every accessor call so revocations surface consistently.
|
|
906
|
+
|
|
907
|
+
```typescript
|
|
908
|
+
const udp = energyApp.useUdp();
|
|
909
|
+
const socket = await udp.bind(5000);
|
|
910
|
+
|
|
911
|
+
socket.onMessage((data, rinfo) => {
|
|
912
|
+
console.log(`Received ${data.length}B from ${rinfo.address}:${rinfo.port}`);
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
await socket.send(new TextEncoder().encode('hello'), 5001, '192.168.1.50');
|
|
916
|
+
```
|
|
917
|
+
|
|
918
|
+
Throws `EnergyAppPermissionNotGrantedError` if the `Udp` permission isn't granted.
|
|
919
|
+
|
|
920
|
+
#### `useModbusRtu(): EnergyAppModbusRtu`
|
|
921
|
+
|
|
922
|
+
Modbus RTU over serial. Open a port with baud rate / parity / data bits / stop bits, then read/write registers by slave ID.
|
|
923
|
+
|
|
924
|
+
```typescript
|
|
925
|
+
const rtu = energyApp.useModbusRtu();
|
|
926
|
+
const client = await rtu.connect('/dev/ttyUSB0', { baudRate: 9600, parity: 'none' });
|
|
927
|
+
|
|
928
|
+
const registers = await client.readRegisters(/* slaveId */ 1, /* startReg */ 0, /* count */ 10);
|
|
929
|
+
await client.writeRegisters(1, 100, [42, 43]);
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
Requires the `ModbusRtu` permission.
|
|
933
|
+
|
|
934
|
+
#### `useWifi(): EnergyAppWifi`
|
|
935
|
+
|
|
936
|
+
List the SSIDs the device is configured to join that are currently in range.
|
|
937
|
+
|
|
938
|
+
```typescript
|
|
939
|
+
const wifi = energyApp.useWifi();
|
|
940
|
+
const ssids = await wifi.getKnownSsids();
|
|
941
|
+
for (const { ssid } of ssids) console.log(ssid);
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
Requires the `Wifi` permission.
|
|
945
|
+
|
|
946
|
+
### Location & Site
|
|
947
|
+
|
|
948
|
+
#### `useLocation(): EnergyAppLocation`
|
|
949
|
+
|
|
950
|
+
Two-tier location API. Zip-code resolution and full coordinates are gated by separate permissions so apps can opt into the minimum precision they need.
|
|
951
|
+
|
|
952
|
+
```typescript
|
|
953
|
+
const location = energyApp.useLocation();
|
|
954
|
+
|
|
955
|
+
const zip = await location.getZipCodeLocation(); // requires LocationZipCode
|
|
956
|
+
const full = await location.getLocation(); // requires LocationCoordinates
|
|
957
|
+
if (full) console.log(`lat=${full.latitude} lon=${full.longitude}`);
|
|
958
|
+
```
|
|
959
|
+
|
|
960
|
+
#### `useGridConnectionPoint(): EnergyAppGridConnectionPoint`
|
|
961
|
+
|
|
962
|
+
Read the site's grid connection details — main fuse rating, number of phases, and the maximum allowed grid power. Use this to size dispatch envelopes and avoid violating the contractual cap.
|
|
963
|
+
|
|
964
|
+
```typescript
|
|
965
|
+
const gcp = energyApp.useGridConnectionPoint();
|
|
966
|
+
const point = await gcp.getGridConnectionPoint();
|
|
967
|
+
if (point) {
|
|
968
|
+
console.log(`Fuse ${point.fuseAmpere}A across ${point.numberOfPhases} phases`);
|
|
969
|
+
}
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
### Energy Domain APIs
|
|
973
|
+
|
|
974
|
+
#### `useEnergyManager(): EnergyAppEnergyManager`
|
|
975
|
+
|
|
976
|
+
Read information about the currently active energy manager (vendor, version, supported features). Useful for apps that want to behave differently depending on which manager owns dispatch.
|
|
977
|
+
|
|
978
|
+
```typescript
|
|
979
|
+
const em = energyApp.useEnergyManager();
|
|
980
|
+
const info = await em.getEnergyManagerInfo();
|
|
981
|
+
if (info) console.log(`Active manager: ${info.name} v${info.version}`);
|
|
982
|
+
```
|
|
983
|
+
|
|
984
|
+
Requires the `EnergyManagerInfo` permission.
|
|
985
|
+
|
|
986
|
+
#### `useElectricityTariff(): EnergyAppElectricityTariff`
|
|
987
|
+
|
|
988
|
+
Register, retrieve, and manage electricity tariffs. One tariff can be marked as the system default.
|
|
989
|
+
|
|
990
|
+
```typescript
|
|
991
|
+
const tariffs = energyApp.useElectricityTariff();
|
|
992
|
+
|
|
993
|
+
await tariffs.registerTariff({ id: 't1', name: 'Spot 2026', pricePerKwh: 0.21 });
|
|
994
|
+
await tariffs.makeDefaultTariff('t1');
|
|
995
|
+
|
|
996
|
+
const defaultTariff = await tariffs.getDefaultTariff();
|
|
997
|
+
const all = await tariffs.getAllTariffs();
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
Requires the `ElectricityTariff` permission.
|
|
1001
|
+
|
|
1002
|
+
#### `useWeatherForecasting(): EnergyAppWeatherForecasting`
|
|
1003
|
+
|
|
1004
|
+
Register a weather-forecast provider (e.g. wraps an external API) and / or consume forecasts by zip code or coordinates.
|
|
1005
|
+
|
|
1006
|
+
```typescript
|
|
1007
|
+
const weather = energyApp.useWeatherForecasting();
|
|
1008
|
+
|
|
1009
|
+
await weather.registerForecast({ forecastId: 'wx-prod', name: 'OpenWeather' });
|
|
1010
|
+
const byZip = await weather.getWeatherForecastByZipCode('wx-prod');
|
|
1011
|
+
const byCoords = await weather.getWeatherForecastByCoordinates('wx-prod', 48.13, 11.57);
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
Publishers need `WeatherForecastRegister`; consumers need `WeatherForecastUse`.
|
|
1015
|
+
|
|
1016
|
+
#### `usePvForecasting(): EnergyAppPvForecasting`
|
|
1017
|
+
|
|
1018
|
+
Same shape as weather forecasting, but for PV production.
|
|
1019
|
+
|
|
1020
|
+
```typescript
|
|
1021
|
+
const pvForecast = energyApp.usePvForecasting();
|
|
1022
|
+
await pvForecast.registerForecast({ forecastId: 'pv-prod', name: 'Solargis' });
|
|
1023
|
+
const forecast = await pvForecast.getPvForecast('pv-prod');
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
Publishers need `PvForecastRegister`; consumers need `PvForecastUse`.
|
|
1027
|
+
|
|
1028
|
+
#### `useDynamicPriceForecast(): EnergyAppDynamicPriceForecast`
|
|
1029
|
+
|
|
1030
|
+
Publish and consume forward-looking electricity-price forecasts (e.g. day-ahead spot). The data is forecast only — never settled prices.
|
|
1031
|
+
|
|
1032
|
+
```typescript
|
|
1033
|
+
const dpf = energyApp.useDynamicPriceForecast();
|
|
1034
|
+
|
|
1035
|
+
await dpf.registerForecast({ forecastId: 'epex-da', name: 'EPEX Day-Ahead', vendor: 'EPEX' });
|
|
1036
|
+
await dpf.publishForecast('epex-da', {
|
|
1037
|
+
currency: 'EUR',
|
|
1038
|
+
resolution: '1h',
|
|
1039
|
+
entries: [{ timestampIso: '2026-05-23T10:00:00Z', consumptionPricePerKwh: 0.21 }]
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
const latest = await dpf.getLatestForecast();
|
|
1043
|
+
dpf.onForecastPublished((forecast) => console.log('new forecast', forecast.forecastId));
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
Publishers need `DynamicPriceForecastRegister`; consumers need `DynamicPriceForecastUse`.
|
|
1047
|
+
|
|
1048
|
+
#### `usePvSystem(): EnergyAppPvSystem`
|
|
1049
|
+
|
|
1050
|
+
Register a PV system's structural configuration (kWp, DC string orientations, associated appliances) so other apps can reason about expected production.
|
|
1051
|
+
|
|
1052
|
+
```typescript
|
|
1053
|
+
const pv = energyApp.usePvSystem();
|
|
1054
|
+
await pv.registerPvSystem({
|
|
1055
|
+
id: 'pv-1',
|
|
1056
|
+
kWp: 9.6,
|
|
1057
|
+
dcStrings: [
|
|
1058
|
+
{ azimuth: 180, tilt: 30 },
|
|
1059
|
+
{ azimuth: 90, tilt: 30 }
|
|
1060
|
+
]
|
|
1061
|
+
});
|
|
1062
|
+
const systems = await pv.getPvSystems();
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
Publishers need `PvSystemRegister`; consumers need `PvSystemUse`.
|
|
1066
|
+
|
|
1067
|
+
#### `useTimeseries(): EnergyAppTimeseries`
|
|
1068
|
+
|
|
1069
|
+
Query historical 15-minute aggregated data across the energy domain (PV production, battery SoC / power, meter values, grid power, home consumption, heatpump electrical / thermal, air-conditioning, temperature sensors). Some endpoints also support 1-minute resolution.
|
|
1070
|
+
|
|
1071
|
+
```typescript
|
|
1072
|
+
const ts = energyApp.useTimeseries();
|
|
1073
|
+
const last24h = await ts.query({
|
|
1074
|
+
dataType: 'pvProduction',
|
|
1075
|
+
resolution: '15m',
|
|
1076
|
+
startTime: Date.now() - 24 * 60 * 60 * 1000,
|
|
1077
|
+
endTime: Date.now()
|
|
1078
|
+
});
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
Requires the `Timeseries` permission.
|
|
1082
|
+
|
|
1083
|
+
#### `useDiagnostics(): EnergyAppDiagnostics`
|
|
1084
|
+
|
|
1085
|
+
Energy-manager packages can submit their current state, forecast, and control plan to internal diagnostics for offline analysis. Fire-and-forget.
|
|
1086
|
+
|
|
1087
|
+
```typescript
|
|
1088
|
+
const diag = energyApp.useDiagnostics();
|
|
1089
|
+
diag.energyManagerDiagnostics(
|
|
1090
|
+
{ batterySoc: 47, gridPowerW: 1200 },
|
|
1091
|
+
{ pvNext24h: [...] },
|
|
1092
|
+
{ actions: [{ applianceId: 'battery-1', mode: 'charge', powerW: 3000 }] }
|
|
1093
|
+
);
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
### Operational Utilities
|
|
1097
|
+
|
|
1098
|
+
#### `useOnboarding(): EnergyAppOnboarding`
|
|
1099
|
+
|
|
1100
|
+
Drive a multi-step onboarding guide — start / advance / back / skip / cancel, persist responses, and observe step transitions.
|
|
1101
|
+
|
|
1102
|
+
```typescript
|
|
1103
|
+
const guide = energyApp.useOnboarding();
|
|
1104
|
+
|
|
1105
|
+
await guide.startGuide('pv-setup', EnyoOnboardingGuideCategory.PvSystem);
|
|
1106
|
+
const step = await guide.nextStep('pv-setup');
|
|
1107
|
+
await guide.respondToStep('pv-setup', { answer: 'yes' });
|
|
1108
|
+
|
|
1109
|
+
const listenerId = guide.onStepListener('pv-setup', (event) => {
|
|
1110
|
+
console.log('step changed:', event.stepId);
|
|
1111
|
+
});
|
|
1112
|
+
```
|
|
1113
|
+
|
|
1114
|
+
#### `useSecretManager(): EnergyAppSecretManager`
|
|
1115
|
+
|
|
1116
|
+
Encrypted retrieval / storage of developer-org secrets (API keys, vendor tokens, OAuth client secrets). Strongly typed accessors keep the call site safe.
|
|
1117
|
+
|
|
1118
|
+
```typescript
|
|
1119
|
+
const secrets = energyApp.useSecretManager();
|
|
1120
|
+
|
|
1121
|
+
await secrets.saveSecret('weather-api', { token: 'xyz' });
|
|
1122
|
+
const cred = await secrets.getSecret<{ token: string }>('weather-api');
|
|
1123
|
+
|
|
1124
|
+
const names = await secrets.listAvailableSecrets();
|
|
1125
|
+
await secrets.removeSecret('weather-api');
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
Requires the `SecretManager` permission.
|
|
1129
|
+
|
|
1130
|
+
#### `useSequenceGenerator(): EnergyAppSequenceGenerator`
|
|
1131
|
+
|
|
1132
|
+
Process-local monotonic counter, keyed by an arbitrary name. Use it for stable request / message IDs without coordinating across instances.
|
|
1133
|
+
|
|
1134
|
+
```typescript
|
|
1135
|
+
const seq = energyApp.useSequenceGenerator();
|
|
1136
|
+
const reqId = await seq.next('mqtt-publish'); // 1, 2, 3, …
|
|
1137
|
+
const txId = await seq.next('ocpp-tx'); // independent counter
|
|
1138
|
+
```
|
|
1139
|
+
|
|
725
1140
|
## Advanced Modbus Integration
|
|
726
1141
|
|
|
727
1142
|
The SDK includes a powerful, vendor-agnostic Modbus implementation for energy management systems. This allows you to connect to any Modbus-enabled device through configuration without code changes.
|
|
@@ -910,6 +1325,60 @@ The Modbus implementation follows a clean, modular architecture:
|
|
|
910
1325
|
|
|
911
1326
|
This modular design ensures maintainability, testability, and extensibility for future enhancements.
|
|
912
1327
|
|
|
1328
|
+
## Appliance Management
|
|
1329
|
+
|
|
1330
|
+
`ApplianceManager` is the recommended way to keep the SDK's appliance list and your in-process state in sync. It wraps `useAppliances()` with caching, identifier-based lookup strategies, bulk operations, and helpers that the device-integrations and `NetworkDeviceManager` consume internally.
|
|
1331
|
+
|
|
1332
|
+
```typescript
|
|
1333
|
+
import { ApplianceManager } from '@enyo-energy/energy-app-sdk';
|
|
1334
|
+
|
|
1335
|
+
const applianceManager = await ApplianceManager.initialize(energyApp, {
|
|
1336
|
+
// Optional config: identifier strategy, cache options, etc.
|
|
1337
|
+
});
|
|
1338
|
+
|
|
1339
|
+
// Create or update by identifier (idempotent — uses the configured strategy).
|
|
1340
|
+
const applianceId = await applianceManager.createOrUpdateAppliance({
|
|
1341
|
+
identifier: 'sn-1234567890',
|
|
1342
|
+
name: [{ language: 'en', name: 'Inverter A' }],
|
|
1343
|
+
type: EnyoApplianceTypeEnum.Inverter,
|
|
1344
|
+
/* ... */
|
|
1345
|
+
});
|
|
1346
|
+
|
|
1347
|
+
// Lookups
|
|
1348
|
+
const inverters = await applianceManager.getAppliancesByType(EnyoApplianceTypeEnum.Inverter);
|
|
1349
|
+
const byId = await applianceManager.findApplianceById(applianceId);
|
|
1350
|
+
const matches = await applianceManager.findByIdentifier('sn-1234567890');
|
|
1351
|
+
|
|
1352
|
+
// State transitions
|
|
1353
|
+
await applianceManager.updateApplianceState(
|
|
1354
|
+
applianceId,
|
|
1355
|
+
EnyoApplianceConnectionType.Modbus,
|
|
1356
|
+
EnyoApplianceStateEnum.Connected
|
|
1357
|
+
);
|
|
1358
|
+
```
|
|
1359
|
+
|
|
1360
|
+
**Key methods**
|
|
1361
|
+
|
|
1362
|
+
| Method | Purpose |
|
|
1363
|
+
|---|---|
|
|
1364
|
+
| `static initialize(app, config?)` | Build a manager, prime the cache, install SDK listeners. |
|
|
1365
|
+
| `createOrUpdateAppliance(config)` | Upsert by the configured `IdentifierStrategy`. Returns the appliance ID. Throws `MissingIdentifierError` if the strategy returns no identifier, or `DuplicateIdentifierError` if the identifier maps to more than one appliance. |
|
|
1366
|
+
| `updateAppliance(id, patch)` | Patch an existing appliance. |
|
|
1367
|
+
| `removeAppliance(id)` / `removeAppliancesByIdentifier(id)` | Delete one / many. |
|
|
1368
|
+
| `findApplianceById(id)` | SDK lookup by appliance ID. Returns `null` on not-found; **propagates** SDK errors. |
|
|
1369
|
+
| `findByIdentifier(extractedId)` | Cache-first lookup keyed by the configured identifier strategy. Falls through to one SDK list call on cache miss. |
|
|
1370
|
+
| `findFirstByStrategies(value, strategies)` | Probes each strategy in order against the SDK list; returns the first match plus which strategy hit. |
|
|
1371
|
+
| `findAppliancesByNetworkDeviceId(deviceId)` | Synchronous, cache-backed reverse lookup from a NetworkDevice to its appliances. |
|
|
1372
|
+
| `getAppliancesByType(type)` / `getAllAppliancesByType(type)` | Filtered listing (own / all). |
|
|
1373
|
+
| `updateApplianceState(id, connection, state)` | State transitions (`Connected` / `Offline` / `Error` / …). |
|
|
1374
|
+
| `setAppliancesStateByIdentifier(id, state)` | Bulk state transition for every appliance sharing an identifier; preserves each appliance's existing `connectionType`. |
|
|
1375
|
+
| `bulkUpdate(updates)` | Atomic batch of state changes. |
|
|
1376
|
+
| `setIdentifierStrategy(strategy, rebuildCache)` / `getIdentifierStrategy()` | Swap the identifier-resolution strategy at runtime. `rebuildCache` is required: pass `false` to keep the cached appliances and just recompute the in-memory identifier index against the new strategy, or `true` to force a full refresh from the SDK. |
|
|
1377
|
+
| `refreshCache()` / `clearCache()` | Manual cache control. |
|
|
1378
|
+
| `dispose()` | Release SDK listeners. |
|
|
1379
|
+
|
|
1380
|
+
Identifier strategies are exported from the package — typical choices match on serial number, hostname, or a composite of `manufacturer + model + sn`.
|
|
1381
|
+
|
|
913
1382
|
## Network Devices & Access Recovery
|
|
914
1383
|
|
|
915
1384
|
Packages that talk to local hardware over TCP (Modbus, SunSpec, EEBUS over SHIP, REST) must deal with two failure modes the `useNetworkDevices()` API exposes only at a low level:
|
|
@@ -1026,7 +1495,9 @@ What the manager handles for you:
|
|
|
1026
1495
|
|
|
1027
1496
|
- **Access-denied recovery** — `withAccessGuard` / `ensureAccess` delegate to the bundled `NetworkAccessGuard`.
|
|
1028
1497
|
- **User-driven transitions** — on `listenForDeviceAccessChange`, the manager dispatches `onApplianceAccessRestored` on `'granted'` and `onApplianceAccessRevoked` on `'denied'` / `'pending'`, resolving each transition into the per-appliance events your reconnect/disconnect code needs.
|
|
1029
|
-
- **Listener dedup** — the manager
|
|
1498
|
+
- **Listener dedup** — both the manager's SDK access-change listener and the guard's own restored callback feed into the same internal `dispatchAccessRestored`. The manager records which devices have already been dispatched for the current `'granted'` transition and short-circuits a second dispatch, so the dedup is order-independent and does not rely on SDK listener FIFO semantics. The mark is cleared on the next non-granted transition or device removal.
|
|
1499
|
+
- **AccessDenied vs AccessRevoked** — both signal "the package can no longer read this device", but the source differs. `onApplianceAccessDenied` fires when `withAccessGuard` catches a runtime read error (the SDK's "Network access denied" message). `onApplianceAccessRevoked` fires when the SDK explicitly reports a status transition to `'denied'` or `'pending'` (typically a user-driven UI action). Wire both if you want a single "lost access" signal — they will not double-fire for one underlying event.
|
|
1500
|
+
- **One manager per `EnergyApp`** — `NetworkDeviceManager.initialize` enforces a single active manager per `EnergyApp` instance. Calling it a second time without first calling `dispose()` throws `NetworkDeviceManagerAlreadyInitializedError`. After disposal a fresh manager can be created.
|
|
1030
1501
|
- **Device removal** — on `listenForNetworkDeviceRemoved`, the manager fires `onApplianceNetworkDeviceRemoved` per affected appliance and clears its cache.
|
|
1031
1502
|
- **Optional auto-state toggle** — with `autoToggleApplianceState: true`, the manager flips affected appliances to `EnyoApplianceStateEnum.Offline` on denial / revocation / removal, and back to `EnyoApplianceStateEnum.Connected` on restoration, via `applianceManager.updateApplianceState(...)`.
|
|
1032
1503
|
|
|
@@ -1069,6 +1540,37 @@ async function connectDevice(networkDeviceId: string) {
|
|
|
1069
1540
|
|
|
1070
1541
|
This pattern matches the wiring used by real Sungrow / Fronius energy-app packages: one `NetworkDeviceManager` per package, `ensureAccess` before every connect, `withAccessGuard` around every poll, and a single `getDevices({ accessStatus: 'granted' })` pass at startup to cover the warm-restart case.
|
|
1071
1542
|
|
|
1543
|
+
## Retry Framework
|
|
1544
|
+
|
|
1545
|
+
`RetryManager` centralises retry / backoff / circuit-breaker logic so polling loops don't have to reinvent it. Register one entry per logical operation, give it a `RetryPolicy`, and run attempts through `execute(id, fn)` — the manager handles attempt counting, exponential backoff, transition into `Open` after repeated failures, and recovery on the next success.
|
|
1546
|
+
|
|
1547
|
+
```typescript
|
|
1548
|
+
import { RetryManager, exponentialBackoff } from '@enyo-energy/energy-app-sdk';
|
|
1549
|
+
|
|
1550
|
+
const retries = new RetryManager();
|
|
1551
|
+
|
|
1552
|
+
retries.register('modbus-inverter-1', {
|
|
1553
|
+
backoff: exponentialBackoff({ initialMs: 1_000, maxMs: 60_000, factor: 2 }),
|
|
1554
|
+
maxAttempts: Infinity, // keep retrying forever
|
|
1555
|
+
openAfterConsecutiveFailures: 5, // trip the breaker after 5 fails
|
|
1556
|
+
});
|
|
1557
|
+
|
|
1558
|
+
const value = await retries.execute('modbus-inverter-1', () =>
|
|
1559
|
+
modbusClient.readHoldingRegisters(40000, 4)
|
|
1560
|
+
);
|
|
1561
|
+
|
|
1562
|
+
// React to circuit-breaker transitions (Idle → Retrying → Open → Closed).
|
|
1563
|
+
const unsubscribe = retries.onStateChange((snapshot) => {
|
|
1564
|
+
console.log(`[${snapshot.id}] ${snapshot.state} (attempt ${snapshot.attempts})`);
|
|
1565
|
+
});
|
|
1566
|
+
|
|
1567
|
+
retries.statuses(); // current snapshots of every registered op
|
|
1568
|
+
retries.reset('modbus-inverter-1');
|
|
1569
|
+
retries.unregister('modbus-inverter-1');
|
|
1570
|
+
```
|
|
1571
|
+
|
|
1572
|
+
Backoff helpers (`exponentialBackoff`, `fixedBackoff`, `linearBackoff` — see `src/implementations/retry/backoff.ts`) and the dedicated error types (`RetryAbortedError`, `RetryOpenError`) live alongside the manager so you can distinguish "we gave up" from "the caller cancelled".
|
|
1573
|
+
|
|
1072
1574
|
## Device Integrations
|
|
1073
1575
|
|
|
1074
1576
|
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.
|
|
@@ -1382,7 +1884,7 @@ const battery = new BatteryForecast(energyApp, 'battery-1', {
|
|
|
1382
1884
|
|
|
1383
1885
|
await Promise.all([pv.initialize(), battery.initialize()]);
|
|
1384
1886
|
|
|
1385
|
-
energyApp.useInterval().createInterval('
|
|
1887
|
+
energyApp.useInterval().createInterval('5m', () => {
|
|
1386
1888
|
const pvNext24h = pv.getForecast();
|
|
1387
1889
|
const batteryNext24h = battery.getForecast();
|
|
1388
1890
|
runDispatch(pvNext24h, batteryNext24h);
|
|
@@ -1919,7 +2421,7 @@ For more information about the CLI, visit [@enyo-energy/cli on npm](https://www.
|
|
|
1919
2421
|
|
|
1920
2422
|
---
|
|
1921
2423
|
|
|
1922
|
-
**Package Version:** 0.0.
|
|
2424
|
+
**Package Version:** see `package.json` (`version` field) — currently `0.0.134`
|
|
1923
2425
|
**SDK Version:** Auto-injected during build
|
|
1924
2426
|
**License:** ISC
|
|
1925
2427
|
**Repository:** [github.com/enyo-energy/energy-app-sdk](https://github.com/enyo-energy/energy-app-sdk)
|
package/dist/cjs/energy-app.cjs
CHANGED
|
@@ -288,6 +288,16 @@ class EnergyApp {
|
|
|
288
288
|
useGridConnectionPoint() {
|
|
289
289
|
return this.energyAppSdk.useGridConnectionPoint();
|
|
290
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Gets the Configuration Manager API for registering internal (non user-facing)
|
|
293
|
+
* package configurations. Configurations are typed as either `number` or
|
|
294
|
+
* `select`, addressed by a unique key, and emit change events when their
|
|
295
|
+
* persisted value is updated.
|
|
296
|
+
* @returns The Configuration Manager API instance
|
|
297
|
+
*/
|
|
298
|
+
useConfigurationManager() {
|
|
299
|
+
return this.energyAppSdk.useConfigurationManager();
|
|
300
|
+
}
|
|
291
301
|
/**
|
|
292
302
|
* Gets the current SDK version.
|
|
293
303
|
* @returns The semantic version string of the SDK
|
|
@@ -34,6 +34,7 @@ import { EnergyAppLearningPhase } from "./packages/energy-app-learning-phase.cjs
|
|
|
34
34
|
import { EnergyAppWifi } from "./packages/energy-app-wifi.cjs";
|
|
35
35
|
import { EnergyAppUdp } from "./packages/energy-app-udp.cjs";
|
|
36
36
|
import { EnergyAppGridConnectionPoint } from "./packages/energy-app-grid-connection-point.cjs";
|
|
37
|
+
import { EnergyAppConfigurationManager } from "./packages/energy-app-configuration-manager.cjs";
|
|
37
38
|
/**
|
|
38
39
|
* Concrete implementation of {@link EnyoEnergyAppSdk} that delegates every call
|
|
39
40
|
* to the runtime-provided `energyAppSdkInstance` global.
|
|
@@ -223,6 +224,14 @@ export declare class EnergyApp implements EnyoEnergyAppSdk {
|
|
|
223
224
|
* @returns The Grid Connection Point API instance
|
|
224
225
|
*/
|
|
225
226
|
useGridConnectionPoint(): EnergyAppGridConnectionPoint;
|
|
227
|
+
/**
|
|
228
|
+
* Gets the Configuration Manager API for registering internal (non user-facing)
|
|
229
|
+
* package configurations. Configurations are typed as either `number` or
|
|
230
|
+
* `select`, addressed by a unique key, and emit change events when their
|
|
231
|
+
* persisted value is updated.
|
|
232
|
+
* @returns The Configuration Manager API instance
|
|
233
|
+
*/
|
|
234
|
+
useConfigurationManager(): EnergyAppConfigurationManager;
|
|
226
235
|
/**
|
|
227
236
|
* Gets the current SDK version.
|
|
228
237
|
* @returns The semantic version string of the SDK
|