@enyo-energy/energy-app-sdk 1.23.0 → 1.25.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 +109 -2
- package/dist/cjs/implementations/onboarding-v2/define-onboarding-guide-v2.cjs +9 -3
- package/dist/cjs/implementations/onboarding-v2/define-onboarding-guide-v2.d.cts +9 -3
- package/dist/cjs/implementations/onboarding-v2/onboarding-v2-validators.cjs +7 -3
- package/dist/cjs/integrations/integration-energy-app.cjs +45 -0
- package/dist/cjs/integrations/integration-energy-app.d.cts +35 -1
- package/dist/cjs/packages/energy-app-grid-connection-point.d.cts +6 -1
- package/dist/cjs/types/enyo-charger-appliance.cjs +6 -0
- package/dist/cjs/types/enyo-charger-appliance.d.cts +7 -1
- package/dist/cjs/types/enyo-data-bus-value.cjs +2 -0
- package/dist/cjs/types/enyo-data-bus-value.d.cts +161 -2
- package/dist/cjs/types/enyo-eebus.d.cts +13 -0
- package/dist/cjs/types/enyo-electricity-tariff.d.cts +9 -0
- package/dist/cjs/types/enyo-grid-connection-point.cjs +8 -0
- package/dist/cjs/types/enyo-grid-connection-point.d.cts +21 -0
- package/dist/cjs/types/enyo-onboarding-v2-eebus-device-select.d.cts +13 -1
- package/dist/cjs/types/enyo-onboarding-v2.d.cts +25 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/implementations/onboarding-v2/define-onboarding-guide-v2.d.ts +9 -3
- package/dist/implementations/onboarding-v2/define-onboarding-guide-v2.js +9 -3
- package/dist/implementations/onboarding-v2/onboarding-v2-validators.js +7 -3
- package/dist/integrations/integration-energy-app.d.ts +35 -1
- package/dist/integrations/integration-energy-app.js +45 -0
- package/dist/packages/energy-app-grid-connection-point.d.ts +6 -1
- package/dist/types/enyo-charger-appliance.d.ts +7 -1
- package/dist/types/enyo-charger-appliance.js +6 -0
- package/dist/types/enyo-data-bus-value.d.ts +161 -2
- package/dist/types/enyo-data-bus-value.js +2 -0
- package/dist/types/enyo-eebus.d.ts +13 -0
- package/dist/types/enyo-electricity-tariff.d.ts +9 -0
- package/dist/types/enyo-grid-connection-point.d.ts +21 -0
- package/dist/types/enyo-grid-connection-point.js +7 -1
- package/dist/types/enyo-onboarding-v2-eebus-device-select.d.ts +13 -1
- package/dist/types/enyo-onboarding-v2.d.ts +25 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -184,7 +184,7 @@ The SDK exposes several layered building blocks. Pick the one that matches the k
|
|
|
184
184
|
| List known WiFi SSIDs in range | [`useWifi()`](#usewifi-energyappwifi) |
|
|
185
185
|
| Query historical timeseries (PV, battery, meter, …) | [`useTimeseries()`](#usetimeseries-energyapptimeseries) |
|
|
186
186
|
| Read site location (zip or coordinates) | [`useLocation()`](#uselocation-energyapplocation) |
|
|
187
|
-
| Read grid connection point (fuse, phases, max power) | [`useGridConnectionPoint()`](#usegridconnectionpoint-energyappgridconnectionpoint) |
|
|
187
|
+
| Read grid connection point (fuse, phases, max power, charger limit) | [`useGridConnectionPoint()`](#usegridconnectionpoint-energyappgridconnectionpoint) |
|
|
188
188
|
| Retrieve secrets from the developer org secret store | [`useSecretManager()`](#usesecretmanager-energyappsecretmanager) |
|
|
189
189
|
| Submit energy-manager diagnostics | [`useDiagnostics()`](#usediagnostics-energyappdiagnostics) |
|
|
190
190
|
| Register a weather / PV / dynamic-price forecast provider | [`useWeatherForecasting()`](#useweatherforecasting-energyappweatherforecasting) / [`usePvForecasting()`](#usepvforecasting-energyapppvforecasting) / [`useDynamicPriceForecast()`](#usedynamicpriceforecast-energyappdynamicpriceforecast) |
|
|
@@ -1592,13 +1592,18 @@ if (full) console.log(`lat=${full.latitude} lon=${full.longitude}`);
|
|
|
1592
1592
|
|
|
1593
1593
|
#### `useGridConnectionPoint(): EnergyAppGridConnectionPoint`
|
|
1594
1594
|
|
|
1595
|
-
Read the site's grid connection details — main fuse rating, number of phases,
|
|
1595
|
+
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.
|
|
1596
|
+
|
|
1597
|
+
`chargerLimitW` is optional: when it is not configured, load balancing falls back to `DEFAULT_CHARGER_LIMIT_W` (11 kW).
|
|
1596
1598
|
|
|
1597
1599
|
```typescript
|
|
1600
|
+
import {DEFAULT_CHARGER_LIMIT_W} from "@enyo-energy/energy-app-sdk";
|
|
1601
|
+
|
|
1598
1602
|
const gcp = energyApp.useGridConnectionPoint();
|
|
1599
1603
|
const point = await gcp.getGridConnectionPoint();
|
|
1600
1604
|
if (point) {
|
|
1601
1605
|
console.log(`Fuse ${point.fuseAmpere}A across ${point.numberOfPhases} phases`);
|
|
1606
|
+
console.log(`Charger limit ${point.chargerLimitW ?? DEFAULT_CHARGER_LIMIT_W} W`);
|
|
1602
1607
|
}
|
|
1603
1608
|
```
|
|
1604
1609
|
|
|
@@ -1725,6 +1730,14 @@ await tariffs.publishPrices(EnyoTariffDirectionEnum.Consumption, {
|
|
|
1725
1730
|
});
|
|
1726
1731
|
```
|
|
1727
1732
|
|
|
1733
|
+
An entry may carry an optional `gridFeeGrossPerKwh`: the gross grid fee **contained in**
|
|
1734
|
+
`pricePerKwh`, in currency units per kWh. It is a breakdown only — `pricePerKwh` is always the
|
|
1735
|
+
total, so never compute `pricePerKwh + gridFeeGrossPerKwh`.
|
|
1736
|
+
|
|
1737
|
+
```typescript
|
|
1738
|
+
entries.push({ timestampIso: '2026-05-23T10:00:00Z', pricePerKwh: 0.31, gridFeeGrossPerKwh: 0.09 });
|
|
1739
|
+
```
|
|
1740
|
+
|
|
1728
1741
|
**Calling `setTariff` is the activation signal.** Return `AuthenticationRequired` or
|
|
1729
1742
|
`OnboardingRequired` from the handler to have the host send the user somewhere, and carry the
|
|
1730
1743
|
`authenticationUrl` / `onboardingGuideId` that makes it actionable; when that flow later completes,
|
|
@@ -4453,6 +4466,100 @@ Notes:
|
|
|
4453
4466
|
grant can be read against the announcement it answers. It is advisory — the
|
|
4454
4467
|
command's `powerW` remains the only limit.
|
|
4455
4468
|
|
|
4469
|
+
#### Announcing Power Flexibility
|
|
4470
|
+
|
|
4471
|
+
`ApplianceFlexibilityAnnouncementV2` is the **power-based** sibling of the
|
|
4472
|
+
announcement above. Where V1 says "4 kWh by 14:00", V2 says "I can draw
|
|
4473
|
+
800–2300 W, you may start me any time between 10:00 and 14:00, and I will then
|
|
4474
|
+
run for up to 90 minutes".
|
|
4475
|
+
|
|
4476
|
+
Which one to send is decided by the demand, not by preference:
|
|
4477
|
+
|
|
4478
|
+
| | Send V1 | Send V2 |
|
|
4479
|
+
| --- | --- | --- |
|
|
4480
|
+
| The appliance owes a known amount of energy by a deadline | ✅ | |
|
|
4481
|
+
| The appliance can absorb power, and the energy falls out of how long it runs | | ✅ |
|
|
4482
|
+
| Example | A charging session that needs 22 kWh by 07:00 | A heat pump that will take surplus into its tank |
|
|
4483
|
+
|
|
4484
|
+
V2 deliberately has **no `kWh` field**. An energy figure would be read as
|
|
4485
|
+
authoritative the moment it existed, and the message would collapse back into V1
|
|
4486
|
+
with extra fields. An appliance that knows its energy sends V1.
|
|
4487
|
+
|
|
4488
|
+
**The window is a trigger window, not a run window.**
|
|
4489
|
+
`availableFromIsoTimestamp` and `availableUntilIsoTimestamp` bound when the run
|
|
4490
|
+
may be *started*. `durationMinutes` says how long it then runs — a run started
|
|
4491
|
+
one minute before the window closes may still be drawing power long afterwards.
|
|
4492
|
+
|
|
4493
|
+
```typescript
|
|
4494
|
+
import {
|
|
4495
|
+
EnergyApp,
|
|
4496
|
+
EnyoFlexibilityTargetEnum,
|
|
4497
|
+
} from '@enyo-energy/energy-app-sdk';
|
|
4498
|
+
|
|
4499
|
+
const energyApp = new EnergyApp();
|
|
4500
|
+
const dataBus = energyApp.useDataBus();
|
|
4501
|
+
|
|
4502
|
+
dataBus.sendMessage([{
|
|
4503
|
+
type: 'message',
|
|
4504
|
+
message: 'ApplianceFlexibilityAnnouncementV2',
|
|
4505
|
+
applianceId: 'heatpump-1',
|
|
4506
|
+
data: {
|
|
4507
|
+
flexibility: {
|
|
4508
|
+
// Modulating compressor: 800 W to 2300 W in 100 W steps.
|
|
4509
|
+
power: {minWatt: 800, maxWatt: 2300, stepWatt: 100},
|
|
4510
|
+
// May be started any time this morning ...
|
|
4511
|
+
availableFromIsoTimestamp: '2025-10-01T10:00:00Z',
|
|
4512
|
+
availableUntilIsoTimestamp: '2025-10-01T14:00:00Z',
|
|
4513
|
+
// ... and then runs for up to 90 minutes, 20 at the very least.
|
|
4514
|
+
durationMinutes: 90,
|
|
4515
|
+
minDurationMinutes: 20,
|
|
4516
|
+
// What the power would go into. Required here, unlike in V1.
|
|
4517
|
+
targets: [
|
|
4518
|
+
{target: EnyoFlexibilityTargetEnum.DomesticHotWater, powerW: 1500},
|
|
4519
|
+
{target: EnyoFlexibilityTargetEnum.BufferTank, powerW: 800},
|
|
4520
|
+
],
|
|
4521
|
+
},
|
|
4522
|
+
},
|
|
4523
|
+
}]);
|
|
4524
|
+
```
|
|
4525
|
+
|
|
4526
|
+
Integrations built on the SDK's integration base classes can publish the same
|
|
4527
|
+
message without assembling the envelope by hand:
|
|
4528
|
+
|
|
4529
|
+
```typescript
|
|
4530
|
+
class MyHeatpump extends HeatpumpIntegrationEnergyApp {
|
|
4531
|
+
private announce(): void {
|
|
4532
|
+
this.publishFlexibilityAnnouncement('heatpump-1', {
|
|
4533
|
+
power: {minWatt: 800, maxWatt: 2300, stepWatt: 100},
|
|
4534
|
+
availableUntilIsoTimestamp: '2025-10-01T14:00:00Z',
|
|
4535
|
+
durationMinutes: 90,
|
|
4536
|
+
targets: [
|
|
4537
|
+
{target: EnyoFlexibilityTargetEnum.DomesticHotWater, powerW: 1500},
|
|
4538
|
+
],
|
|
4539
|
+
});
|
|
4540
|
+
}
|
|
4541
|
+
}
|
|
4542
|
+
```
|
|
4543
|
+
|
|
4544
|
+
Notes:
|
|
4545
|
+
|
|
4546
|
+
- `power` is a band (`minWatt` / `maxWatt` / `stepWatt`), not a single figure,
|
|
4547
|
+
because a modulating appliance is *placed*, not switched. A fixed-power
|
|
4548
|
+
appliance states the same value for both bounds and a `stepWatt` equal to the
|
|
4549
|
+
band's width.
|
|
4550
|
+
- `targets` is **required** here. V1 has no need of it — `kWh` is authoritative
|
|
4551
|
+
there and the breakdown is decoration. V2 has no energy figure, so the targets
|
|
4552
|
+
are the substance of the announcement.
|
|
4553
|
+
- `durationMinutes` omitted means the appliance sets no limit of its own and is
|
|
4554
|
+
expected to stop itself when it is satisfied. `minDurationMinutes` is the
|
|
4555
|
+
shortest run still worth starting — below it, a consumer filling a short gap
|
|
4556
|
+
should leave the appliance alone rather than cycle it.
|
|
4557
|
+
- `context.progress` is worth setting precisely because there is no energy
|
|
4558
|
+
figure: without it a consumer cannot tell a run that has nearly finished from
|
|
4559
|
+
one that has barely started.
|
|
4560
|
+
- V1 is unchanged and remains fully supported. V2 is an additive sibling, not a
|
|
4561
|
+
migration.
|
|
4562
|
+
|
|
4456
4563
|
#### Explaining Why a Command Was Issued
|
|
4457
4564
|
|
|
4458
4565
|
Every data bus command can carry an `EnyoDataBusCommandReason`. Its `type`
|
|
@@ -306,7 +306,11 @@ exports.onboardingV2Block = {
|
|
|
306
306
|
* Filter it. `deviceTypes` is what turns this from "here are the six EEBUS
|
|
307
307
|
* devices in the house" into "here is your heat pump", and with one match it
|
|
308
308
|
* skips the screen entirely instead of asking a question with one possible
|
|
309
|
-
* answer.
|
|
309
|
+
* answer. `vendors` narrows it further, by the `brand` a peer announces —
|
|
310
|
+
* use it where the device type cannot separate the candidates (two EEBUS
|
|
311
|
+
* heat pumps in one house), or where the guide is written for one
|
|
312
|
+
* manufacturer and must not offer a competitor's device. The two filters are
|
|
313
|
+
* conjunctive: a peer must satisfy both to be offered.
|
|
310
314
|
*
|
|
311
315
|
* The picker is drawn from what mDNS discovery found, so the guide must have
|
|
312
316
|
* scanned — keep {@link EnyoOnboardingV2Guide.requiresNetworkScan} at its
|
|
@@ -327,8 +331,9 @@ exports.onboardingV2Block = {
|
|
|
327
331
|
* paired peer into appliances.
|
|
328
332
|
*
|
|
329
333
|
* @param id - Stable block id, unique within the guide.
|
|
330
|
-
* @param options - Screen wording, optional `deviceTypes`
|
|
331
|
-
* behaviour, and the `paired` / `not-found` / `failure`
|
|
334
|
+
* @param options - Screen wording, optional `deviceTypes` and `vendors`
|
|
335
|
+
* filters, skip behaviour, and the `paired` / `not-found` / `failure`
|
|
336
|
+
* routing handles.
|
|
332
337
|
* @returns The EEBUS device-select block.
|
|
333
338
|
*
|
|
334
339
|
* @example
|
|
@@ -336,6 +341,7 @@ exports.onboardingV2Block = {
|
|
|
336
341
|
* onboardingV2Block.eebusDeviceSelect('pair', {
|
|
337
342
|
* headline: t('Wärmepumpe auswählen', 'Select the heat pump'),
|
|
338
343
|
* deviceTypes: [EnyoEebusDeviceTypeEnum.HeatPumpAppliance],
|
|
344
|
+
* vendors: ['Vaillant'],
|
|
339
345
|
* outcomes: [
|
|
340
346
|
* {id: 'ok', value: EnyoOnboardingV2EebusPairOutcome.Paired, label: t('Gekoppelt', 'Paired')},
|
|
341
347
|
* {id: 'none', value: EnyoOnboardingV2EebusPairOutcome.NotFound, label: t('Nichts gefunden', 'Nothing found')},
|
|
@@ -254,7 +254,11 @@ export declare const onboardingV2Block: {
|
|
|
254
254
|
* Filter it. `deviceTypes` is what turns this from "here are the six EEBUS
|
|
255
255
|
* devices in the house" into "here is your heat pump", and with one match it
|
|
256
256
|
* skips the screen entirely instead of asking a question with one possible
|
|
257
|
-
* answer.
|
|
257
|
+
* answer. `vendors` narrows it further, by the `brand` a peer announces —
|
|
258
|
+
* use it where the device type cannot separate the candidates (two EEBUS
|
|
259
|
+
* heat pumps in one house), or where the guide is written for one
|
|
260
|
+
* manufacturer and must not offer a competitor's device. The two filters are
|
|
261
|
+
* conjunctive: a peer must satisfy both to be offered.
|
|
258
262
|
*
|
|
259
263
|
* The picker is drawn from what mDNS discovery found, so the guide must have
|
|
260
264
|
* scanned — keep {@link EnyoOnboardingV2Guide.requiresNetworkScan} at its
|
|
@@ -275,8 +279,9 @@ export declare const onboardingV2Block: {
|
|
|
275
279
|
* paired peer into appliances.
|
|
276
280
|
*
|
|
277
281
|
* @param id - Stable block id, unique within the guide.
|
|
278
|
-
* @param options - Screen wording, optional `deviceTypes`
|
|
279
|
-
* behaviour, and the `paired` / `not-found` / `failure`
|
|
282
|
+
* @param options - Screen wording, optional `deviceTypes` and `vendors`
|
|
283
|
+
* filters, skip behaviour, and the `paired` / `not-found` / `failure`
|
|
284
|
+
* routing handles.
|
|
280
285
|
* @returns The EEBUS device-select block.
|
|
281
286
|
*
|
|
282
287
|
* @example
|
|
@@ -284,6 +289,7 @@ export declare const onboardingV2Block: {
|
|
|
284
289
|
* onboardingV2Block.eebusDeviceSelect('pair', {
|
|
285
290
|
* headline: t('Wärmepumpe auswählen', 'Select the heat pump'),
|
|
286
291
|
* deviceTypes: [EnyoEebusDeviceTypeEnum.HeatPumpAppliance],
|
|
292
|
+
* vendors: ['Vaillant'],
|
|
287
293
|
* outcomes: [
|
|
288
294
|
* {id: 'ok', value: EnyoOnboardingV2EebusPairOutcome.Paired, label: t('Gekoppelt', 'Paired')},
|
|
289
295
|
* {id: 'none', value: EnyoOnboardingV2EebusPairOutcome.NotFound, label: t('Nichts gefunden', 'Nothing found')},
|
|
@@ -614,9 +614,9 @@ function isPickerBlock(block) {
|
|
|
614
614
|
* it would either be skipped along with it or offer a way past the pick. Both
|
|
615
615
|
* are errors rather than warnings, because there is no reading of the step
|
|
616
616
|
* that behaves sensibly.
|
|
617
|
-
* - **An empty filter is not a filter.** `detectedAt: []` / `deviceTypes: []`
|
|
618
|
-
* match nothing, so the picker can only ever reach its
|
|
619
|
-
* Omitting the property is how "no filter" is expressed.
|
|
617
|
+
* - **An empty filter is not a filter.** `detectedAt: []` / `deviceTypes: []` /
|
|
618
|
+
* `vendors: []` match nothing, so the picker can only ever reach its
|
|
619
|
+
* `not-found` branch. Omitting the property is how "no filter" is expressed.
|
|
620
620
|
* - **A picker that renders should say something.** With neither a headline of
|
|
621
621
|
* its own nor a step title, the installer gets a bare list — a warning, since
|
|
622
622
|
* the host has a default caption.
|
|
@@ -655,6 +655,10 @@ function validatePickerBlocks(step, at, errors, warnings) {
|
|
|
655
655
|
errors.push(`${at}: ${label(block)} has an empty \`deviceTypes\` filter, which matches no peer — ` +
|
|
656
656
|
'omit the property to offer every discovered peer.');
|
|
657
657
|
}
|
|
658
|
+
if (block.vendors && block.vendors.length === 0) {
|
|
659
|
+
errors.push(`${at}: ${label(block)} has an empty \`vendors\` filter, which matches no peer — ` +
|
|
660
|
+
'omit the property to offer peers of every vendor.');
|
|
661
|
+
}
|
|
658
662
|
}
|
|
659
663
|
if (!block.headline?.length && !step.title?.length) {
|
|
660
664
|
warnings.push(`${at}: ${label(block)} has no headline and sits on a step with no title — ` +
|
|
@@ -176,6 +176,51 @@ class IntegrationEnergyApp extends energy_app_js_1.EnergyApp {
|
|
|
176
176
|
};
|
|
177
177
|
this.useDataBus().sendMessage([msg]);
|
|
178
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Publishes an `ApplianceFlexibilityAnnouncementV2` — the power-based
|
|
181
|
+
* flexibility announcement: a draw the appliance offers inside a trigger
|
|
182
|
+
* window, with no fixed energy attached.
|
|
183
|
+
*
|
|
184
|
+
* Use this when the appliance can absorb power but owes no particular
|
|
185
|
+
* amount of energy — a heat pump that will take surplus into its tank, an
|
|
186
|
+
* air conditioner that can pre-cool. When the appliance instead owes a
|
|
187
|
+
* known `kWh` by a deadline, send an `ApplianceFlexibilityAnnouncementV1`
|
|
188
|
+
* rather than this; see
|
|
189
|
+
* {@link EnyoDataBusApplianceFlexibilityAnnouncementV2} for the full
|
|
190
|
+
* distinction.
|
|
191
|
+
*
|
|
192
|
+
* Publish again whenever the offer changes — the announcement describes the
|
|
193
|
+
* appliance right now, and a consumer keeps the last one it saw.
|
|
194
|
+
*
|
|
195
|
+
* @param applianceId - The appliance making the offer.
|
|
196
|
+
* @param flexibility - The power band, the window it may be triggered in,
|
|
197
|
+
* optionally how long it may then run, and what the power is for. See
|
|
198
|
+
* {@link EnyoDataBusApplianceFlexibilityAnnouncementV2.data.flexibility}.
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```typescript
|
|
202
|
+
* this.publishFlexibilityAnnouncement('heatpump-1', {
|
|
203
|
+
* power: {minWatt: 800, maxWatt: 2300, stepWatt: 100},
|
|
204
|
+
* availableUntilIsoTimestamp: '2025-10-01T14:00:00Z',
|
|
205
|
+
* durationMinutes: 90,
|
|
206
|
+
* targets: [
|
|
207
|
+
* {target: EnyoFlexibilityTargetEnum.DomesticHotWater, powerW: 1500},
|
|
208
|
+
* ],
|
|
209
|
+
* });
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
publishFlexibilityAnnouncement(applianceId, flexibility) {
|
|
213
|
+
const msg = {
|
|
214
|
+
id: this.generateMessageId(),
|
|
215
|
+
type: 'message',
|
|
216
|
+
message: enyo_data_bus_value_js_1.EnyoDataBusMessageEnum.ApplianceFlexibilityAnnouncementV2,
|
|
217
|
+
source: this.source,
|
|
218
|
+
applianceId,
|
|
219
|
+
timestampIso: new Date().toISOString(),
|
|
220
|
+
data: { flexibility }
|
|
221
|
+
};
|
|
222
|
+
this.useDataBus().sendMessage([msg]);
|
|
223
|
+
}
|
|
179
224
|
/**
|
|
180
225
|
* Resolves the list of appliance IDs this integration is responsible for.
|
|
181
226
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EnergyApp } from "../energy-app.cjs";
|
|
2
|
-
import { EnyoDataBusGridOperatorPowerLimitationExecutedV1, EnyoDataBusGridOperatorPowerLimitationV1, EnyoDataBusMessage, EnyoDataBusMessageEnum } from "../types/enyo-data-bus-value.cjs";
|
|
2
|
+
import { EnyoDataBusApplianceFlexibilityAnnouncementV2, EnyoDataBusGridOperatorPowerLimitationExecutedV1, EnyoDataBusGridOperatorPowerLimitationV1, EnyoDataBusMessage, EnyoDataBusMessageEnum } from "../types/enyo-data-bus-value.cjs";
|
|
3
3
|
import { EnyoApplianceTypeEnum } from "../types/enyo-appliance.cjs";
|
|
4
4
|
import { EnyoSourceEnum } from "../types/enyo-source.enum.cjs";
|
|
5
5
|
import { DataBusCommandHandler } from "../implementations/data-bus/data-bus-command-handler.cjs";
|
|
@@ -132,6 +132,40 @@ export declare abstract class IntegrationEnergyApp extends EnergyApp {
|
|
|
132
132
|
* (seconds), and optional command correlation id / reason.
|
|
133
133
|
*/
|
|
134
134
|
publishGridOperatorPowerLimitationExecuted(applianceId: string, data: EnyoDataBusGridOperatorPowerLimitationExecutedV1['data']): void;
|
|
135
|
+
/**
|
|
136
|
+
* Publishes an `ApplianceFlexibilityAnnouncementV2` — the power-based
|
|
137
|
+
* flexibility announcement: a draw the appliance offers inside a trigger
|
|
138
|
+
* window, with no fixed energy attached.
|
|
139
|
+
*
|
|
140
|
+
* Use this when the appliance can absorb power but owes no particular
|
|
141
|
+
* amount of energy — a heat pump that will take surplus into its tank, an
|
|
142
|
+
* air conditioner that can pre-cool. When the appliance instead owes a
|
|
143
|
+
* known `kWh` by a deadline, send an `ApplianceFlexibilityAnnouncementV1`
|
|
144
|
+
* rather than this; see
|
|
145
|
+
* {@link EnyoDataBusApplianceFlexibilityAnnouncementV2} for the full
|
|
146
|
+
* distinction.
|
|
147
|
+
*
|
|
148
|
+
* Publish again whenever the offer changes — the announcement describes the
|
|
149
|
+
* appliance right now, and a consumer keeps the last one it saw.
|
|
150
|
+
*
|
|
151
|
+
* @param applianceId - The appliance making the offer.
|
|
152
|
+
* @param flexibility - The power band, the window it may be triggered in,
|
|
153
|
+
* optionally how long it may then run, and what the power is for. See
|
|
154
|
+
* {@link EnyoDataBusApplianceFlexibilityAnnouncementV2.data.flexibility}.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* this.publishFlexibilityAnnouncement('heatpump-1', {
|
|
159
|
+
* power: {minWatt: 800, maxWatt: 2300, stepWatt: 100},
|
|
160
|
+
* availableUntilIsoTimestamp: '2025-10-01T14:00:00Z',
|
|
161
|
+
* durationMinutes: 90,
|
|
162
|
+
* targets: [
|
|
163
|
+
* {target: EnyoFlexibilityTargetEnum.DomesticHotWater, powerW: 1500},
|
|
164
|
+
* ],
|
|
165
|
+
* });
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
publishFlexibilityAnnouncement(applianceId: string, flexibility: EnyoDataBusApplianceFlexibilityAnnouncementV2['data']['flexibility']): void;
|
|
135
169
|
/**
|
|
136
170
|
* Resolves the list of appliance IDs this integration is responsible for.
|
|
137
171
|
*
|
|
@@ -4,7 +4,8 @@ import { EnyoGridConnectionPoint } from "../types/enyo-grid-connection-point.cjs
|
|
|
4
4
|
*
|
|
5
5
|
* The grid connection point describes the physical interface between the
|
|
6
6
|
* local electrical installation and the public grid, including the main
|
|
7
|
-
* fuse rating, the number of phases,
|
|
7
|
+
* fuse rating, the number of phases, the maximum allowed grid power, and the
|
|
8
|
+
* total power that load balancing may allocate to EV chargers.
|
|
8
9
|
* Energy apps consume this information to size grid-import/export budgets,
|
|
9
10
|
* enforce per-phase current limits, and respect contractual or regulatory
|
|
10
11
|
* power caps.
|
|
@@ -21,12 +22,16 @@ export interface EnergyAppGridConnectionPoint {
|
|
|
21
22
|
*
|
|
22
23
|
* @example
|
|
23
24
|
* ```typescript
|
|
25
|
+
* import {DEFAULT_CHARGER_LIMIT_W} from "@enyo-energy/energy-app-sdk";
|
|
26
|
+
*
|
|
24
27
|
* const gridConnectionPoint = energyApp.useGridConnectionPoint();
|
|
25
28
|
* const details = await gridConnectionPoint.getGridConnectionPoint();
|
|
26
29
|
* if (details) {
|
|
27
30
|
* console.log(`Fuse: ${details.fuseAmpere} A`);
|
|
28
31
|
* console.log(`Phases: ${details.numberOfPhases}`);
|
|
29
32
|
* console.log(`Power limit: ${details.powerLimitW} W`);
|
|
33
|
+
* const chargerLimitW = details.chargerLimitW ?? DEFAULT_CHARGER_LIMIT_W;
|
|
34
|
+
* console.log(`Charger limit: ${chargerLimitW} W`);
|
|
30
35
|
* }
|
|
31
36
|
* ```
|
|
32
37
|
*/
|
|
@@ -69,4 +69,10 @@ var EnyoChargerApplianceAvailableFeaturesEnum;
|
|
|
69
69
|
EnyoChargerApplianceAvailableFeaturesEnum["PvSurplusMode"] = "PvSurplusMode";
|
|
70
70
|
/** If the charger supports switching between three-phase and one-phase charging */
|
|
71
71
|
EnyoChargerApplianceAvailableFeaturesEnum["ThreeToOnePhaseSwitch"] = "ThreeToOnePhaseSwitch";
|
|
72
|
+
/**
|
|
73
|
+
* If the charger requires the vehicle to be disconnected before a new charge can be started.
|
|
74
|
+
* Once the charger is in {@link EnyoChargerApplianceStatusEnum.Finishing}, no new charge can be
|
|
75
|
+
* started remotely; the customer has to unplug the vehicle and plug it in again.
|
|
76
|
+
*/
|
|
77
|
+
EnyoChargerApplianceAvailableFeaturesEnum["DisconnectToRestartCharge"] = "DisconnectToRestartCharge";
|
|
72
78
|
})(EnyoChargerApplianceAvailableFeaturesEnum || (exports.EnyoChargerApplianceAvailableFeaturesEnum = EnyoChargerApplianceAvailableFeaturesEnum = {}));
|
|
@@ -82,7 +82,13 @@ export declare enum EnyoChargerApplianceAvailableFeaturesEnum {
|
|
|
82
82
|
/** If the Charger supprots a pv surplus mode */
|
|
83
83
|
PvSurplusMode = "PvSurplusMode",
|
|
84
84
|
/** If the charger supports switching between three-phase and one-phase charging */
|
|
85
|
-
ThreeToOnePhaseSwitch = "ThreeToOnePhaseSwitch"
|
|
85
|
+
ThreeToOnePhaseSwitch = "ThreeToOnePhaseSwitch",
|
|
86
|
+
/**
|
|
87
|
+
* If the charger requires the vehicle to be disconnected before a new charge can be started.
|
|
88
|
+
* Once the charger is in {@link EnyoChargerApplianceStatusEnum.Finishing}, no new charge can be
|
|
89
|
+
* started remotely; the customer has to unplug the vehicle and plug it in again.
|
|
90
|
+
*/
|
|
91
|
+
DisconnectToRestartCharge = "DisconnectToRestartCharge"
|
|
86
92
|
}
|
|
87
93
|
/**
|
|
88
94
|
* Phase configurations a charger can operate in.
|
|
@@ -425,6 +425,8 @@ var EnyoDataBusMessageEnum;
|
|
|
425
425
|
EnyoDataBusMessageEnum["MeterValuesUpdateV1"] = "MeterValuesUpdateV1";
|
|
426
426
|
EnyoDataBusMessageEnum["BatteryValuesUpdateV1"] = "BatteryValuesUpdateV1";
|
|
427
427
|
EnyoDataBusMessageEnum["ApplianceFlexibilityAnnouncementV1"] = "ApplianceFlexibilityAnnouncementV1";
|
|
428
|
+
/** Power-based flexibility: a draw the appliance offers inside a trigger window, with no fixed energy. */
|
|
429
|
+
EnyoDataBusMessageEnum["ApplianceFlexibilityAnnouncementV2"] = "ApplianceFlexibilityAnnouncementV2";
|
|
428
430
|
EnyoDataBusMessageEnum["ApplianceStateUpdateV1"] = "ApplianceStateUpdateV1";
|
|
429
431
|
EnyoDataBusMessageEnum["HeatpumpValuesUpdateV1"] = "HeatpumpValuesUpdateV1";
|
|
430
432
|
EnyoDataBusMessageEnum["HeatingRodValuesUpdateV1"] = "HeatingRodValuesUpdateV1";
|
|
@@ -9,7 +9,7 @@ import type { EnyoCalibrationRequestOriginEnum, EnyoCalibrationRun } from "./eny
|
|
|
9
9
|
import { EnyoEnergyPrices } from "./enyo-energy-prices.cjs";
|
|
10
10
|
import { EnyoCurrencyEnum } from "./enyo-currency.cjs";
|
|
11
11
|
import { EnyoHeatpumpApplianceModeEnum } from "./enyo-heatpump-appliance.cjs";
|
|
12
|
-
import type { EnyoFlexibilityTargetEnum, EnyoFlexibilityTargetPower } from "./enyo-flexibility-announcement.cjs";
|
|
12
|
+
import type { EnyoFlexibilityHeatpumpTargetTypeEnum, EnyoFlexibilityPowerBand, EnyoFlexibilityProgress, EnyoFlexibilityTargetEnum, EnyoFlexibilityTargetPower } from "./enyo-flexibility-announcement.cjs";
|
|
13
13
|
import { EnyoSmartPlugApplianceStateEnum } from "./enyo-smart-plug-appliance.cjs";
|
|
14
14
|
import { EnyoAirConditioningApplianceModeEnum, EnyoAirConditioningOptimizationModeEnum } from "./enyo-air-conditioning-appliance.cjs";
|
|
15
15
|
import { EnergyAppPackageCategory } from "../energy-app-package-definition.cjs";
|
|
@@ -696,6 +696,8 @@ export declare enum EnyoDataBusMessageEnum {
|
|
|
696
696
|
MeterValuesUpdateV1 = "MeterValuesUpdateV1",
|
|
697
697
|
BatteryValuesUpdateV1 = "BatteryValuesUpdateV1",
|
|
698
698
|
ApplianceFlexibilityAnnouncementV1 = "ApplianceFlexibilityAnnouncementV1",
|
|
699
|
+
/** Power-based flexibility: a draw the appliance offers inside a trigger window, with no fixed energy. */
|
|
700
|
+
ApplianceFlexibilityAnnouncementV2 = "ApplianceFlexibilityAnnouncementV2",
|
|
699
701
|
ApplianceStateUpdateV1 = "ApplianceStateUpdateV1",
|
|
700
702
|
HeatpumpValuesUpdateV1 = "HeatpumpValuesUpdateV1",
|
|
701
703
|
HeatingRodValuesUpdateV1 = "HeatingRodValuesUpdateV1",
|
|
@@ -1073,6 +1075,149 @@ export interface EnyoDataBusApplianceFlexibilityAnnouncementV1 extends EnyoDataB
|
|
|
1073
1075
|
};
|
|
1074
1076
|
};
|
|
1075
1077
|
}
|
|
1078
|
+
/**
|
|
1079
|
+
* An appliance announces a *power* it can absorb inside a window, with no fixed
|
|
1080
|
+
* energy attached.
|
|
1081
|
+
*
|
|
1082
|
+
* The power-based counterpart to
|
|
1083
|
+
* {@link EnyoDataBusApplianceFlexibilityAnnouncementV1}. V1 answers "how much
|
|
1084
|
+
* energy do I owe, and by when" — the right shape for a charging session with a
|
|
1085
|
+
* target. This one answers "how much can I draw, when may you start me, and how
|
|
1086
|
+
* long may I run" — the right shape for a heat pump that can take surplus into a
|
|
1087
|
+
* tank without ever owing a particular number of kWh.
|
|
1088
|
+
*
|
|
1089
|
+
* Which to send is decided by the demand, not by preference:
|
|
1090
|
+
*
|
|
1091
|
+
* - **Energy is fixed, timing is not** → V1. The appliance owes `kWh` by a
|
|
1092
|
+
* deadline and the decision maker schedules it.
|
|
1093
|
+
* - **Power is offered, energy falls out of it** → V2. There is no amount the
|
|
1094
|
+
* appliance is owed; running it longer simply uses more.
|
|
1095
|
+
*
|
|
1096
|
+
* Deliberately no `kWh` field: an energy figure here would be read as
|
|
1097
|
+
* authoritative the moment it exists, and the announcement would collapse back
|
|
1098
|
+
* into V1 with extra fields. An appliance that knows its energy should send V1.
|
|
1099
|
+
*
|
|
1100
|
+
* **The window is a trigger window, not a run window.**
|
|
1101
|
+
* {@link data.flexibility.availableFromIsoTimestamp} and
|
|
1102
|
+
* {@link data.flexibility.availableUntilIsoTimestamp} bound when the run may be
|
|
1103
|
+
* *started*; {@link data.flexibility.durationMinutes} says how long it then
|
|
1104
|
+
* runs, and a run started at the end of the window may finish well past it.
|
|
1105
|
+
*
|
|
1106
|
+
* @example
|
|
1107
|
+
* ```typescript
|
|
1108
|
+
* dataBus.sendMessage([{
|
|
1109
|
+
* type: 'message',
|
|
1110
|
+
* message: EnyoDataBusMessageEnum.ApplianceFlexibilityAnnouncementV2,
|
|
1111
|
+
* applianceId: 'heatpump-1',
|
|
1112
|
+
* data: {
|
|
1113
|
+
* flexibility: {
|
|
1114
|
+
* // Modulating compressor: 800 W to 2300 W in 100 W steps.
|
|
1115
|
+
* power: {minWatt: 800, maxWatt: 2300, stepWatt: 100},
|
|
1116
|
+
* // May be started any time this morning ...
|
|
1117
|
+
* availableFromIsoTimestamp: '2025-10-01T10:00:00Z',
|
|
1118
|
+
* availableUntilIsoTimestamp: '2025-10-01T14:00:00Z',
|
|
1119
|
+
* // ... and then runs for up to 90 minutes, 20 at the very least.
|
|
1120
|
+
* durationMinutes: 90,
|
|
1121
|
+
* minDurationMinutes: 20,
|
|
1122
|
+
* // What the power would go into.
|
|
1123
|
+
* targets: [
|
|
1124
|
+
* {target: EnyoFlexibilityTargetEnum.DomesticHotWater, powerW: 1500},
|
|
1125
|
+
* {target: EnyoFlexibilityTargetEnum.BufferTank, powerW: 800},
|
|
1126
|
+
* ],
|
|
1127
|
+
* },
|
|
1128
|
+
* },
|
|
1129
|
+
* }]);
|
|
1130
|
+
* ```
|
|
1131
|
+
*/
|
|
1132
|
+
export interface EnyoDataBusApplianceFlexibilityAnnouncementV2 extends EnyoDataBusMessage {
|
|
1133
|
+
type: 'message';
|
|
1134
|
+
message: EnyoDataBusMessageEnum.ApplianceFlexibilityAnnouncementV2;
|
|
1135
|
+
/** ID of the appliance */
|
|
1136
|
+
applianceId: string;
|
|
1137
|
+
data: {
|
|
1138
|
+
flexibility: {
|
|
1139
|
+
/**
|
|
1140
|
+
* Power envelope the appliance offers, in Watts — `minWatt`,
|
|
1141
|
+
* `maxWatt` and the `stepWatt` granularity between them.
|
|
1142
|
+
*
|
|
1143
|
+
* A band rather than a single figure because a modulating appliance
|
|
1144
|
+
* is placed, not switched: a decision maker with surplus to spend
|
|
1145
|
+
* needs to know it may run the compressor at 1200 W rather than
|
|
1146
|
+
* choosing between 2300 W and nothing. A fixed-power appliance
|
|
1147
|
+
* states the same value for both bounds and a `stepWatt` equal to
|
|
1148
|
+
* the band's width.
|
|
1149
|
+
*/
|
|
1150
|
+
power: EnyoFlexibilityPowerBand;
|
|
1151
|
+
/**
|
|
1152
|
+
* Earliest the run may be triggered, ISO 8601. Omitted means it may
|
|
1153
|
+
* be triggered immediately.
|
|
1154
|
+
*/
|
|
1155
|
+
availableFromIsoTimestamp?: string;
|
|
1156
|
+
/**
|
|
1157
|
+
* Latest the run may be triggered, ISO 8601.
|
|
1158
|
+
*
|
|
1159
|
+
* A trigger deadline, not a completion deadline — a run started one
|
|
1160
|
+
* minute before this may still be drawing power long afterwards.
|
|
1161
|
+
* See {@link durationMinutes} for how long.
|
|
1162
|
+
*/
|
|
1163
|
+
availableUntilIsoTimestamp: string;
|
|
1164
|
+
/**
|
|
1165
|
+
* How long the run may last once triggered, in minutes.
|
|
1166
|
+
*
|
|
1167
|
+
* Omitted means the appliance sets no limit of its own and the
|
|
1168
|
+
* decision maker may run it for as long as the window and its own
|
|
1169
|
+
* budget allow — the appliance is expected to stop itself when the
|
|
1170
|
+
* tank, the room or the battery is satisfied.
|
|
1171
|
+
*/
|
|
1172
|
+
durationMinutes?: number;
|
|
1173
|
+
/**
|
|
1174
|
+
* Shortest contiguous run still worth starting, in minutes.
|
|
1175
|
+
*
|
|
1176
|
+
* Below this the run costs more than it returns — a compressor that
|
|
1177
|
+
* spends its first ten minutes getting up to temperature gains
|
|
1178
|
+
* nothing from a five-minute slot, and a decision maker filling a
|
|
1179
|
+
* short gap should leave it alone rather than cycle it.
|
|
1180
|
+
*/
|
|
1181
|
+
minDurationMinutes?: number;
|
|
1182
|
+
/**
|
|
1183
|
+
* What the offered power would go into, and how much of it each
|
|
1184
|
+
* target would draw — e.g. a heat pump splitting between the
|
|
1185
|
+
* domestic hot water tank and the heating buffer tank.
|
|
1186
|
+
*
|
|
1187
|
+
* Required here, unlike on
|
|
1188
|
+
* {@link EnyoDataBusApplianceFlexibilityAnnouncementV1} where it is
|
|
1189
|
+
* optional context beside an authoritative `kWh`: this message has
|
|
1190
|
+
* no energy figure, so the targets are the substance of the
|
|
1191
|
+
* announcement rather than a decoration on it. A given target
|
|
1192
|
+
* SHOULD appear at most once, and the entries' `powerW` SHOULD sit
|
|
1193
|
+
* inside {@link power}.
|
|
1194
|
+
*/
|
|
1195
|
+
targets: EnyoFlexibilityTargetPower[];
|
|
1196
|
+
/**
|
|
1197
|
+
* Optional extra context for the consumer of this announcement.
|
|
1198
|
+
* Nested so further context keys can be added without changing the
|
|
1199
|
+
* message shape again.
|
|
1200
|
+
*/
|
|
1201
|
+
context?: {
|
|
1202
|
+
/**
|
|
1203
|
+
* For heat pumps: what the flexibility is aimed at. Narrower
|
|
1204
|
+
* than {@link targets}, and shared with the category-level
|
|
1205
|
+
* announcement so both surfaces speak one vocabulary.
|
|
1206
|
+
*/
|
|
1207
|
+
heatpumpTargetType?: EnyoFlexibilityHeatpumpTargetTypeEnum;
|
|
1208
|
+
/**
|
|
1209
|
+
* What the run is driving toward and where it stands now — a
|
|
1210
|
+
* tank at 38 °C heading for 50 °C.
|
|
1211
|
+
*
|
|
1212
|
+
* Worth setting precisely because this message carries no
|
|
1213
|
+
* energy figure: without it a consumer cannot tell a run that
|
|
1214
|
+
* has nearly finished from one that has barely started.
|
|
1215
|
+
*/
|
|
1216
|
+
progress?: EnyoFlexibilityProgress;
|
|
1217
|
+
};
|
|
1218
|
+
};
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1076
1221
|
/**
|
|
1077
1222
|
* Message sent when an appliance's connectivity state and/or health status
|
|
1078
1223
|
* changes. At least one of `state` or `status` should be set; both may be
|
|
@@ -3213,7 +3358,7 @@ export interface EnyoDataBusVehicleSocUpdateV1 extends EnyoDataBusMessage {
|
|
|
3213
3358
|
* energyApp.useDataBus().sendMessage([{
|
|
3214
3359
|
* type: 'message',
|
|
3215
3360
|
* message: 'RequestVehicleSocEstimateV1',
|
|
3216
|
-
* data: {requestId, vehicleId, maxAgeMs: 15 * 60 * 1000},
|
|
3361
|
+
* data: {requestId, vehicleId, maxAgeMs: 15 * 60 * 1000, targetSocPercent: 80},
|
|
3217
3362
|
* }]);
|
|
3218
3363
|
* ```
|
|
3219
3364
|
*/
|
|
@@ -3244,6 +3389,20 @@ export interface EnyoDataBusRequestVehicleSocEstimateV1 extends EnyoDataBusMessa
|
|
|
3244
3389
|
* values — find the right one without guessing.
|
|
3245
3390
|
*/
|
|
3246
3391
|
applianceId?: string;
|
|
3392
|
+
/**
|
|
3393
|
+
* State of charge the caller is planning towards, in percent (0-100) —
|
|
3394
|
+
* the session's target as in
|
|
3395
|
+
* {@link EnyoDataBusStartChargeV1.data.targetSocPercent}, not
|
|
3396
|
+
* a limit on the answer.
|
|
3397
|
+
*
|
|
3398
|
+
* Told to the responder because what the estimate is *for* changes how
|
|
3399
|
+
* much trouble is worth taking to get it: a stored reading already at
|
|
3400
|
+
* or above the target answers the question without waking the car,
|
|
3401
|
+
* while one far below it justifies a fresh fetch. Omitted means the
|
|
3402
|
+
* responder decides on its own; the reading returned is the same
|
|
3403
|
+
* either way.
|
|
3404
|
+
*/
|
|
3405
|
+
targetSocPercent?: number;
|
|
3247
3406
|
};
|
|
3248
3407
|
}
|
|
3249
3408
|
/**
|
|
@@ -80,6 +80,19 @@ export interface EebusDiscoveredDevice {
|
|
|
80
80
|
ski: string;
|
|
81
81
|
/** Human-readable device name advertised during discovery */
|
|
82
82
|
deviceName?: string;
|
|
83
|
+
/**
|
|
84
|
+
* The vendor the peer announced in its SHIP record (the `brand` TXT key),
|
|
85
|
+
* verbatim and untranslated — e.g. `Vaillant`, `KEBA`, `Viessmann`.
|
|
86
|
+
*
|
|
87
|
+
* The peer's own claim, made before anything is paired, which is what makes
|
|
88
|
+
* it usable as a discovery filter next to {@link deviceType}: see
|
|
89
|
+
* {@link EnyoOnboardingV2EebusDeviceSelectBlock.vendors}. Spelling and case
|
|
90
|
+
* are whatever the firmware ships, so compare case-insensitively rather
|
|
91
|
+
* than with `===`.
|
|
92
|
+
*
|
|
93
|
+
* Absent when the peer advertises no `brand`.
|
|
94
|
+
*/
|
|
95
|
+
brand?: string;
|
|
83
96
|
/** IP address or hostname of the device */
|
|
84
97
|
host: string;
|
|
85
98
|
/** Port number for the SHIP connection */
|
|
@@ -180,6 +180,15 @@ export interface EnyoTariffPriceEntry {
|
|
|
180
180
|
timestampIso: string;
|
|
181
181
|
/** Price per kWh for this interval, in the tariff's currency. */
|
|
182
182
|
pricePerKwh: number;
|
|
183
|
+
/**
|
|
184
|
+
* Optional gross grid fee per kWh contained in {@link pricePerKwh}, in the
|
|
185
|
+
* tariff's currency (not cent).
|
|
186
|
+
*
|
|
187
|
+
* Informational only: it breaks down the price, it is **never added** to it.
|
|
188
|
+
* {@link pricePerKwh} is always the total price. Only meaningful when the
|
|
189
|
+
* series declares {@link EnyoPriceComponentEnum.GridFee} in its `includes`.
|
|
190
|
+
*/
|
|
191
|
+
gridFeeGrossPerKwh?: number;
|
|
183
192
|
}
|
|
184
193
|
/**
|
|
185
194
|
* Prices for one direction over a requested range.
|
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CHARGER_LIMIT_W = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Default total charger power limit, in watts (W), applied by load balancing
|
|
6
|
+
* when {@link EnyoGridConnectionPoint.chargerLimitW} is not configured.
|
|
7
|
+
*
|
|
8
|
+
* 11 kW corresponds to the common three-phase 16 A wallbox rating.
|
|
9
|
+
*/
|
|
10
|
+
exports.DEFAULT_CHARGER_LIMIT_W = 11000;
|