@enyo-energy/energy-app-sdk 1.2.0 → 1.3.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 +211 -1
- package/dist/cjs/energy-app-package-definition.cjs +1 -0
- package/dist/cjs/energy-app-package-definition.d.cts +1 -0
- package/dist/cjs/energy-app-permission.type.cjs +2 -0
- package/dist/cjs/energy-app-permission.type.d.cts +3 -1
- package/dist/cjs/energy-app.cjs +16 -0
- package/dist/cjs/energy-app.d.cts +15 -0
- package/dist/cjs/enyo-energy-app-sdk.d.cts +3 -0
- package/dist/cjs/implementations/pricing/compose-electricity-prices.cjs +218 -0
- package/dist/cjs/implementations/pricing/compose-electricity-prices.d.cts +100 -0
- package/dist/cjs/implementations/pricing/price-component-validators.cjs +295 -0
- package/dist/cjs/implementations/pricing/price-component-validators.d.cts +90 -0
- package/dist/cjs/implementations/pricing/price-schedule-resolver.cjs +182 -0
- package/dist/cjs/implementations/pricing/price-schedule-resolver.d.cts +95 -0
- package/dist/cjs/index.cjs +7 -0
- package/dist/cjs/index.d.cts +7 -0
- package/dist/cjs/packages/energy-app-electricity-tariff.d.cts +34 -1
- package/dist/cjs/packages/energy-app-grid-fee.cjs +2 -0
- package/dist/cjs/packages/energy-app-grid-fee.d.cts +181 -0
- package/dist/cjs/types/enyo-electricity-tariff.cjs +33 -1
- package/dist/cjs/types/enyo-electricity-tariff.d.cts +161 -4
- package/dist/cjs/types/enyo-grid-fee.cjs +15 -0
- package/dist/cjs/types/enyo-grid-fee.d.cts +129 -0
- package/dist/cjs/types/enyo-price-composition.cjs +15 -0
- package/dist/cjs/types/enyo-price-composition.d.cts +126 -0
- package/dist/cjs/types/enyo-price-schedule.cjs +45 -0
- package/dist/cjs/types/enyo-price-schedule.d.cts +137 -0
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/energy-app-package-definition.d.ts +1 -0
- package/dist/energy-app-package-definition.js +1 -0
- package/dist/energy-app-permission.type.d.ts +3 -1
- package/dist/energy-app-permission.type.js +2 -0
- package/dist/energy-app.d.ts +15 -0
- package/dist/energy-app.js +16 -0
- package/dist/enyo-energy-app-sdk.d.ts +3 -0
- package/dist/implementations/pricing/compose-electricity-prices.d.ts +100 -0
- package/dist/implementations/pricing/compose-electricity-prices.js +212 -0
- package/dist/implementations/pricing/price-component-validators.d.ts +90 -0
- package/dist/implementations/pricing/price-component-validators.js +285 -0
- package/dist/implementations/pricing/price-schedule-resolver.d.ts +95 -0
- package/dist/implementations/pricing/price-schedule-resolver.js +175 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/packages/energy-app-electricity-tariff.d.ts +34 -1
- package/dist/packages/energy-app-grid-fee.d.ts +181 -0
- package/dist/packages/energy-app-grid-fee.js +1 -0
- package/dist/types/enyo-electricity-tariff.d.ts +161 -4
- package/dist/types/enyo-electricity-tariff.js +32 -0
- package/dist/types/enyo-grid-fee.d.ts +129 -0
- package/dist/types/enyo-grid-fee.js +12 -0
- package/dist/types/enyo-price-composition.d.ts +126 -0
- package/dist/types/enyo-price-composition.js +12 -0
- package/dist/types/enyo-price-schedule.d.ts +137 -0
- package/dist/types/enyo-price-schedule.js +42 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { EnyoPriceSchedule, EnyoResolvedPriceEntry } from '../../types/enyo-price-schedule.cjs';
|
|
2
|
+
/**
|
|
3
|
+
* Length of one resolved interval, in minutes. Matches the resolution of
|
|
4
|
+
* `useElectricityPrices().getPrices()` so resolved schedules can be combined
|
|
5
|
+
* with a price series interval by interval.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PRICE_SCHEDULE_INTERVAL_MINUTES = 15;
|
|
8
|
+
/**
|
|
9
|
+
* Wall-clock calendar fields of an instant, as seen in a specific time zone.
|
|
10
|
+
*/
|
|
11
|
+
export interface ZonedDateParts {
|
|
12
|
+
/** Full year, e.g. `2026`. */
|
|
13
|
+
year: number;
|
|
14
|
+
/** Month, `1` = January … `12` = December. */
|
|
15
|
+
month: number;
|
|
16
|
+
/** Day of the month, starting at `1`. */
|
|
17
|
+
day: number;
|
|
18
|
+
/** Day of the week, `0` = Sunday … `6` = Saturday. */
|
|
19
|
+
weekday: number;
|
|
20
|
+
/** Hour in 24-hour notation, `0`–`23`. */
|
|
21
|
+
hour: number;
|
|
22
|
+
/** Minute, `0`–`59`. */
|
|
23
|
+
minute: number;
|
|
24
|
+
/** Minutes since local midnight (`hour * 60 + minute`). */
|
|
25
|
+
minutesOfDay: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Projects an instant onto the wall clock of a time zone.
|
|
29
|
+
*
|
|
30
|
+
* Uses `Intl.DateTimeFormat`, so daylight-saving transitions are handled by the
|
|
31
|
+
* platform's time zone database without pulling in a dependency.
|
|
32
|
+
*
|
|
33
|
+
* @param date - The instant to project
|
|
34
|
+
* @param timezone - IANA time zone identifier, e.g. `'Europe/Berlin'`
|
|
35
|
+
* @returns The wall-clock calendar fields of `date` in `timezone`
|
|
36
|
+
* @throws {RangeError} If `timezone` is not a valid IANA identifier
|
|
37
|
+
*/
|
|
38
|
+
export declare function getZonedDateParts(date: Date, timezone: string): ZonedDateParts;
|
|
39
|
+
/**
|
|
40
|
+
* Parses an `HH:mm` wall-clock time into minutes since midnight.
|
|
41
|
+
*
|
|
42
|
+
* @param value - Time in 24-hour `HH:mm` notation, e.g. `'22:00'`
|
|
43
|
+
* @returns Minutes since midnight, or `null` when the value is malformed
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseTimeOfDay(value: string): number | null;
|
|
46
|
+
/**
|
|
47
|
+
* Rounds an instant down to the start of its 15-minute interval.
|
|
48
|
+
*
|
|
49
|
+
* @param timestampMs - Epoch milliseconds
|
|
50
|
+
* @returns Epoch milliseconds of the interval start
|
|
51
|
+
*/
|
|
52
|
+
export declare function floorToInterval(timestampMs: number): number;
|
|
53
|
+
/**
|
|
54
|
+
* Options for {@link resolvePriceSchedule}.
|
|
55
|
+
*/
|
|
56
|
+
export interface ResolvePriceScheduleOptions {
|
|
57
|
+
/** Start of the range to resolve, in ISO format (inclusive). */
|
|
58
|
+
fromIso: string;
|
|
59
|
+
/** End of the range to resolve, in ISO format (exclusive). */
|
|
60
|
+
untilIso: string;
|
|
61
|
+
/** IANA time zone the schedule's wall-clock times are expressed in. */
|
|
62
|
+
timezone: string;
|
|
63
|
+
/** Optional start of the component's validity in ISO format (inclusive). */
|
|
64
|
+
validFromIso?: string;
|
|
65
|
+
/** Optional end of the component's validity in ISO format (exclusive). */
|
|
66
|
+
validUntilIso?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Expands a price schedule into a flat 15-minute series over a time range.
|
|
70
|
+
*
|
|
71
|
+
* The range start is rounded down to the enclosing 15-minute interval. Intervals
|
|
72
|
+
* no window covers resolve to `amountPerKwh: 0`; intervals outside the
|
|
73
|
+
* component's validity window are omitted entirely, so an empty result means
|
|
74
|
+
* "this component does not apply here" rather than "it is free here".
|
|
75
|
+
*
|
|
76
|
+
* Windows are evaluated in array order and the first match wins — schedules are
|
|
77
|
+
* expected to be overlap-free, which the validators enforce at registration
|
|
78
|
+
* time.
|
|
79
|
+
*
|
|
80
|
+
* @param schedule - The schedule to expand
|
|
81
|
+
* @param options - Range, time zone and optional validity bounds
|
|
82
|
+
* @returns Resolved entries sorted ascending by `timestampIso`
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const entries = resolvePriceSchedule(
|
|
87
|
+
* {
|
|
88
|
+
* type: EnyoPriceScheduleTypeEnum.Recurring,
|
|
89
|
+
* windows: [{ startTimeOfDay: '22:00', endTimeOfDay: '06:00', amountPerKwh: 0.05 }],
|
|
90
|
+
* },
|
|
91
|
+
* { fromIso: '2026-09-02T00:00:00Z', untilIso: '2026-09-03T00:00:00Z', timezone: 'Europe/Berlin' },
|
|
92
|
+
* );
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
export declare function resolvePriceSchedule(schedule: EnyoPriceSchedule, options: ResolvePriceScheduleOptions): EnyoResolvedPriceEntry[];
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -152,3 +152,10 @@ __exportStar(require("./packages/energy-app-epex-spot-price.cjs"), exports);
|
|
|
152
152
|
__exportStar(require("./types/enyo-automation.cjs"), exports);
|
|
153
153
|
__exportStar(require("./packages/energy-app-automation.cjs"), exports);
|
|
154
154
|
__exportStar(require("./implementations/automation/automation-validators.cjs"), exports);
|
|
155
|
+
__exportStar(require("./types/enyo-price-schedule.cjs"), exports);
|
|
156
|
+
__exportStar(require("./types/enyo-grid-fee.cjs"), exports);
|
|
157
|
+
__exportStar(require("./types/enyo-price-composition.cjs"), exports);
|
|
158
|
+
__exportStar(require("./packages/energy-app-grid-fee.cjs"), exports);
|
|
159
|
+
__exportStar(require("./implementations/pricing/price-schedule-resolver.cjs"), exports);
|
|
160
|
+
__exportStar(require("./implementations/pricing/price-component-validators.cjs"), exports);
|
|
161
|
+
__exportStar(require("./implementations/pricing/compose-electricity-prices.cjs"), exports);
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -136,3 +136,10 @@ export * from './packages/energy-app-epex-spot-price.cjs';
|
|
|
136
136
|
export * from './types/enyo-automation.cjs';
|
|
137
137
|
export * from './packages/energy-app-automation.cjs';
|
|
138
138
|
export * from './implementations/automation/automation-validators.cjs';
|
|
139
|
+
export * from './types/enyo-price-schedule.cjs';
|
|
140
|
+
export * from './types/enyo-grid-fee.cjs';
|
|
141
|
+
export * from './types/enyo-price-composition.cjs';
|
|
142
|
+
export * from './packages/energy-app-grid-fee.cjs';
|
|
143
|
+
export * from './implementations/pricing/price-schedule-resolver.cjs';
|
|
144
|
+
export * from './implementations/pricing/price-component-validators.cjs';
|
|
145
|
+
export * from './implementations/pricing/compose-electricity-prices.cjs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EnyoElectricityTariff, EnyoElectricityTariffWithDefault } from "../types/enyo-electricity-tariff.cjs";
|
|
1
|
+
import { EnyoElectricityTariff, EnyoElectricityTariffWithDefault, EnyoTariffChangeEvent } from "../types/enyo-electricity-tariff.cjs";
|
|
2
2
|
/**
|
|
3
3
|
* Interface for managing electricity tariffs.
|
|
4
4
|
* Provides methods to register, retrieve, and remove electricity tariffs
|
|
@@ -60,4 +60,37 @@ export interface EnergyAppElectricityTariff {
|
|
|
60
60
|
* @returns Promise that resolves to the full updated tariff with its default indicator
|
|
61
61
|
*/
|
|
62
62
|
updateTariff(id: string, attributes: Partial<Omit<EnyoElectricityTariff, 'id'>>): Promise<EnyoElectricityTariffWithDefault>;
|
|
63
|
+
/**
|
|
64
|
+
* Registers a listener invoked whenever any tariff is registered, updated
|
|
65
|
+
* or removed, or whenever a different tariff becomes the system default.
|
|
66
|
+
*
|
|
67
|
+
* Listeners see changes made by every energy app on the system, not just
|
|
68
|
+
* this one — filter on {@link EnyoTariffChangeEvent.tariffId} when only one
|
|
69
|
+
* tariff matters. This is the signal to recompose prices: a changed grid fee
|
|
70
|
+
* link, an added or expired bonus, or a new default tariff all invalidate a
|
|
71
|
+
* previously composed price series.
|
|
72
|
+
*
|
|
73
|
+
* Requires the `ElectricityTariff` permission.
|
|
74
|
+
*
|
|
75
|
+
* @param listener - Callback invoked with the tariff change event
|
|
76
|
+
* @returns A unique listener id that can be passed to {@link offTariffChanged}
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const listenerId = tariffs.onTariffChanged(async event => {
|
|
81
|
+
* if (event.changeType === EnyoTariffChangeTypeEnum.Removed) return;
|
|
82
|
+
* await recomposePrices(event.tariff);
|
|
83
|
+
* });
|
|
84
|
+
* // later
|
|
85
|
+
* tariffs.offTariffChanged(listenerId);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
onTariffChanged(listener: (event: EnyoTariffChangeEvent) => void | Promise<void>): string;
|
|
89
|
+
/**
|
|
90
|
+
* Removes a previously registered tariff change listener. If the listener id
|
|
91
|
+
* is unknown, this operation is a no-op.
|
|
92
|
+
*
|
|
93
|
+
* @param listenerId - The id returned from {@link onTariffChanged}
|
|
94
|
+
*/
|
|
95
|
+
offTariffChanged(listenerId: string): void;
|
|
63
96
|
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { EnyoDynamicGridFee, EnyoDynamicGridFeeFilter, EnyoDynamicGridFeeRegistration, EnyoDynamicGridFeeSeries, EnyoGridFeeChangeEvent } from '../types/enyo-grid-fee.cjs';
|
|
2
|
+
import { EnyoAbsolutePriceWindow } from '../types/enyo-price-schedule.cjs';
|
|
3
|
+
/**
|
|
4
|
+
* Interface for publishing and consuming dynamic grid fees (network charges).
|
|
5
|
+
*
|
|
6
|
+
* Any energy app can act as a producer by registering a grid fee — typically an
|
|
7
|
+
* app that knows the local grid operator's tariff sheet or fetches a published
|
|
8
|
+
* series — and any energy app can act as a consumer by resolving that fee for a
|
|
9
|
+
* time range with {@link getDynamicGridFees}.
|
|
10
|
+
*
|
|
11
|
+
* Publishing requires the `GridFeeRegister` permission; consuming requires
|
|
12
|
+
* `GridFeeUse`.
|
|
13
|
+
*
|
|
14
|
+
* A grid fee describes the site's **grid connection**, not a supplier contract:
|
|
15
|
+
* it is registered and resolved independently of any tariff, and the same fee
|
|
16
|
+
* applies whichever supplier the site buys from.
|
|
17
|
+
*
|
|
18
|
+
* **Nothing here is applied to a price automatically.** The host never folds a
|
|
19
|
+
* grid fee into {@link EnergyAppEnergyPrices.getPrices}, because provider APIs
|
|
20
|
+
* differ: some already return grid-fee-inclusive prices, some do not. The app
|
|
21
|
+
* that owns the tariff knows which is the case — it declares it via the
|
|
22
|
+
* tariff's `priceComposition` and composes the effective price itself with
|
|
23
|
+
* `composeElectricityPrices()`.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Producer: a §14a EnWG module 3 HT/NT network charge
|
|
28
|
+
* const gridFee = energyApp.useGridFee();
|
|
29
|
+
* await gridFee.registerGridFee({
|
|
30
|
+
* id: 'dso-hd-2026',
|
|
31
|
+
* name: 'Netzentgelt HT/NT 2026',
|
|
32
|
+
* gridOperator: 'Netze BW',
|
|
33
|
+
* currency: EnyoCurrencyEnum.EUR,
|
|
34
|
+
* timezone: 'Europe/Berlin',
|
|
35
|
+
* appliesTo: EnyoPriceAppliesToEnum.Consumption,
|
|
36
|
+
* moduleThreeCompliant: true,
|
|
37
|
+
* schedule: {
|
|
38
|
+
* type: EnyoPriceScheduleTypeEnum.Recurring,
|
|
39
|
+
* windows: [
|
|
40
|
+
* { startTimeOfDay: '06:00', endTimeOfDay: '22:00', amountPerKwh: 0.0912 },
|
|
41
|
+
* { startTimeOfDay: '22:00', endTimeOfDay: '06:00', amountPerKwh: 0.0431 },
|
|
42
|
+
* ],
|
|
43
|
+
* },
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* // Consumer: resolve it for the next 24 hours
|
|
47
|
+
* const fees = await gridFee.getDynamicGridFees({
|
|
48
|
+
* fromIso: new Date().toISOString(),
|
|
49
|
+
* untilIso: new Date(Date.now() + 86_400_000).toISOString(),
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export interface EnergyAppGridFee {
|
|
54
|
+
/**
|
|
55
|
+
* Registers a new dynamic grid fee or updates an existing one. Uses upsert
|
|
56
|
+
* logic based on `id` — if a fee with the same id already exists it is
|
|
57
|
+
* replaced, otherwise a new one is created.
|
|
58
|
+
*
|
|
59
|
+
* Requires the `GridFeeRegister` permission.
|
|
60
|
+
*
|
|
61
|
+
* @param registration - The grid fee to register, including its schedule
|
|
62
|
+
* @returns Promise that resolves to the stored grid fee, including the host-assigned `publishedAtIso`
|
|
63
|
+
*/
|
|
64
|
+
registerGridFee(registration: EnyoDynamicGridFeeRegistration): Promise<EnyoDynamicGridFee>;
|
|
65
|
+
/**
|
|
66
|
+
* Partially updates a registered grid fee. Only the provided attributes are
|
|
67
|
+
* modified; all other fields remain unchanged.
|
|
68
|
+
*
|
|
69
|
+
* Requires the `GridFeeRegister` permission.
|
|
70
|
+
*
|
|
71
|
+
* @param id - The unique identifier of the grid fee to update
|
|
72
|
+
* @param attributes - A partial set of grid fee fields to update (excluding `id`)
|
|
73
|
+
* @returns Promise that resolves to the full updated grid fee
|
|
74
|
+
*/
|
|
75
|
+
updateGridFee(id: string, attributes: Partial<Omit<EnyoDynamicGridFeeRegistration, 'id'>>): Promise<EnyoDynamicGridFee>;
|
|
76
|
+
/**
|
|
77
|
+
* Removes a registered grid fee. {@link getDynamicGridFees} resolves to
|
|
78
|
+
* `null` for it afterwards. If the fee does not exist, this operation is a
|
|
79
|
+
* no-op.
|
|
80
|
+
*
|
|
81
|
+
* Requires the `GridFeeRegister` permission.
|
|
82
|
+
*
|
|
83
|
+
* @param id - The unique identifier of the grid fee to remove
|
|
84
|
+
* @returns Promise that resolves when the grid fee has been removed
|
|
85
|
+
*/
|
|
86
|
+
removeGridFee(id: string): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Retrieves all registered grid fees across all energy apps on the system.
|
|
89
|
+
*
|
|
90
|
+
* Requires the `GridFeeUse` permission.
|
|
91
|
+
*
|
|
92
|
+
* @returns Promise that resolves to an array of all registered grid fees
|
|
93
|
+
*/
|
|
94
|
+
listGridFees(): Promise<EnyoDynamicGridFee[]>;
|
|
95
|
+
/**
|
|
96
|
+
* Retrieves a single registered grid fee by its id, or `null` when no fee
|
|
97
|
+
* with that id exists.
|
|
98
|
+
*
|
|
99
|
+
* Requires the `GridFeeUse` permission.
|
|
100
|
+
*
|
|
101
|
+
* @param id - The unique identifier of the grid fee
|
|
102
|
+
* @returns Promise that resolves to the grid fee, or `null`
|
|
103
|
+
*/
|
|
104
|
+
getGridFee(id: string): Promise<EnyoDynamicGridFee | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Replaces the absolute windows of a grid fee whose schedule is
|
|
107
|
+
* {@link EnyoPriceScheduleTypeEnum.Absolute}. Use this for fees the grid
|
|
108
|
+
* operator publishes as a dated series (for example day-ahead), where the
|
|
109
|
+
* schedule changes far more often than the fee's metadata.
|
|
110
|
+
*
|
|
111
|
+
* Windows must not overlap and are stored sorted ascending by `startIso`.
|
|
112
|
+
* Publishing replaces the previously stored windows in full.
|
|
113
|
+
*
|
|
114
|
+
* Requires the `GridFeeRegister` permission.
|
|
115
|
+
*
|
|
116
|
+
* @param id - The unique identifier of the registered grid fee
|
|
117
|
+
* @param windows - The complete set of absolute windows to store
|
|
118
|
+
* @returns Promise that resolves when the windows have been stored and change listeners dispatched
|
|
119
|
+
*/
|
|
120
|
+
publishGridFeeWindows(id: string, windows: EnyoAbsolutePriceWindow[]): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Resolves a dynamic grid fee to a flat **15-minute series** over the
|
|
123
|
+
* requested range — the same resolution
|
|
124
|
+
* {@link EnergyAppEnergyPrices.getPrices} uses, so both series can be
|
|
125
|
+
* combined interval by interval.
|
|
126
|
+
*
|
|
127
|
+
* The fee is selected by `gridFeeId` or `meteringPointId`; with no selector
|
|
128
|
+
* the grid fee that applies to this device is used. Grid fees are **not**
|
|
129
|
+
* bound to a tariff — a network charge is a property of the grid connection,
|
|
130
|
+
* and the same fee applies no matter which supplier the site buys from.
|
|
131
|
+
* Returns `null` when no fee matches the selector.
|
|
132
|
+
*
|
|
133
|
+
* Intervals no window covers resolve to `feePerKwh: 0`, and intervals
|
|
134
|
+
* outside the fee's `validFromIso` / `validUntilIso` window are omitted.
|
|
135
|
+
*
|
|
136
|
+
* Requires the `GridFeeUse` permission.
|
|
137
|
+
*
|
|
138
|
+
* @param filter - The time range and the selector identifying which fee to resolve
|
|
139
|
+
* @returns Promise that resolves to the 15-minute fee series, or `null` when no fee applies
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* const fees = await gridFee.getDynamicGridFees({
|
|
144
|
+
* fromIso: '2026-09-02T00:00:00Z',
|
|
145
|
+
* untilIso: '2026-09-03T00:00:00Z',
|
|
146
|
+
* });
|
|
147
|
+
* fees?.entries.forEach(e => console.log(e.timestampIso, e.feePerKwh));
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
getDynamicGridFees(filter: EnyoDynamicGridFeeFilter): Promise<EnyoDynamicGridFeeSeries | null>;
|
|
151
|
+
/**
|
|
152
|
+
* Registers a listener invoked whenever any grid fee is registered, updated
|
|
153
|
+
* or removed — including when its absolute windows are republished.
|
|
154
|
+
*
|
|
155
|
+
* Use it to recompute composed prices without polling: a grid operator that
|
|
156
|
+
* publishes a new day-ahead series mid-day changes the cost of every future
|
|
157
|
+
* interval.
|
|
158
|
+
*
|
|
159
|
+
* Requires the `GridFeeUse` permission.
|
|
160
|
+
*
|
|
161
|
+
* @param listener - Callback invoked with the change event
|
|
162
|
+
* @returns A unique listener id that can be passed to {@link offGridFeeChanged}
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* const id = gridFee.onGridFeeChanged(async event => {
|
|
167
|
+
* if (event.gridFeeId === myFeeId) await recomputePrices();
|
|
168
|
+
* });
|
|
169
|
+
* // later
|
|
170
|
+
* gridFee.offGridFeeChanged(id);
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
onGridFeeChanged(listener: (event: EnyoGridFeeChangeEvent) => void | Promise<void>): string;
|
|
174
|
+
/**
|
|
175
|
+
* Removes a previously registered grid fee change listener. If the listener
|
|
176
|
+
* id is unknown, this operation is a no-op.
|
|
177
|
+
*
|
|
178
|
+
* @param listenerId - The id returned from {@link onGridFeeChanged}
|
|
179
|
+
*/
|
|
180
|
+
offGridFeeChanged(listenerId: string): void;
|
|
181
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ElectricityTariffTypeEnum = void 0;
|
|
3
|
+
exports.EnyoTariffChangeTypeEnum = exports.GridFeeModeEnum = exports.ElectricityTariffTypeEnum = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Enum representing the type of electricity tariff pricing model
|
|
6
6
|
*/
|
|
@@ -13,3 +13,35 @@ var ElectricityTariffTypeEnum;
|
|
|
13
13
|
/** Price changes dynamically based on market conditions */
|
|
14
14
|
ElectricityTariffTypeEnum["Dynamic"] = "dynamic";
|
|
15
15
|
})(ElectricityTariffTypeEnum || (exports.ElectricityTariffTypeEnum = ElectricityTariffTypeEnum = {}));
|
|
16
|
+
/**
|
|
17
|
+
* How the grid fee (network charge) of a tariff is determined.
|
|
18
|
+
*/
|
|
19
|
+
var GridFeeModeEnum;
|
|
20
|
+
(function (GridFeeModeEnum) {
|
|
21
|
+
/**
|
|
22
|
+
* A single constant fee per kWh, carried by the tariff itself
|
|
23
|
+
* (see {@link DynamicTariffData.gridFeePerKwh}).
|
|
24
|
+
*/
|
|
25
|
+
GridFeeModeEnum["Static"] = "static";
|
|
26
|
+
/**
|
|
27
|
+
* A time-dependent fee, read from the grid fee API with
|
|
28
|
+
* `useGridFee().getDynamicGridFees()`. The tariff only declares *that* the
|
|
29
|
+
* fee is time-dependent — which fee applies is a property of the site's grid
|
|
30
|
+
* connection, not of the tariff.
|
|
31
|
+
*/
|
|
32
|
+
GridFeeModeEnum["Dynamic"] = "dynamic";
|
|
33
|
+
})(GridFeeModeEnum || (exports.GridFeeModeEnum = GridFeeModeEnum = {}));
|
|
34
|
+
/**
|
|
35
|
+
* What happened to a tariff registration.
|
|
36
|
+
*/
|
|
37
|
+
var EnyoTariffChangeTypeEnum;
|
|
38
|
+
(function (EnyoTariffChangeTypeEnum) {
|
|
39
|
+
/** A new tariff was registered. */
|
|
40
|
+
EnyoTariffChangeTypeEnum["Registered"] = "registered";
|
|
41
|
+
/** An existing tariff's attributes, grid fee link or bonuses changed. */
|
|
42
|
+
EnyoTariffChangeTypeEnum["Updated"] = "updated";
|
|
43
|
+
/** A tariff was removed. */
|
|
44
|
+
EnyoTariffChangeTypeEnum["Removed"] = "removed";
|
|
45
|
+
/** A different tariff became the system default. */
|
|
46
|
+
EnyoTariffChangeTypeEnum["DefaultChanged"] = "default-changed";
|
|
47
|
+
})(EnyoTariffChangeTypeEnum || (exports.EnyoTariffChangeTypeEnum = EnyoTariffChangeTypeEnum = {}));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EnyoPriceAppliesToEnum, EnyoPriceSchedule } from './enyo-price-schedule.cjs';
|
|
1
2
|
/**
|
|
2
3
|
* Enum representing the type of electricity tariff pricing model
|
|
3
4
|
*/
|
|
@@ -9,10 +10,119 @@ export declare enum ElectricityTariffTypeEnum {
|
|
|
9
10
|
/** Price changes dynamically based on market conditions */
|
|
10
11
|
Dynamic = "dynamic"
|
|
11
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* How the grid fee (network charge) of a tariff is determined.
|
|
15
|
+
*/
|
|
16
|
+
export declare enum GridFeeModeEnum {
|
|
17
|
+
/**
|
|
18
|
+
* A single constant fee per kWh, carried by the tariff itself
|
|
19
|
+
* (see {@link DynamicTariffData.gridFeePerKwh}).
|
|
20
|
+
*/
|
|
21
|
+
Static = "static",
|
|
22
|
+
/**
|
|
23
|
+
* A time-dependent fee, read from the grid fee API with
|
|
24
|
+
* `useGridFee().getDynamicGridFees()`. The tariff only declares *that* the
|
|
25
|
+
* fee is time-dependent — which fee applies is a property of the site's grid
|
|
26
|
+
* connection, not of the tariff.
|
|
27
|
+
*/
|
|
28
|
+
Dynamic = "dynamic"
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Declares how the grid fee (network charge) that applies alongside a tariff is
|
|
32
|
+
* determined.
|
|
33
|
+
*
|
|
34
|
+
* Mixed into every tariff pricing shape: a fixed energy price combined with
|
|
35
|
+
* time-variable network charges (e.g. §14a EnWG module 3) is just as real a
|
|
36
|
+
* product as a spot-market tariff, so the declaration is not exclusive to
|
|
37
|
+
* dynamic tariffs.
|
|
38
|
+
*
|
|
39
|
+
* A grid fee itself is **not** bound to a tariff — it belongs to the site's grid
|
|
40
|
+
* connection and is registered and resolved through `useGridFee()` independently.
|
|
41
|
+
* The tariff only says whether its grid fee is a constant it carries itself or a
|
|
42
|
+
* time-dependent one to be read from that API.
|
|
43
|
+
*
|
|
44
|
+
* The grid fee is never applied automatically. Energy apps read the fee and
|
|
45
|
+
* compose the effective price themselves — see `composeElectricityPrices()`.
|
|
46
|
+
*/
|
|
47
|
+
export interface TariffGridFeeConfig {
|
|
48
|
+
/**
|
|
49
|
+
* How the grid fee is determined. Defaults to {@link GridFeeModeEnum.Static}
|
|
50
|
+
* when omitted, so tariffs registered before this field existed keep their
|
|
51
|
+
* previous behaviour.
|
|
52
|
+
*
|
|
53
|
+
* {@link GridFeeModeEnum.Dynamic} must not be combined with
|
|
54
|
+
* `priceComposition.includesGridFee === true` — a fee already contained in
|
|
55
|
+
* the tariff's prices must not be added again.
|
|
56
|
+
*/
|
|
57
|
+
gridFeeMode?: GridFeeModeEnum;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Declares which cost components are **already contained** in the prices this
|
|
61
|
+
* tariff yields.
|
|
62
|
+
*
|
|
63
|
+
* Provider APIs differ: some return all-in prices with network charges, levies
|
|
64
|
+
* and taxes baked in, others return the pure energy price. Consumers must never
|
|
65
|
+
* add a component that is already included — this declaration is what makes the
|
|
66
|
+
* difference machine-readable instead of tribal knowledge.
|
|
67
|
+
*
|
|
68
|
+
* When omitted, prices are treated as **energy price only**.
|
|
69
|
+
*/
|
|
70
|
+
export interface TariffPriceCompositionInfo {
|
|
71
|
+
/** `true` when the tariff's prices already contain the grid fee. */
|
|
72
|
+
includesGridFee: boolean;
|
|
73
|
+
/** `true` when the tariff's prices already contain taxes and levies. */
|
|
74
|
+
includesTaxesAndLevies?: boolean;
|
|
75
|
+
/** `true` when the tariff's prices already have its bonuses applied. */
|
|
76
|
+
includesBonuses?: boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A time-dependent discount granted on top of a tariff, expressed in currency
|
|
80
|
+
* per kWh — for example "5 ct/kWh cheaper between 22:00 and 06:00" or a
|
|
81
|
+
* promotional rebate that runs for a fixed number of months.
|
|
82
|
+
*
|
|
83
|
+
* A tariff may carry several bonuses. Amounts in {@link schedule} are positive
|
|
84
|
+
* magnitudes and are **subtracted** from the price.
|
|
85
|
+
*
|
|
86
|
+
* Consumption-quota bonuses ("the first 100 kWh each month are free") are not
|
|
87
|
+
* expressible here — they require consumption accounting that this model
|
|
88
|
+
* deliberately does not carry.
|
|
89
|
+
*/
|
|
90
|
+
export interface EnyoTariffBonus {
|
|
91
|
+
/** Unique identifier of the bonus within its tariff. */
|
|
92
|
+
id: string;
|
|
93
|
+
/** Human-readable name shown to the user, e.g. `'Nachtbonus'`. */
|
|
94
|
+
name: string;
|
|
95
|
+
/**
|
|
96
|
+
* When and how much the discount is. Amounts are positive and subtracted
|
|
97
|
+
* from the price.
|
|
98
|
+
*/
|
|
99
|
+
schedule: EnyoPriceSchedule;
|
|
100
|
+
/**
|
|
101
|
+
* IANA time zone the schedule's wall-clock times are expressed in, e.g.
|
|
102
|
+
* `'Europe/Berlin'`.
|
|
103
|
+
*/
|
|
104
|
+
timezone: string;
|
|
105
|
+
/** Whether the bonus applies to consumption, feed-in, or both. */
|
|
106
|
+
appliesTo: EnyoPriceAppliesToEnum;
|
|
107
|
+
/** Optional start of the bonus's validity in ISO format (inclusive). */
|
|
108
|
+
validFromIso?: string;
|
|
109
|
+
/** Optional end of the bonus's validity in ISO format (exclusive). */
|
|
110
|
+
validUntilIso?: string;
|
|
111
|
+
/**
|
|
112
|
+
* When `true`, this bonus suppresses every lower-priority bonus in the
|
|
113
|
+
* intervals it covers instead of stacking with them.
|
|
114
|
+
*/
|
|
115
|
+
exclusive?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Ranking used to pick between competing exclusive bonuses — higher wins.
|
|
118
|
+
* Defaults to `0`.
|
|
119
|
+
*/
|
|
120
|
+
priority?: number;
|
|
121
|
+
}
|
|
12
122
|
/**
|
|
13
123
|
* Pricing data for a static (fixed-price) electricity tariff
|
|
14
124
|
*/
|
|
15
|
-
export interface StaticTariffData {
|
|
125
|
+
export interface StaticTariffData extends TariffGridFeeConfig {
|
|
16
126
|
/** Price per kWh for consumption */
|
|
17
127
|
pricePerKwh: number;
|
|
18
128
|
/** Currency code (ISO 4217, e.g., 'EUR', 'USD') */
|
|
@@ -21,8 +131,15 @@ export interface StaticTariffData {
|
|
|
21
131
|
/**
|
|
22
132
|
* Pricing data for a dynamic electricity tariff
|
|
23
133
|
*/
|
|
24
|
-
export interface DynamicTariffData {
|
|
25
|
-
/**
|
|
134
|
+
export interface DynamicTariffData extends TariffGridFeeConfig {
|
|
135
|
+
/**
|
|
136
|
+
* Constant price per kWh for grid fees.
|
|
137
|
+
*
|
|
138
|
+
* @deprecated Set {@link TariffGridFeeConfig.gridFeeMode} to
|
|
139
|
+
* {@link GridFeeModeEnum.Dynamic} and read the fee from
|
|
140
|
+
* `useGridFee().getDynamicGridFees()` instead. Still honoured as the
|
|
141
|
+
* constant fallback while `gridFeeMode` is Static or omitted.
|
|
142
|
+
*/
|
|
26
143
|
gridFeePerKwh?: number;
|
|
27
144
|
/** Currency code (ISO 4217, e.g., 'EUR', 'USD') */
|
|
28
145
|
currency: string;
|
|
@@ -39,7 +156,7 @@ export interface TimeVariableScheduleEntry {
|
|
|
39
156
|
/**
|
|
40
157
|
* Pricing data for a time-variable electricity tariff
|
|
41
158
|
*/
|
|
42
|
-
export interface TimeVariableTariffData {
|
|
159
|
+
export interface TimeVariableTariffData extends TariffGridFeeConfig {
|
|
43
160
|
/** Schedule of time-based price entries */
|
|
44
161
|
schedule: TimeVariableScheduleEntry[];
|
|
45
162
|
/** Currency code (ISO 4217, e.g., 'EUR', 'USD') */
|
|
@@ -67,6 +184,17 @@ export interface EnyoElectricityTariff {
|
|
|
67
184
|
dynamicTariffData?: DynamicTariffData;
|
|
68
185
|
/** Optional external tariff id for easy identification */
|
|
69
186
|
externalTariffId?: string;
|
|
187
|
+
/**
|
|
188
|
+
* Optional declaration of which cost components the tariff's prices already
|
|
189
|
+
* contain. Omitted means "energy price only".
|
|
190
|
+
*/
|
|
191
|
+
priceComposition?: TariffPriceCompositionInfo;
|
|
192
|
+
/**
|
|
193
|
+
* Optional discounts granted on top of this tariff. Several bonuses may
|
|
194
|
+
* apply at the same time — overlapping bonuses stack additively unless one
|
|
195
|
+
* of them is {@link EnyoTariffBonus.exclusive}.
|
|
196
|
+
*/
|
|
197
|
+
bonuses?: EnyoTariffBonus[];
|
|
70
198
|
}
|
|
71
199
|
/**
|
|
72
200
|
* Tariff registration data extended with default indicator.
|
|
@@ -76,3 +204,32 @@ export interface EnyoElectricityTariffWithDefault extends EnyoElectricityTariff
|
|
|
76
204
|
/** Indicates whether this tariff is the system default */
|
|
77
205
|
defaultTariff: boolean;
|
|
78
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* What happened to a tariff registration.
|
|
209
|
+
*/
|
|
210
|
+
export declare enum EnyoTariffChangeTypeEnum {
|
|
211
|
+
/** A new tariff was registered. */
|
|
212
|
+
Registered = "registered",
|
|
213
|
+
/** An existing tariff's attributes, grid fee link or bonuses changed. */
|
|
214
|
+
Updated = "updated",
|
|
215
|
+
/** A tariff was removed. */
|
|
216
|
+
Removed = "removed",
|
|
217
|
+
/** A different tariff became the system default. */
|
|
218
|
+
DefaultChanged = "default-changed"
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Event delivered to listeners registered via
|
|
222
|
+
* {@link EnergyAppElectricityTariff.onTariffChanged}.
|
|
223
|
+
*/
|
|
224
|
+
export interface EnyoTariffChangeEvent {
|
|
225
|
+
/** What happened. */
|
|
226
|
+
changeType: EnyoTariffChangeTypeEnum;
|
|
227
|
+
/** Identifier of the affected tariff. */
|
|
228
|
+
tariffId: string;
|
|
229
|
+
/**
|
|
230
|
+
* The tariff after the change, or `null` when it was removed. For
|
|
231
|
+
* {@link EnyoTariffChangeTypeEnum.DefaultChanged} this is the tariff that
|
|
232
|
+
* became the new default.
|
|
233
|
+
*/
|
|
234
|
+
tariff: EnyoElectricityTariffWithDefault | null;
|
|
235
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EnyoGridFeeChangeTypeEnum = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* What happened to a grid fee registration.
|
|
6
|
+
*/
|
|
7
|
+
var EnyoGridFeeChangeTypeEnum;
|
|
8
|
+
(function (EnyoGridFeeChangeTypeEnum) {
|
|
9
|
+
/** A new grid fee was registered. */
|
|
10
|
+
EnyoGridFeeChangeTypeEnum["Registered"] = "registered";
|
|
11
|
+
/** An existing grid fee's attributes or schedule changed. */
|
|
12
|
+
EnyoGridFeeChangeTypeEnum["Updated"] = "updated";
|
|
13
|
+
/** A grid fee was removed. */
|
|
14
|
+
EnyoGridFeeChangeTypeEnum["Removed"] = "removed";
|
|
15
|
+
})(EnyoGridFeeChangeTypeEnum || (exports.EnyoGridFeeChangeTypeEnum = EnyoGridFeeChangeTypeEnum = {}));
|