@enyo-energy/energy-app-sdk 1.24.0 → 1.26.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 +60 -2
- package/dist/cjs/energy-app-package-definition.cjs +29 -1
- package/dist/cjs/energy-app-package-definition.d.cts +77 -0
- 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 +36 -0
- package/dist/cjs/integrations/integration-energy-app.d.cts +26 -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 +108 -2
- package/dist/cjs/types/enyo-data-bus-value.d.cts +334 -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-forecasting.d.cts +36 -5
- 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/types/enyo-weather-history.d.cts +35 -4
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/energy-app-package-definition.d.ts +77 -0
- package/dist/energy-app-package-definition.js +28 -0
- 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 +26 -1
- package/dist/integrations/integration-energy-app.js +36 -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 +334 -2
- package/dist/types/enyo-data-bus-value.js +107 -1
- package/dist/types/enyo-eebus.d.ts +13 -0
- package/dist/types/enyo-electricity-tariff.d.ts +9 -0
- package/dist/types/enyo-forecasting.d.ts +36 -5
- 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/types/enyo-weather-history.d.ts +35 -4
- 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) |
|
|
@@ -249,6 +249,7 @@ Every Energy App must be defined using `defineEnergyAppPackage()`:
|
|
|
249
249
|
import {
|
|
250
250
|
defineEnergyAppPackage,
|
|
251
251
|
EnergyAppPackageCategory,
|
|
252
|
+
EnergyAppPackageOptionsDeviceDetectionModbusModeEnum,
|
|
252
253
|
EnergyAppPermissionTypeEnum
|
|
253
254
|
} from '@enyo-energy/energy-app-sdk';
|
|
254
255
|
|
|
@@ -291,11 +292,22 @@ const packageDef = defineEnergyAppPackage({
|
|
|
291
292
|
},
|
|
292
293
|
deviceDetection: {
|
|
293
294
|
modbus: [{
|
|
295
|
+
// Optional, only on the first entry: how the entries and their matching
|
|
296
|
+
// values combine. Default: RegistersOr_MatchingValuesOr.
|
|
297
|
+
mode: EnergyAppPackageOptionsDeviceDetectionModbusModeEnum.RegistersAnd_MatchingValuesOr,
|
|
294
298
|
unitIds: [1],
|
|
295
299
|
registerAddress: 40001,
|
|
296
300
|
registerSize: 2,
|
|
297
301
|
type: 'string',
|
|
298
302
|
matchingValues: ['SolarMax', 'SMA']
|
|
303
|
+
}, {
|
|
304
|
+
unitIds: [1],
|
|
305
|
+
// `registerType` defaults to 'holding'; use 'input' for function code 4.
|
|
306
|
+
registerType: 'input',
|
|
307
|
+
registerAddress: 30053,
|
|
308
|
+
registerSize: 2,
|
|
309
|
+
type: 'UInt32BE',
|
|
310
|
+
matchingValues: ['9401', '9402']
|
|
299
311
|
}],
|
|
300
312
|
mdns: [{
|
|
301
313
|
// The Envoy advertises under a vendor-specific service type; without
|
|
@@ -1592,13 +1604,18 @@ if (full) console.log(`lat=${full.latitude} lon=${full.longitude}`);
|
|
|
1592
1604
|
|
|
1593
1605
|
#### `useGridConnectionPoint(): EnergyAppGridConnectionPoint`
|
|
1594
1606
|
|
|
1595
|
-
Read the site's grid connection details — main fuse rating, number of phases,
|
|
1607
|
+
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.
|
|
1608
|
+
|
|
1609
|
+
`chargerLimitW` is optional: when it is not configured, load balancing falls back to `DEFAULT_CHARGER_LIMIT_W` (11 kW).
|
|
1596
1610
|
|
|
1597
1611
|
```typescript
|
|
1612
|
+
import {DEFAULT_CHARGER_LIMIT_W} from "@enyo-energy/energy-app-sdk";
|
|
1613
|
+
|
|
1598
1614
|
const gcp = energyApp.useGridConnectionPoint();
|
|
1599
1615
|
const point = await gcp.getGridConnectionPoint();
|
|
1600
1616
|
if (point) {
|
|
1601
1617
|
console.log(`Fuse ${point.fuseAmpere}A across ${point.numberOfPhases} phases`);
|
|
1618
|
+
console.log(`Charger limit ${point.chargerLimitW ?? DEFAULT_CHARGER_LIMIT_W} W`);
|
|
1602
1619
|
}
|
|
1603
1620
|
```
|
|
1604
1621
|
|
|
@@ -1725,6 +1742,14 @@ await tariffs.publishPrices(EnyoTariffDirectionEnum.Consumption, {
|
|
|
1725
1742
|
});
|
|
1726
1743
|
```
|
|
1727
1744
|
|
|
1745
|
+
An entry may carry an optional `gridFeeGrossPerKwh`: the gross grid fee **contained in**
|
|
1746
|
+
`pricePerKwh`, in currency units per kWh. It is a breakdown only — `pricePerKwh` is always the
|
|
1747
|
+
total, so never compute `pricePerKwh + gridFeeGrossPerKwh`.
|
|
1748
|
+
|
|
1749
|
+
```typescript
|
|
1750
|
+
entries.push({ timestampIso: '2026-05-23T10:00:00Z', pricePerKwh: 0.31, gridFeeGrossPerKwh: 0.09 });
|
|
1751
|
+
```
|
|
1752
|
+
|
|
1728
1753
|
**Calling `setTariff` is the activation signal.** Return `AuthenticationRequired` or
|
|
1729
1754
|
`OnboardingRequired` from the handler to have the host send the user somewhere, and carry the
|
|
1730
1755
|
`authenticationUrl` / `onboardingGuideId` that makes it actionable; when that flow later completes,
|
|
@@ -1847,6 +1872,11 @@ forecast series concatenate into one timeline without translation. Every measure
|
|
|
1847
1872
|
optional: you get what the provider holds and you asked for, and a measure it does not hold is simply
|
|
1848
1873
|
absent rather than an error.
|
|
1849
1874
|
|
|
1875
|
+
`timestampIso` is the **start** of the bucket a reading or forecast entry covers. The irradiance
|
|
1876
|
+
fields are the mean over `[timestampIso, timestampIso + resolution)` — not the value at that moment,
|
|
1877
|
+
and not the mean of the preceding hour. Temperature, wind and cloud cover are the value at the start
|
|
1878
|
+
of the bucket for an hourly source, and the time-weighted mean over the bucket at coarser resolutions.
|
|
1879
|
+
|
|
1850
1880
|
Aggregates per measure live in `statistics`, keyed by `WeatherHistoryMeasureEnum`. `averageValue` is
|
|
1851
1881
|
time-weighted; for the irradiance measures it is a mean power density in W/m², so multiply by the
|
|
1852
1882
|
covered duration in hours to get received energy in Wh/m². `symbol` is categorical and therefore
|
|
@@ -3980,6 +4010,12 @@ Each event carries the **complete** picture of the slot — render it as it arri
|
|
|
3980
4010
|
|
|
3981
4011
|
New reason types came with this surface, so a skipped row can say *why* instead of falling back to a generic "scheduled optimization": `SessionComplete`, `AppliancePaused`, `NothingConnected`, `DeadlinePassed`, `WaitingForCheaperSlot`, `AboveOwnPriceLimit`, `BelowMinPower`, `OtherApplianceTurn`, `SupplyExhausted`, `OutsideSchedule` — grouped by the new `SessionState` and `Contention` reason categories. `ApplianceInitiatedDraw` and `PowerOffered` came with the waterfall states above.
|
|
3982
4012
|
|
|
4013
|
+
**Battery vs. charging car.** While a car charges, the house battery is either held out of it or allowed to help, according to the owner's `batteryEvDischargeMode`. Two reason types (category `BatteryState`) say which: `BatteryReservedFromEv` for the hold (`Discharge 0`) and `BatterySupportsEvCharging` for the release (`mode=Auto`). Both carry `context.batteryToEv` (`EnyoDataBusCommandReasonBatteryToEvContext`) with the owner's `mode`, the hold `trigger` (`EnyoBatteryToEvHoldTriggerEnum`: `OwnerBlocked`, `SocLimitReached`, `AllowanceSpent`, `NoMeasurement`), `socLimitPercent`, `allowanceWh` and `remainingWh`. The energy manager re-checks a hold periodically by briefly releasing the battery; that re-check sets `batteryToEv.probe: true` and should not be listed as its own entry in a command history.
|
|
4014
|
+
|
|
4015
|
+
**Short-cycling protection.** When an appliance is kept running (or kept off) to honour its minimum on/off time, state `DeviceProtection` with `context.switching` (`EnyoDataBusCommandReasonSwitchingContext`): `hold` (`EnyoSwitchingProtectionHoldEnum.KeptOn` / `KeptOff`), `minOnSeconds`, `minOffSeconds` and `untilIso`. The text can then say "Kept running for another 4 minutes to protect the compressor" instead of a generic "Protecting the device".
|
|
4016
|
+
|
|
4017
|
+
A hold that keeps an appliance **off** after a stop has its own type, `RestartDelay` (category `DeviceProtection`): set `context.switching` with `hold: KeptOff`, `minOffSeconds` and `untilIso` (when it may restart), and `powerW` to the power waiting for it — e.g. "Short pause after switching off — charging resumes at 13:15 so the car isn't switched on and off too often."
|
|
4018
|
+
|
|
3983
4019
|
## Dynamic Grid Fees & Tariff Bonuses
|
|
3984
4020
|
|
|
3985
4021
|
An electricity price is rarely one number. It is the energy price, plus the grid operator's network
|
|
@@ -4547,6 +4583,28 @@ Notes:
|
|
|
4547
4583
|
- V1 is unchanged and remains fully supported. V2 is an additive sibling, not a
|
|
4548
4584
|
migration.
|
|
4549
4585
|
|
|
4586
|
+
#### Forecasting When a Heat Pump Runs
|
|
4587
|
+
|
|
4588
|
+
A heat pump integration can publish its own forecast of when the heat pump will run with
|
|
4589
|
+
`HeatpumpOperationForecastV1` (or `publishHeatpumpOperationForecast()` on `IntegrationEnergyApp`).
|
|
4590
|
+
It is a prediction, not a request for power — to offer power, send `ApplianceFlexibilityAnnouncementV2`.
|
|
4591
|
+
|
|
4592
|
+
Each entry covers one slot of `resolution`, starting at `timestampIso`. `outdoorTemperatureC` and
|
|
4593
|
+
`running` are always present; `flowTemperatureC`, `generatedHeatWh`, `consumptionWh` and
|
|
4594
|
+
`averagePowerW` are optional. Energy values are per slot, and `averagePowerW` is averaged over the
|
|
4595
|
+
whole slot. Each message replaces the previous forecast for the appliance.
|
|
4596
|
+
|
|
4597
|
+
```typescript
|
|
4598
|
+
this.publishHeatpumpOperationForecast('heatpump-1', {
|
|
4599
|
+
resolution: ForecastResolutionEnum.OneHour,
|
|
4600
|
+
entries: [
|
|
4601
|
+
{timestampIso: '2026-10-06T06:00:00Z', outdoorTemperatureC: 4.5, running: true,
|
|
4602
|
+
flowTemperatureC: 38, generatedHeatWh: 5200, consumptionWh: 1600, averagePowerW: 1600},
|
|
4603
|
+
{timestampIso: '2026-10-06T07:00:00Z', outdoorTemperatureC: 5.0, running: false},
|
|
4604
|
+
],
|
|
4605
|
+
});
|
|
4606
|
+
```
|
|
4607
|
+
|
|
4550
4608
|
#### Explaining Why a Command Was Issued
|
|
4551
4609
|
|
|
4552
4610
|
Every data bus command can carry an `EnyoDataBusCommandReason`. Its `type`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EnergyAppPackageFirmwareModeEnum = exports.EnergyAppPackageCompatibilityStatus = exports.EnergyAppPackageCategory = void 0;
|
|
3
|
+
exports.EnergyAppPackageFirmwareModeEnum = exports.EnergyAppPackageCompatibilityStatus = exports.EnergyAppPackageOptionsDeviceDetectionModbusModeEnum = exports.EnergyAppPackageCategory = void 0;
|
|
4
4
|
exports.defineEnergyAppPackage = defineEnergyAppPackage;
|
|
5
5
|
const version_js_1 = require("./version.cjs");
|
|
6
6
|
var EnergyAppPackageCategory;
|
|
@@ -27,6 +27,34 @@ var EnergyAppPackageCategory;
|
|
|
27
27
|
EnergyAppPackageCategory["Vehicle"] = "vehicle";
|
|
28
28
|
EnergyAppPackageCategory["Other"] = "other";
|
|
29
29
|
})(EnergyAppPackageCategory || (exports.EnergyAppPackageCategory = EnergyAppPackageCategory = {}));
|
|
30
|
+
/**
|
|
31
|
+
* How the Modbus device detection rules in
|
|
32
|
+
* {@link EnergyAppPackageOptionsDeviceDetection.modbus} are combined.
|
|
33
|
+
*
|
|
34
|
+
* Each name has two parts:
|
|
35
|
+
* - `Registers…`: how the entries (registers) of the `modbus` list combine.
|
|
36
|
+
* `Or` means one matching register is enough; `And` means every register has
|
|
37
|
+
* to match, all on the same unit id.
|
|
38
|
+
* - `MatchingValues…`: how the `matchingValues` within one register combine.
|
|
39
|
+
* `Or` means the register's value has to match one of them; `And` means it
|
|
40
|
+
* has to match all of them.
|
|
41
|
+
*
|
|
42
|
+
* Only read from the **first** entry of the `modbus` list and applies to the
|
|
43
|
+
* whole list; set it there and nowhere else. Defaults to
|
|
44
|
+
* {@link RegistersOr_MatchingValuesOr} when omitted, which is the behaviour of
|
|
45
|
+
* all existing rules.
|
|
46
|
+
*/
|
|
47
|
+
var EnergyAppPackageOptionsDeviceDetectionModbusModeEnum;
|
|
48
|
+
(function (EnergyAppPackageOptionsDeviceDetectionModbusModeEnum) {
|
|
49
|
+
/** One register has to match, with one of its matching values. The default. */
|
|
50
|
+
EnergyAppPackageOptionsDeviceDetectionModbusModeEnum["RegistersOr_MatchingValuesOr"] = "RegistersOr_MatchingValuesOr";
|
|
51
|
+
/** One register has to match, with all of its matching values. */
|
|
52
|
+
EnergyAppPackageOptionsDeviceDetectionModbusModeEnum["RegistersOr_MatchingValuesAnd"] = "RegistersOr_MatchingValuesAnd";
|
|
53
|
+
/** Every register has to match, each with one of its matching values. */
|
|
54
|
+
EnergyAppPackageOptionsDeviceDetectionModbusModeEnum["RegistersAnd_MatchingValuesOr"] = "RegistersAnd_MatchingValuesOr";
|
|
55
|
+
/** Every register has to match, each with all of its matching values. */
|
|
56
|
+
EnergyAppPackageOptionsDeviceDetectionModbusModeEnum["RegistersAnd_MatchingValuesAnd"] = "RegistersAnd_MatchingValuesAnd";
|
|
57
|
+
})(EnergyAppPackageOptionsDeviceDetectionModbusModeEnum || (exports.EnergyAppPackageOptionsDeviceDetectionModbusModeEnum = EnergyAppPackageOptionsDeviceDetectionModbusModeEnum = {}));
|
|
30
58
|
/**
|
|
31
59
|
* Whether a declared compatibility entry means "this works" or "this is known
|
|
32
60
|
* not to work".
|
|
@@ -40,8 +40,85 @@ export interface EnergyAppPackageOptionsDeviceDetectionHostname {
|
|
|
40
40
|
operation: 'eq' | 'startsWith';
|
|
41
41
|
matchingValue: string;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Which Modbus register bank a device detection rule reads.
|
|
45
|
+
* - `'holding'`: holding registers, function code 3
|
|
46
|
+
* - `'input'`: input registers, function code 4
|
|
47
|
+
*
|
|
48
|
+
* The two banks are separate address spaces, so the same address may hold
|
|
49
|
+
* different data (or nothing) in each.
|
|
50
|
+
*/
|
|
51
|
+
export type EnergyAppPackageOptionsDeviceDetectionModbusRegisterType = 'holding' | 'input';
|
|
52
|
+
/**
|
|
53
|
+
* How the Modbus device detection rules in
|
|
54
|
+
* {@link EnergyAppPackageOptionsDeviceDetection.modbus} are combined.
|
|
55
|
+
*
|
|
56
|
+
* Each name has two parts:
|
|
57
|
+
* - `Registers…`: how the entries (registers) of the `modbus` list combine.
|
|
58
|
+
* `Or` means one matching register is enough; `And` means every register has
|
|
59
|
+
* to match, all on the same unit id.
|
|
60
|
+
* - `MatchingValues…`: how the `matchingValues` within one register combine.
|
|
61
|
+
* `Or` means the register's value has to match one of them; `And` means it
|
|
62
|
+
* has to match all of them.
|
|
63
|
+
*
|
|
64
|
+
* Only read from the **first** entry of the `modbus` list and applies to the
|
|
65
|
+
* whole list; set it there and nowhere else. Defaults to
|
|
66
|
+
* {@link RegistersOr_MatchingValuesOr} when omitted, which is the behaviour of
|
|
67
|
+
* all existing rules.
|
|
68
|
+
*/
|
|
69
|
+
export declare enum EnergyAppPackageOptionsDeviceDetectionModbusModeEnum {
|
|
70
|
+
/** One register has to match, with one of its matching values. The default. */
|
|
71
|
+
RegistersOr_MatchingValuesOr = "RegistersOr_MatchingValuesOr",
|
|
72
|
+
/** One register has to match, with all of its matching values. */
|
|
73
|
+
RegistersOr_MatchingValuesAnd = "RegistersOr_MatchingValuesAnd",
|
|
74
|
+
/** Every register has to match, each with one of its matching values. */
|
|
75
|
+
RegistersAnd_MatchingValuesOr = "RegistersAnd_MatchingValuesOr",
|
|
76
|
+
/** Every register has to match, each with all of its matching values. */
|
|
77
|
+
RegistersAnd_MatchingValuesAnd = "RegistersAnd_MatchingValuesAnd"
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Optional device detection configuration for Modbus TCP register matching:
|
|
81
|
+
* read a register range and compare its decoded value against the matching
|
|
82
|
+
* values.
|
|
83
|
+
*
|
|
84
|
+
* How several entries and several matching values combine is set by
|
|
85
|
+
* {@link mode} on the first entry of the list.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* // Vendor name in holding registers AND model id in an input register:
|
|
89
|
+
* modbus: [
|
|
90
|
+
* {
|
|
91
|
+
* mode: EnergyAppPackageOptionsDeviceDetectionModbusModeEnum.RegistersAnd_MatchingValuesOr,
|
|
92
|
+
* unitIds: [1],
|
|
93
|
+
* registerAddress: 40001,
|
|
94
|
+
* registerSize: 2,
|
|
95
|
+
* type: 'string',
|
|
96
|
+
* matchingValues: ['SMA'],
|
|
97
|
+
* },
|
|
98
|
+
* {
|
|
99
|
+
* unitIds: [1],
|
|
100
|
+
* registerType: 'input',
|
|
101
|
+
* registerAddress: 30053,
|
|
102
|
+
* registerSize: 2,
|
|
103
|
+
* type: 'UInt32BE',
|
|
104
|
+
* matchingValues: ['9401', '9402'],
|
|
105
|
+
* },
|
|
106
|
+
* ]
|
|
107
|
+
*/
|
|
43
108
|
export interface EnergyAppPackageOptionsDeviceDetectionModbus {
|
|
109
|
+
/**
|
|
110
|
+
* How all entries of the `modbus` list and their matching values combine.
|
|
111
|
+
* Only read from the first entry of the list — set it there and leave it
|
|
112
|
+
* out on the others. Defaults to
|
|
113
|
+
* {@link EnergyAppPackageOptionsDeviceDetectionModbusModeEnum.RegistersOr_MatchingValuesOr}.
|
|
114
|
+
*/
|
|
115
|
+
mode?: EnergyAppPackageOptionsDeviceDetectionModbusModeEnum;
|
|
44
116
|
unitIds: number[];
|
|
117
|
+
/**
|
|
118
|
+
* Which register bank to read. Defaults to `'holding'` when omitted,
|
|
119
|
+
* which is the behaviour of all existing rules.
|
|
120
|
+
*/
|
|
121
|
+
registerType?: EnergyAppPackageOptionsDeviceDetectionModbusRegisterType;
|
|
45
122
|
/** Register address, for example 30001 */
|
|
46
123
|
registerAddress: number;
|
|
47
124
|
/** Register size, for example 2 for 30001 - 30002 */
|
|
@@ -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 — ` +
|
|
@@ -221,6 +221,42 @@ class IntegrationEnergyApp extends energy_app_js_1.EnergyApp {
|
|
|
221
221
|
};
|
|
222
222
|
this.useDataBus().sendMessage([msg]);
|
|
223
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Publishes a `HeatpumpOperationForecastV1` — this heat pump's own forecast
|
|
226
|
+
* of when it will run, slot by slot.
|
|
227
|
+
*
|
|
228
|
+
* A prediction, not a request for power: to offer power the heat pump could
|
|
229
|
+
* absorb, use {@link publishFlexibilityAnnouncement}. Publish again whenever
|
|
230
|
+
* the forecast changes; each message replaces the previous one for the
|
|
231
|
+
* appliance.
|
|
232
|
+
*
|
|
233
|
+
* @param applianceId - The heat pump appliance the forecast is for.
|
|
234
|
+
* @param forecast - The slot length and the slots. See
|
|
235
|
+
* {@link EnyoDataBusHeatpumpOperationForecastV1.data}.
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* this.publishHeatpumpOperationForecast('heatpump-1', {
|
|
240
|
+
* resolution: ForecastResolutionEnum.OneHour,
|
|
241
|
+
* entries: [
|
|
242
|
+
* {timestampIso: '2026-10-06T06:00:00Z', outdoorTemperatureC: 4.5, running: true, averagePowerW: 1600},
|
|
243
|
+
* {timestampIso: '2026-10-06T07:00:00Z', outdoorTemperatureC: 5.0, running: false},
|
|
244
|
+
* ],
|
|
245
|
+
* });
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
publishHeatpumpOperationForecast(applianceId, forecast) {
|
|
249
|
+
const msg = {
|
|
250
|
+
id: this.generateMessageId(),
|
|
251
|
+
type: 'message',
|
|
252
|
+
message: enyo_data_bus_value_js_1.EnyoDataBusMessageEnum.HeatpumpOperationForecastV1,
|
|
253
|
+
source: this.source,
|
|
254
|
+
applianceId,
|
|
255
|
+
timestampIso: new Date().toISOString(),
|
|
256
|
+
data: forecast
|
|
257
|
+
};
|
|
258
|
+
this.useDataBus().sendMessage([msg]);
|
|
259
|
+
}
|
|
224
260
|
/**
|
|
225
261
|
* Resolves the list of appliance IDs this integration is responsible for.
|
|
226
262
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EnergyApp } from "../energy-app.cjs";
|
|
2
|
-
import { EnyoDataBusApplianceFlexibilityAnnouncementV2, EnyoDataBusGridOperatorPowerLimitationExecutedV1, EnyoDataBusGridOperatorPowerLimitationV1, EnyoDataBusMessage, EnyoDataBusMessageEnum } from "../types/enyo-data-bus-value.cjs";
|
|
2
|
+
import { EnyoDataBusApplianceFlexibilityAnnouncementV2, EnyoDataBusGridOperatorPowerLimitationExecutedV1, EnyoDataBusGridOperatorPowerLimitationV1, EnyoDataBusHeatpumpOperationForecastV1, 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";
|
|
@@ -166,6 +166,31 @@ export declare abstract class IntegrationEnergyApp extends EnergyApp {
|
|
|
166
166
|
* ```
|
|
167
167
|
*/
|
|
168
168
|
publishFlexibilityAnnouncement(applianceId: string, flexibility: EnyoDataBusApplianceFlexibilityAnnouncementV2['data']['flexibility']): void;
|
|
169
|
+
/**
|
|
170
|
+
* Publishes a `HeatpumpOperationForecastV1` — this heat pump's own forecast
|
|
171
|
+
* of when it will run, slot by slot.
|
|
172
|
+
*
|
|
173
|
+
* A prediction, not a request for power: to offer power the heat pump could
|
|
174
|
+
* absorb, use {@link publishFlexibilityAnnouncement}. Publish again whenever
|
|
175
|
+
* the forecast changes; each message replaces the previous one for the
|
|
176
|
+
* appliance.
|
|
177
|
+
*
|
|
178
|
+
* @param applianceId - The heat pump appliance the forecast is for.
|
|
179
|
+
* @param forecast - The slot length and the slots. See
|
|
180
|
+
* {@link EnyoDataBusHeatpumpOperationForecastV1.data}.
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* this.publishHeatpumpOperationForecast('heatpump-1', {
|
|
185
|
+
* resolution: ForecastResolutionEnum.OneHour,
|
|
186
|
+
* entries: [
|
|
187
|
+
* {timestampIso: '2026-10-06T06:00:00Z', outdoorTemperatureC: 4.5, running: true, averagePowerW: 1600},
|
|
188
|
+
* {timestampIso: '2026-10-06T07:00:00Z', outdoorTemperatureC: 5.0, running: false},
|
|
189
|
+
* ],
|
|
190
|
+
* });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
publishHeatpumpOperationForecast(applianceId: string, forecast: EnyoDataBusHeatpumpOperationForecastV1['data']): void;
|
|
169
194
|
/**
|
|
170
195
|
* Resolves the list of appliance IDs this integration is responsible for.
|
|
171
196
|
*
|
|
@@ -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.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EnyoPowerSourceEnum = exports.EnyoHeatpumpHeatSourceEnum = exports.EnyoHeatpumpControlPurposeEnum = exports.EnyoChargingProfileTypeEnum = exports.EnyoCommandAcknowledgeAnswerEnum = exports.EnyoStorageControlDirectionEnum = exports.EnyoStorageControlModeEnum = exports.EnyoStorageScheduleDirectionEnum = exports.EnyoStorageScheduleModeEnum = exports.EnyoChargingLimitRequestResultEnum = exports.EnyoDataBusMessageEnum = exports.EnyoChargeInitiatorEnum = exports.EnyoPriceLimitModeEnum = exports.EnyoChargeModeEnum = exports.EnyoChargingStopReason = exports.EnyoChargingMeterValueContext = exports.EnyoStringStateEnum = exports.EnyoHeatingRodStateEnum = exports.EnyoInverterStateEnum = exports.EnyoBatteryStateEnum = exports.EnyoGridOperatorLimitTypeEnum = exports.EnyoDataBusCommandReasonCategoryEnum = exports.EnyoDataBusCommandReasonTypeEnum = void 0;
|
|
3
|
+
exports.EnyoPowerSourceEnum = exports.EnyoHeatpumpHeatSourceEnum = exports.EnyoHeatpumpControlPurposeEnum = exports.EnyoChargingProfileTypeEnum = exports.EnyoCommandAcknowledgeAnswerEnum = exports.EnyoStorageControlDirectionEnum = exports.EnyoStorageControlModeEnum = exports.EnyoStorageScheduleDirectionEnum = exports.EnyoStorageScheduleModeEnum = exports.EnyoChargingLimitRequestResultEnum = exports.EnyoDataBusMessageEnum = exports.EnyoChargeInitiatorEnum = exports.EnyoPriceLimitModeEnum = exports.EnyoChargeModeEnum = exports.EnyoChargingStopReason = exports.EnyoChargingMeterValueContext = exports.EnyoStringStateEnum = exports.EnyoHeatingRodStateEnum = exports.EnyoInverterStateEnum = exports.EnyoBatteryStateEnum = exports.EnyoGridOperatorLimitTypeEnum = exports.EnyoSwitchingProtectionHoldEnum = exports.EnyoBatteryToEvHoldTriggerEnum = exports.EnyoDataBusCommandReasonCategoryEnum = exports.EnyoDataBusCommandReasonTypeEnum = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Enum representing the reason type for why a data bus command was issued.
|
|
6
6
|
* Used to attach context to commands for logging, debugging, and UI display.
|
|
@@ -71,7 +71,16 @@ var EnyoDataBusCommandReasonTypeEnum;
|
|
|
71
71
|
EnyoDataBusCommandReasonTypeEnum["ScheduledOptimization"] = "scheduled-optimization";
|
|
72
72
|
/** Command issued because the user explicitly requested it */
|
|
73
73
|
EnyoDataBusCommandReasonTypeEnum["UserRequest"] = "user-request";
|
|
74
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Command issued to protect the device (e.g. overheating or safety limit).
|
|
76
|
+
*
|
|
77
|
+
* When the protection is a minimum on/off time — an appliance kept running
|
|
78
|
+
* (or kept off) to avoid short-cycling its compressor — set
|
|
79
|
+
* {@link EnyoDataBusCommandReasonContext.switching} so the text can say how
|
|
80
|
+
* long the hold lasts instead of a generic "protecting the device". A hold
|
|
81
|
+
* that keeps an appliance OFF after a stop has its own type,
|
|
82
|
+
* {@link RestartDelay}.
|
|
83
|
+
*/
|
|
75
84
|
EnyoDataBusCommandReasonTypeEnum["DeviceProtection"] = "device-protection";
|
|
76
85
|
/** Command issued because home consumption is high */
|
|
77
86
|
EnyoDataBusCommandReasonTypeEnum["HomeConsumptionHigh"] = "home-consumption-high";
|
|
@@ -173,6 +182,53 @@ var EnyoDataBusCommandReasonTypeEnum;
|
|
|
173
182
|
* other constraint were lifted, the appliance would still stay off.
|
|
174
183
|
*/
|
|
175
184
|
EnyoDataBusCommandReasonTypeEnum["OutsideSchedule"] = "outside-schedule";
|
|
185
|
+
/**
|
|
186
|
+
* The house battery is held (`Discharge 0`) so that stored energy does not
|
|
187
|
+
* flow into a charging car.
|
|
188
|
+
*
|
|
189
|
+
* Stated by the decision maker that judged the owner's
|
|
190
|
+
* `batteryEvDischargeMode`, never inferred by the battery's own command
|
|
191
|
+
* path. Says WHY through {@link EnyoDataBusCommandReasonContext.batteryToEv}
|
|
192
|
+
* — the owner blocked it, the SoC limit is reached, the watt-hour allowance
|
|
193
|
+
* is spent, or the battery's power cannot be measured. Set
|
|
194
|
+
* {@link EnyoDataBusCommandReason.socPercent} to the pack's current SoC.
|
|
195
|
+
*
|
|
196
|
+
* Told apart from {@link BatterySoCLow}: the pack is not low, it is at the
|
|
197
|
+
* floor the owner chose for the car. Category
|
|
198
|
+
* {@link EnyoDataBusCommandReasonCategoryEnum.BatteryState}.
|
|
199
|
+
*/
|
|
200
|
+
EnyoDataBusCommandReasonTypeEnum["BatteryReservedFromEv"] = "battery-reserved-from-ev";
|
|
201
|
+
/**
|
|
202
|
+
* While a car charges, the house battery is left to self-manage
|
|
203
|
+
* (`mode=Auto`) and may cover part of the car's draw — within what the
|
|
204
|
+
* owner allowed.
|
|
205
|
+
*
|
|
206
|
+
* The counterpart of {@link BatteryReservedFromEv}. Set
|
|
207
|
+
* {@link EnyoDataBusCommandReasonContext.batteryToEv} so the text can say
|
|
208
|
+
* how far: down to an SoC limit, or how many watt-hours of the allowance
|
|
209
|
+
* are left. A short re-check of an existing hold sets `batteryToEv.probe` —
|
|
210
|
+
* consumers SHOULD NOT show a probe as a separate history entry. Category
|
|
211
|
+
* {@link EnyoDataBusCommandReasonCategoryEnum.BatteryState}.
|
|
212
|
+
*/
|
|
213
|
+
EnyoDataBusCommandReasonTypeEnum["BatterySupportsEvCharging"] = "battery-supports-ev-charging";
|
|
214
|
+
/**
|
|
215
|
+
* The appliance was switched off a moment ago and is held off for its
|
|
216
|
+
* declared minimum off-time, so it is not cycled on and off. Stated by the
|
|
217
|
+
* energy manager's switching protection.
|
|
218
|
+
*
|
|
219
|
+
* Set {@link EnyoDataBusCommandReasonContext.switching} with
|
|
220
|
+
* {@link EnyoSwitchingProtectionHoldEnum.KeptOff}, `minOffSeconds` and
|
|
221
|
+
* `untilIso` — when it may restart, i.e. the last stop plus the minimum
|
|
222
|
+
* off-time — and {@link EnyoDataBusCommandReason.powerW} to the power that
|
|
223
|
+
* is waiting for it, so the text can say why it will start.
|
|
224
|
+
*
|
|
225
|
+
* The specific form of {@link DeviceProtection} for a hold after a stop;
|
|
226
|
+
* a hold that keeps an appliance RUNNING stays `DeviceProtection` with
|
|
227
|
+
* {@link EnyoSwitchingProtectionHoldEnum.KeptOn}. Category
|
|
228
|
+
* {@link EnyoDataBusCommandReasonCategoryEnum.DeviceProtection} — it protects
|
|
229
|
+
* the appliance from short-cycling and is not about price, sun or contention.
|
|
230
|
+
*/
|
|
231
|
+
EnyoDataBusCommandReasonTypeEnum["RestartDelay"] = "restart-delay";
|
|
176
232
|
})(EnyoDataBusCommandReasonTypeEnum || (exports.EnyoDataBusCommandReasonTypeEnum = EnyoDataBusCommandReasonTypeEnum = {}));
|
|
177
233
|
/**
|
|
178
234
|
* Coarse, machine-readable grouping of why a data bus command was issued.
|
|
@@ -215,6 +271,54 @@ var EnyoDataBusCommandReasonCategoryEnum;
|
|
|
215
271
|
/** Any reason not covered by the categories above. */
|
|
216
272
|
EnyoDataBusCommandReasonCategoryEnum["Other"] = "other";
|
|
217
273
|
})(EnyoDataBusCommandReasonCategoryEnum || (exports.EnyoDataBusCommandReasonCategoryEnum = EnyoDataBusCommandReasonCategoryEnum = {}));
|
|
274
|
+
/**
|
|
275
|
+
* Which part of the owner's battery-to-EV setting
|
|
276
|
+
* (`batteryEvDischargeMode`) caused a
|
|
277
|
+
* {@link EnyoDataBusCommandReasonTypeEnum.BatteryReservedFromEv} hold.
|
|
278
|
+
*/
|
|
279
|
+
var EnyoBatteryToEvHoldTriggerEnum;
|
|
280
|
+
(function (EnyoBatteryToEvHoldTriggerEnum) {
|
|
281
|
+
/**
|
|
282
|
+
* {@link EnergyManagerBatteryEvDischargeModeEnum.BlockDischarge}: the owner
|
|
283
|
+
* never lets the battery charge the car.
|
|
284
|
+
*/
|
|
285
|
+
EnyoBatteryToEvHoldTriggerEnum["OwnerBlocked"] = "owner-blocked";
|
|
286
|
+
/**
|
|
287
|
+
* {@link EnergyManagerBatteryEvDischargeModeEnum.SocLimit}: the pack has
|
|
288
|
+
* reached the owner's floor
|
|
289
|
+
* ({@link EnyoDataBusCommandReasonBatteryToEvContext.socLimitPercent}).
|
|
290
|
+
*/
|
|
291
|
+
EnyoBatteryToEvHoldTriggerEnum["SocLimitReached"] = "soc-limit-reached";
|
|
292
|
+
/**
|
|
293
|
+
* {@link EnergyManagerBatteryEvDischargeModeEnum.FixedWh}: this session's
|
|
294
|
+
* allowance ({@link EnyoDataBusCommandReasonBatteryToEvContext.allowanceWh})
|
|
295
|
+
* has gone into the car.
|
|
296
|
+
*/
|
|
297
|
+
EnyoBatteryToEvHoldTriggerEnum["AllowanceSpent"] = "allowance-spent";
|
|
298
|
+
/**
|
|
299
|
+
* The pack's live power cannot be read, so it cannot be shown NOT to feed
|
|
300
|
+
* the car. A fail-safe, stated out loud so that a site whose battery app
|
|
301
|
+
* publishes no power is diagnosable.
|
|
302
|
+
*/
|
|
303
|
+
EnyoBatteryToEvHoldTriggerEnum["NoMeasurement"] = "no-measurement";
|
|
304
|
+
})(EnyoBatteryToEvHoldTriggerEnum || (exports.EnyoBatteryToEvHoldTriggerEnum = EnyoBatteryToEvHoldTriggerEnum = {}));
|
|
305
|
+
/**
|
|
306
|
+
* Which way a short-cycling protection holds an appliance.
|
|
307
|
+
*/
|
|
308
|
+
var EnyoSwitchingProtectionHoldEnum;
|
|
309
|
+
(function (EnyoSwitchingProtectionHoldEnum) {
|
|
310
|
+
/**
|
|
311
|
+
* Kept running although the plan would stop it, because it has not yet run
|
|
312
|
+
* its minimum on-time — it may be drawing grid power meanwhile.
|
|
313
|
+
*/
|
|
314
|
+
EnyoSwitchingProtectionHoldEnum["KeptOn"] = "kept-on";
|
|
315
|
+
/**
|
|
316
|
+
* Kept off although the plan would start it, because it has not yet rested
|
|
317
|
+
* its minimum off-time (e.g. the compressor gap between two starts). Goes
|
|
318
|
+
* with {@link EnyoDataBusCommandReasonTypeEnum.RestartDelay}.
|
|
319
|
+
*/
|
|
320
|
+
EnyoSwitchingProtectionHoldEnum["KeptOff"] = "kept-off";
|
|
321
|
+
})(EnyoSwitchingProtectionHoldEnum || (exports.EnyoSwitchingProtectionHoldEnum = EnyoSwitchingProtectionHoldEnum = {}));
|
|
218
322
|
/**
|
|
219
323
|
* Whether a grid operator power limitation caps power drawn from the grid
|
|
220
324
|
* (consumption) or power fed into the grid (production).
|
|
@@ -429,6 +533,8 @@ var EnyoDataBusMessageEnum;
|
|
|
429
533
|
EnyoDataBusMessageEnum["ApplianceFlexibilityAnnouncementV2"] = "ApplianceFlexibilityAnnouncementV2";
|
|
430
534
|
EnyoDataBusMessageEnum["ApplianceStateUpdateV1"] = "ApplianceStateUpdateV1";
|
|
431
535
|
EnyoDataBusMessageEnum["HeatpumpValuesUpdateV1"] = "HeatpumpValuesUpdateV1";
|
|
536
|
+
/** A heat pump integration's forecast of when its heat pump will run, slot by slot. */
|
|
537
|
+
EnyoDataBusMessageEnum["HeatpumpOperationForecastV1"] = "HeatpumpOperationForecastV1";
|
|
432
538
|
EnyoDataBusMessageEnum["HeatingRodValuesUpdateV1"] = "HeatingRodValuesUpdateV1";
|
|
433
539
|
EnyoDataBusMessageEnum["ChargingStartedV1"] = "ChargingStartedV1";
|
|
434
540
|
EnyoDataBusMessageEnum["ChargingMeterValuesUpdateV1"] = "ChargingMeterValuesUpdateV1";
|