@enyo-energy/energy-app-sdk 1.38.0 → 1.39.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 +136 -18
- package/dist/cjs/packages/energy-app-notification.d.cts +164 -2
- package/dist/cjs/types/enyo-notification.d.cts +55 -2
- package/dist/cjs/version.cjs +1 -1
- package/dist/cjs/version.d.cts +1 -1
- package/dist/packages/energy-app-notification.d.ts +164 -2
- package/dist/types/enyo-notification.d.ts +55 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1290,32 +1290,150 @@ prices.onPriceChange((newPrice) => {
|
|
|
1290
1290
|
|
|
1291
1291
|
#### `useNotification(): EnergyAppNotification`
|
|
1292
1292
|
|
|
1293
|
-
Send notifications to users
|
|
1293
|
+
Send notifications to users. Every category must be registered before it is used; the host uses the category for the
|
|
1294
|
+
user's on/off switch and for rate limits.
|
|
1294
1295
|
|
|
1295
1296
|
```typescript
|
|
1296
1297
|
const notifications = energyApp.useNotification();
|
|
1297
1298
|
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1299
|
+
notifications.registerNotificationCategory({
|
|
1300
|
+
category: 'connection-issue',
|
|
1301
|
+
name: [
|
|
1302
|
+
{ language: 'en', name: 'Connection issue' },
|
|
1303
|
+
{ language: 'de', name: 'Verbindungsproblem' }
|
|
1304
|
+
]
|
|
1304
1305
|
});
|
|
1305
1306
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
type: '
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
}
|
|
1307
|
+
const notificationId = notifications.sendNotification(
|
|
1308
|
+
'connection-issue',
|
|
1309
|
+
{ applianceId, target: { type: 'appliance-settings', applianceId } },
|
|
1310
|
+
[
|
|
1311
|
+
{ language: 'en', title: 'Inverter offline', body: 'Inverter communication lost - please check the connection.' },
|
|
1312
|
+
{ language: 'de', title: 'Wechselrichter offline', body: 'Keine Verbindung zum Wechselrichter - bitte Verbindung prüfen.' }
|
|
1313
|
+
]
|
|
1314
|
+
);
|
|
1315
|
+
```
|
|
1316
|
+
|
|
1317
|
+
Categories:
|
|
1318
|
+
|
|
1319
|
+
| Category | Use when |
|
|
1320
|
+
|---|---|
|
|
1321
|
+
| `connection-issue` | An appliance, gateway or upstream service is unreachable. |
|
|
1322
|
+
| `onboarding-required` | The user has to complete (or revisit) an onboarding flow. |
|
|
1323
|
+
| `charging-issue` | The app asked a charger to charge, but it is not charging. See [Charging issues](#charging-issues). |
|
|
1324
|
+
| `battery-issue` | The app commanded a battery, but it does not follow the command. See [Battery issues](#battery-issues). |
|
|
1325
|
+
| `authentication-required` | A sign-in that used to work was lost. See [Lost sign-in](#lost-sign-in). |
|
|
1326
|
+
|
|
1327
|
+
Targets (`options.target`) decide where tapping the notification leads:
|
|
1328
|
+
|
|
1329
|
+
| Target | Opens |
|
|
1330
|
+
|---|---|
|
|
1331
|
+
| `{ type: 'onboarding', onboardingName }` | A registered onboarding guide. |
|
|
1332
|
+
| `{ type: 'energy-app-settings' }` | The package's own settings. |
|
|
1333
|
+
| `{ type: 'appliance-settings', applianceId }` | The settings screen of an appliance. |
|
|
1334
|
+
| `{ type: 'appliance', applianceId }` | The live view of an appliance (current state, power and session). |
|
|
1335
|
+
| `{ type: 'authentication', applianceId? }` | The package's pending sign-in, created with `requestAuthentication()`. |
|
|
1336
|
+
| `{ type: 'subscription-offer', planKey }` | The offer screen for a subscription plan. |
|
|
1312
1337
|
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1338
|
+
`sendNotification` throws an `EnyoNotificationSendError` with `type: 'not-registered'` if the category was not
|
|
1339
|
+
registered, or `type: 'rate-limit'` if the host's rate limit for the category is exceeded.
|
|
1340
|
+
|
|
1341
|
+
##### Charging issues
|
|
1342
|
+
|
|
1343
|
+
Only the app that decided a charger should charge knows that it should be charging, so the app sends
|
|
1344
|
+
`charging-issue` notifications. The host relies on these rules and does not re-check them. Send one only when
|
|
1345
|
+
**all** of the following hold:
|
|
1346
|
+
|
|
1347
|
+
- The app itself asked the charger to charge: it sent a start or resume, or it is giving the charger more than 0 W.
|
|
1348
|
+
- The charger has stayed non-charging for at least 5 minutes after that request (status is not `Charging`, or it is
|
|
1349
|
+
`Charging` but draws almost no power).
|
|
1350
|
+
- The charger is not `Suspended` with reason `EnyoChargerApplianceSuspendedReasonEnum.Ev`: the car is full or paused
|
|
1351
|
+
charging itself, which is not a fault.
|
|
1352
|
+
- No grid-operator limit (§14a / `GridOperatorPowerLimitationV1`) is currently pushing the charger to 0.
|
|
1353
|
+
|
|
1354
|
+
Send it **at most once per plug-in**: wait until the charger is `Available` again (car unplugged) before sending
|
|
1355
|
+
another one for that appliance. Always pass `applianceId` and the `appliance` target. The host drops more than one
|
|
1356
|
+
`charging-issue` per appliance per 30 minutes with a `rate-limit` error.
|
|
1357
|
+
|
|
1358
|
+
```typescript
|
|
1359
|
+
const notification = energyApp.useNotification();
|
|
1360
|
+
|
|
1361
|
+
notification.registerNotificationCategory({
|
|
1362
|
+
category: 'charging-issue',
|
|
1363
|
+
name: [
|
|
1364
|
+
{language: 'de', name: 'Ladeprobleme'},
|
|
1365
|
+
{language: 'en', name: 'Charging issues'},
|
|
1366
|
+
],
|
|
1367
|
+
description: [
|
|
1368
|
+
{language: 'de', name: 'Ladeprobleme', description: 'Wenn dein Auto nicht lädt, obwohl es laden sollte.'},
|
|
1369
|
+
{language: 'en', name: 'Charging issues', description: 'When your car is not charging although it should.'},
|
|
1370
|
+
],
|
|
1318
1371
|
});
|
|
1372
|
+
|
|
1373
|
+
notification.sendNotification(
|
|
1374
|
+
'charging-issue',
|
|
1375
|
+
{applianceId, target: {type: 'appliance', applianceId}},
|
|
1376
|
+
[
|
|
1377
|
+
{language: 'de', title: 'Dein Auto lädt nicht', body: 'Die Wallbox sollte gerade laden, tut es aber nicht. Prüfe bitte Auto und Ladekabel.'},
|
|
1378
|
+
{language: 'en', title: 'Your car is not charging', body: 'The wallbox should be charging right now but isn\'t. Please check the car and the charging cable.'},
|
|
1379
|
+
],
|
|
1380
|
+
);
|
|
1381
|
+
```
|
|
1382
|
+
|
|
1383
|
+
##### Battery issues
|
|
1384
|
+
|
|
1385
|
+
`battery-issue` follows the same idea for home batteries. Send one only when **all** of the following hold:
|
|
1386
|
+
|
|
1387
|
+
- The app itself commanded the battery (`SetStorageControlV2` with mode `Controlled`, or one of the other storage
|
|
1388
|
+
commands) and that command is still in effect. Never while the battery runs on `Auto`.
|
|
1389
|
+
- For at least 5 minutes the battery has not followed it, judged by `batteryPowerW` in `BatteryValuesUpdateV1`:
|
|
1390
|
+
not charging on `Charge`, not discharging on `Discharge`, or moving power noticeably on `Hold`.
|
|
1391
|
+
- The battery is not simply at its limit: no charge command at or above `maxSoC` (or 100 %), no discharge command
|
|
1392
|
+
at or below `minSoC`.
|
|
1393
|
+
- A discharge to the house is not just capped by low household consumption.
|
|
1394
|
+
- No grid-operator limit (§14a) is pushing the battery to 0, and `controlAllowed` is not `false`.
|
|
1395
|
+
|
|
1396
|
+
Send it **at most once per issue**: wait until the battery follows a command again, or the app releases it to
|
|
1397
|
+
`Auto`, before sending another one. Always pass `applianceId` and the `appliance` target. The host drops more than
|
|
1398
|
+
one `battery-issue` per appliance per 30 minutes with a `rate-limit` error.
|
|
1399
|
+
|
|
1400
|
+
```typescript
|
|
1401
|
+
notification.sendNotification(
|
|
1402
|
+
'battery-issue',
|
|
1403
|
+
{applianceId, target: {type: 'appliance', applianceId}},
|
|
1404
|
+
[
|
|
1405
|
+
{language: 'de', title: 'Dein Speicher reagiert nicht', body: 'Der Batteriespeicher folgt der Steuerung gerade nicht. Prüfe bitte, ob die externe Steuerung am Speicher aktiviert ist.'},
|
|
1406
|
+
{language: 'en', title: 'Your battery is not responding', body: 'The home battery is not following the control right now. Please check that external control is enabled on the battery.'},
|
|
1407
|
+
],
|
|
1408
|
+
);
|
|
1409
|
+
```
|
|
1410
|
+
|
|
1411
|
+
##### Lost sign-in
|
|
1412
|
+
|
|
1413
|
+
`requestAuthentication()` already prompts the user, including for the first sign-in during onboarding.
|
|
1414
|
+
`authentication-required` is only for a sign-in that **used to work** and was lost. Send one only when:
|
|
1415
|
+
|
|
1416
|
+
- The package was `Authenticated` before, the vendor now rejects the credentials or token, and a refresh failed.
|
|
1417
|
+
- The failure is not transient. Timeouts or a vendor outage are a `connection-issue`.
|
|
1418
|
+
- The user did not sign out themselves.
|
|
1419
|
+
|
|
1420
|
+
Before sending, set the state with `setAuthenticationState()` and create a new request with
|
|
1421
|
+
`requestAuthentication()`, so the `authentication` target has a sign-in to open. Send it **at most once per lost
|
|
1422
|
+
session**, and not again until the package is `Authenticated` again. The host allows one per package (or per
|
|
1423
|
+
appliance, for an appliance sign-in) per 24 hours.
|
|
1424
|
+
|
|
1425
|
+
```typescript
|
|
1426
|
+
await auth.setAuthenticationState({state: EnyoAuthenticationStateEnum.AuthenticationFailed});
|
|
1427
|
+
await auth.requestAuthentication({authenticationType: 'oauth', oauth: {}, oneTimeAuthentication: false});
|
|
1428
|
+
|
|
1429
|
+
notification.sendNotification(
|
|
1430
|
+
'authentication-required',
|
|
1431
|
+
{target: {type: 'authentication'}},
|
|
1432
|
+
[
|
|
1433
|
+
{language: 'de', title: 'Bitte erneut anmelden', body: 'Deine Anmeldung ist abgelaufen. Melde dich erneut an, damit wir deine Geräte weiter steuern können.'},
|
|
1434
|
+
{language: 'en', title: 'Please sign in again', body: 'Your sign-in has expired. Sign in again so we can keep controlling your devices.'},
|
|
1435
|
+
],
|
|
1436
|
+
);
|
|
1319
1437
|
```
|
|
1320
1438
|
|
|
1321
1439
|
### App Intelligence
|
|
@@ -11,6 +11,164 @@ import { EnyoNotificationCategory, EnyoNotificationCategoryRegistration, EnyoNot
|
|
|
11
11
|
* The host may additionally enforce rate limits per category. When the limit
|
|
12
12
|
* is exceeded, {@link sendNotification} fails with a `rate-limit` error and
|
|
13
13
|
* the caller must back off before retrying.
|
|
14
|
+
*
|
|
15
|
+
* ## Sending a `charging-issue`
|
|
16
|
+
*
|
|
17
|
+
* The host relies on these rules and does not re-check them, so every app
|
|
18
|
+
* must send a `charging-issue` under the same conditions.
|
|
19
|
+
*
|
|
20
|
+
* Send it only when **all** of the following hold:
|
|
21
|
+
* - The app itself asked the charger to charge: it sent a start or resume,
|
|
22
|
+
* or it is giving the charger more than 0 W of available power.
|
|
23
|
+
* - The charger has stayed non-charging for at least 5 minutes after that
|
|
24
|
+
* request. Non-charging means its status is not
|
|
25
|
+
* {@link EnyoChargerApplianceStatusEnum.Charging}, or it is `Charging` but
|
|
26
|
+
* draws (almost) no power.
|
|
27
|
+
* - The car is not the one holding the charge: do **not** send while the
|
|
28
|
+
* charger reports {@link EnyoChargerApplianceStatusEnum.Suspended} with
|
|
29
|
+
* reason {@link EnyoChargerApplianceSuspendedReasonEnum.Ev}. That means the
|
|
30
|
+
* car's battery is full or the car paused charging itself, which is not a
|
|
31
|
+
* fault.
|
|
32
|
+
* - No grid-operator limit (§14a /
|
|
33
|
+
* {@link EnyoDataBusMessageEnum.GridOperatorPowerLimitationV1}) is
|
|
34
|
+
* currently pushing the charger to 0.
|
|
35
|
+
*
|
|
36
|
+
* Send it **at most once per plug-in**: after sending, wait until the car is
|
|
37
|
+
* unplugged ({@link EnyoChargerApplianceStatusEnum.Available}) before sending
|
|
38
|
+
* again for that appliance.
|
|
39
|
+
*
|
|
40
|
+
* Always pass `options.applianceId` and
|
|
41
|
+
* `options.target = { type: 'appliance', applianceId }`.
|
|
42
|
+
*
|
|
43
|
+
* The host enforces a rate limit of one `charging-issue` per appliance per
|
|
44
|
+
* 30 minutes. A notification sent within that window is dropped and the call
|
|
45
|
+
* fails with a `rate-limit` error.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const notification = sdk.useNotification();
|
|
50
|
+
*
|
|
51
|
+
* notification.registerNotificationCategory({
|
|
52
|
+
* category: 'charging-issue',
|
|
53
|
+
* name: [
|
|
54
|
+
* {language: 'de', name: 'Ladeprobleme'},
|
|
55
|
+
* {language: 'en', name: 'Charging issues'},
|
|
56
|
+
* ],
|
|
57
|
+
* description: [
|
|
58
|
+
* {language: 'de', name: 'Ladeprobleme', description: 'Wenn dein Auto nicht lädt, obwohl es laden sollte.'},
|
|
59
|
+
* {language: 'en', name: 'Charging issues', description: 'When your car is not charging although it should.'},
|
|
60
|
+
* ],
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* notification.sendNotification(
|
|
64
|
+
* 'charging-issue',
|
|
65
|
+
* {applianceId, target: {type: 'appliance', applianceId}},
|
|
66
|
+
* [
|
|
67
|
+
* {language: 'de', title: 'Dein Auto lädt nicht', body: 'Die Wallbox sollte gerade laden, tut es aber nicht. Prüfe bitte Auto und Ladekabel.'},
|
|
68
|
+
* {language: 'en', title: 'Your car is not charging', body: 'The wallbox should be charging right now but isn\'t. Please check the car and the charging cable.'},
|
|
69
|
+
* ],
|
|
70
|
+
* );
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* ## Sending a `battery-issue`
|
|
74
|
+
*
|
|
75
|
+
* Send it only when **all** of the following hold:
|
|
76
|
+
* - The app itself commanded the battery: it sent a
|
|
77
|
+
* {@link EnyoDataBusMessageEnum.SetStorageControlV2} with mode `Controlled`
|
|
78
|
+
* (or one of the `Start…`/`SetStorage…` storage commands) that is still in
|
|
79
|
+
* effect. Never send while the battery runs on its own logic (`Auto`).
|
|
80
|
+
* - For at least 5 minutes after that command, the battery has not followed
|
|
81
|
+
* it, judged by `batteryPowerW` in
|
|
82
|
+
* {@link EnyoDataBusMessageEnum.BatteryValuesUpdateV1}:
|
|
83
|
+
* - `Charge`: the battery is not charging, or charges at (almost) 0 W.
|
|
84
|
+
* - `Discharge`: the battery is not discharging, or discharges at
|
|
85
|
+
* (almost) 0 W.
|
|
86
|
+
* - `Hold`: the battery charges or discharges noticeably.
|
|
87
|
+
* - The battery is not simply at its limit: do **not** send for a charge
|
|
88
|
+
* command while the state of charge is at or above
|
|
89
|
+
* {@link EnyoBatteryApplianceMetadata.maxSoC} (or 100 %), or for a
|
|
90
|
+
* discharge command while it is at or below
|
|
91
|
+
* {@link EnyoBatteryApplianceMetadata.minSoC}.
|
|
92
|
+
* - A discharge to the house is not capped by low household consumption.
|
|
93
|
+
* Without grid discharging, the battery can only deliver what the house
|
|
94
|
+
* draws, which is not a fault.
|
|
95
|
+
* - No grid-operator limit (§14a / `gridOperatorLimit` in
|
|
96
|
+
* `BatteryValuesUpdateV1`, or
|
|
97
|
+
* {@link EnyoDataBusMessageEnum.GridOperatorPowerLimitationV1}) is
|
|
98
|
+
* currently pushing the battery's power to 0.
|
|
99
|
+
* - Control is allowed: {@link EnyoBatteryApplianceMetadata.controlAllowed}
|
|
100
|
+
* is not `false`. (The app must not command such a battery at all.)
|
|
101
|
+
*
|
|
102
|
+
* Send it **at most once per issue**: after sending, wait until the battery
|
|
103
|
+
* follows a command again, or the app releases it back to `Auto`, before
|
|
104
|
+
* sending again for that appliance.
|
|
105
|
+
*
|
|
106
|
+
* Always pass `options.applianceId` and
|
|
107
|
+
* `options.target = { type: 'appliance', applianceId }`.
|
|
108
|
+
*
|
|
109
|
+
* The host enforces a rate limit of one `battery-issue` per appliance per
|
|
110
|
+
* 30 minutes. A notification sent within that window is dropped and the call
|
|
111
|
+
* fails with a `rate-limit` error.
|
|
112
|
+
*
|
|
113
|
+
* ## Sending an `authentication-required`
|
|
114
|
+
*
|
|
115
|
+
* {@link EnergyAppAuthentication.requestAuthentication} already prompts the
|
|
116
|
+
* user, including for the first sign-in during onboarding. This category is
|
|
117
|
+
* only for a sign-in that **used to work** and was lost.
|
|
118
|
+
*
|
|
119
|
+
* Send it only when **all** of the following hold:
|
|
120
|
+
* - The package was authenticated before
|
|
121
|
+
* ({@link EnyoAuthenticationStateEnum.Authenticated}) and the session is now
|
|
122
|
+
* unusable: the vendor rejects the credentials or token, and a refresh (if
|
|
123
|
+
* the vendor supports one) failed.
|
|
124
|
+
* - The failure is not transient. Timeouts, 5xx responses or the vendor cloud
|
|
125
|
+
* being down are a `connection-issue`, not an `authentication-required`.
|
|
126
|
+
* - The user did not sign out themselves: do **not** send after
|
|
127
|
+
* {@link EnergyAppAuthentication.signOut} or a sign-out reported through
|
|
128
|
+
* {@link EnergyAppAuthentication.listenForSignOut}.
|
|
129
|
+
*
|
|
130
|
+
* Before sending, set the state via
|
|
131
|
+
* {@link EnergyAppAuthentication.setAuthenticationState} (to
|
|
132
|
+
* `AuthenticationFailed` or `Unauthenticated`) and create a new request via
|
|
133
|
+
* {@link EnergyAppAuthentication.requestAuthentication}, so the target has a
|
|
134
|
+
* sign-in to open.
|
|
135
|
+
*
|
|
136
|
+
* Send it **at most once per lost session**: after sending, wait until the
|
|
137
|
+
* package is `Authenticated` again before sending another one.
|
|
138
|
+
*
|
|
139
|
+
* Pass `options.target = { type: 'authentication' }`. For an appliance
|
|
140
|
+
* sign-in, also pass `options.applianceId` and set the target's
|
|
141
|
+
* `applianceId`.
|
|
142
|
+
*
|
|
143
|
+
* The host enforces a rate limit of one `authentication-required` per
|
|
144
|
+
* package (or per appliance, for an appliance sign-in) per 24 hours.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const notification = sdk.useNotification();
|
|
149
|
+
* const auth = sdk.useAuthentication();
|
|
150
|
+
*
|
|
151
|
+
* notification.registerNotificationCategory({
|
|
152
|
+
* category: 'authentication-required',
|
|
153
|
+
* name: [
|
|
154
|
+
* {language: 'de', name: 'Anmeldung erforderlich'},
|
|
155
|
+
* {language: 'en', name: 'Sign-in required'},
|
|
156
|
+
* ],
|
|
157
|
+
* });
|
|
158
|
+
*
|
|
159
|
+
* // The vendor rejected the refresh token: the session is gone for good.
|
|
160
|
+
* await auth.setAuthenticationState({state: EnyoAuthenticationStateEnum.AuthenticationFailed});
|
|
161
|
+
* await auth.requestAuthentication({authenticationType: 'oauth', oauth: {}, oneTimeAuthentication: false});
|
|
162
|
+
*
|
|
163
|
+
* notification.sendNotification(
|
|
164
|
+
* 'authentication-required',
|
|
165
|
+
* {target: {type: 'authentication'}},
|
|
166
|
+
* [
|
|
167
|
+
* {language: 'de', title: 'Bitte erneut anmelden', body: 'Deine Anmeldung ist abgelaufen. Melde dich erneut an, damit wir deine Geräte weiter steuern können.'},
|
|
168
|
+
* {language: 'en', title: 'Please sign in again', body: 'Your sign-in has expired. Sign in again so we can keep controlling your devices.'},
|
|
169
|
+
* ],
|
|
170
|
+
* );
|
|
171
|
+
* ```
|
|
14
172
|
*/
|
|
15
173
|
export interface EnergyAppNotification {
|
|
16
174
|
/**
|
|
@@ -44,9 +202,13 @@ export interface EnergyAppNotification {
|
|
|
44
202
|
* `title` (used for list rows and system banners) and a `body` (used in
|
|
45
203
|
* the expanded detail view). When `options.target` is provided, the host
|
|
46
204
|
* routes the user to that destination on interaction — e.g. an onboarding
|
|
47
|
-
* guide for the `onboarding-required` category
|
|
205
|
+
* guide for the `onboarding-required` category, or the appliance's live
|
|
206
|
+
* view (`{ type: 'appliance', applianceId }`) for `charging-issue` and
|
|
207
|
+
* `battery-issue`, or the pending sign-in (`{ type: 'authentication' }`)
|
|
208
|
+
* for `authentication-required`. The "Sending a …" sections on
|
|
209
|
+
* {@link EnergyAppNotification} describe when those categories may be
|
|
210
|
+
* sent.
|
|
48
211
|
*
|
|
49
|
-
* @param type - Visual style of the notification (info, warning, error, success).
|
|
50
212
|
* @param category - Lifecycle category; must be registered beforehand.
|
|
51
213
|
* @param options - Display/behavior options, including optional routing target.
|
|
52
214
|
* @param translations - Per-language `title`/`body` pairs.
|
|
@@ -12,8 +12,19 @@ import { EnergyAppPackageLanguage } from "../energy-app-package-definition.cjs";
|
|
|
12
12
|
* an appliance, gateway, or upstream service that requires user attention.
|
|
13
13
|
* - `onboarding-required`: The package needs the user to complete (or revisit)
|
|
14
14
|
* an onboarding flow before it can continue operating normally.
|
|
15
|
+
* - `charging-issue`: The app expected an appliance to charge — it sent a
|
|
16
|
+
* start or resume, gave the charger power, or scheduled a charge — but the
|
|
17
|
+
* appliance is not charging. See "Sending a `charging-issue`" on
|
|
18
|
+
* {@link EnergyAppNotification} for when to send it.
|
|
19
|
+
* - `battery-issue`: The app commanded a battery to charge, discharge or hold,
|
|
20
|
+
* but the battery is not following the command. See "Sending a
|
|
21
|
+
* `battery-issue`" on {@link EnergyAppNotification} for when to send it.
|
|
22
|
+
* - `authentication-required`: A sign-in that used to work was lost (expired
|
|
23
|
+
* or revoked) and the user has to sign in again before the package can
|
|
24
|
+
* continue. See "Sending an `authentication-required`" on
|
|
25
|
+
* {@link EnergyAppNotification} for when to send it.
|
|
15
26
|
*/
|
|
16
|
-
export type EnyoNotificationCategory = 'connection-issue' | 'onboarding-required';
|
|
27
|
+
export type EnyoNotificationCategory = 'connection-issue' | 'onboarding-required' | 'charging-issue' | 'battery-issue' | 'authentication-required';
|
|
17
28
|
/**
|
|
18
29
|
* Registration payload describing a notification category to the host.
|
|
19
30
|
*
|
|
@@ -45,7 +56,7 @@ export interface EnyoNotificationCategoryTranslation {
|
|
|
45
56
|
* they interact with a notification. Discriminated by the `type` field so
|
|
46
57
|
* additional target kinds can be added without breaking existing consumers.
|
|
47
58
|
*/
|
|
48
|
-
export type EnyoNotificationTarget = EnyoNotificationOnboardingTarget | EnyoNotificationEnergyAppSettingsTarget | EnyoNotificationApplianceSettingsTarget | EnyoNotificationSubscriptionOfferTarget;
|
|
59
|
+
export type EnyoNotificationTarget = EnyoNotificationOnboardingTarget | EnyoNotificationEnergyAppSettingsTarget | EnyoNotificationApplianceSettingsTarget | EnyoNotificationSubscriptionOfferTarget | EnyoNotificationApplianceTarget | EnyoNotificationAuthenticationTarget;
|
|
49
60
|
/**
|
|
50
61
|
* Target that opens an onboarding guide previously registered with the host.
|
|
51
62
|
*
|
|
@@ -73,6 +84,9 @@ export interface EnyoNotificationEnergyAppSettingsTarget {
|
|
|
73
84
|
/**
|
|
74
85
|
* Target that opens the settings screen for a specific appliance managed by
|
|
75
86
|
* the energy app package.
|
|
87
|
+
*
|
|
88
|
+
* To show the appliance's live state instead (e.g. for a `charging-issue`),
|
|
89
|
+
* use {@link EnyoNotificationApplianceTarget}.
|
|
76
90
|
*/
|
|
77
91
|
export interface EnyoNotificationApplianceSettingsTarget {
|
|
78
92
|
/** Discriminator identifying this as an appliance settings target. */
|
|
@@ -83,6 +97,42 @@ export interface EnyoNotificationApplianceSettingsTarget {
|
|
|
83
97
|
*/
|
|
84
98
|
applianceId: string;
|
|
85
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Target that opens the live view of a specific appliance (its current
|
|
102
|
+
* state, power and session), as opposed to its settings screen.
|
|
103
|
+
*
|
|
104
|
+
* This is the target to use for `charging-issue` and `battery-issue`
|
|
105
|
+
* notifications.
|
|
106
|
+
*/
|
|
107
|
+
export interface EnyoNotificationApplianceTarget {
|
|
108
|
+
/** Discriminator identifying this as an appliance target. */
|
|
109
|
+
type: 'appliance';
|
|
110
|
+
/**
|
|
111
|
+
* Identifier of the appliance to open. Must match an appliance id known
|
|
112
|
+
* to the host.
|
|
113
|
+
*/
|
|
114
|
+
applianceId: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Target that opens the package's pending sign-in, i.e. the authentication
|
|
118
|
+
* request previously created via
|
|
119
|
+
* {@link EnergyAppAuthentication.requestAuthentication}.
|
|
120
|
+
*
|
|
121
|
+
* This is the target to use for `authentication-required` notifications.
|
|
122
|
+
* Create the authentication request before sending the notification, so that
|
|
123
|
+
* there is a sign-in for the host to open.
|
|
124
|
+
*/
|
|
125
|
+
export interface EnyoNotificationAuthenticationTarget {
|
|
126
|
+
/** Discriminator identifying this as an authentication target. */
|
|
127
|
+
type: 'authentication';
|
|
128
|
+
/**
|
|
129
|
+
* Identifier of the appliance the sign-in belongs to. Set it when the
|
|
130
|
+
* authentication request was created for a specific appliance
|
|
131
|
+
* ({@link EnyoAuthentication.applianceId}); omit it for a package-wide
|
|
132
|
+
* sign-in.
|
|
133
|
+
*/
|
|
134
|
+
applianceId?: string;
|
|
135
|
+
}
|
|
86
136
|
/**
|
|
87
137
|
* Target that opens enyo's offer screen for one of the package's
|
|
88
138
|
* subscription plans, from where the user can buy it.
|
|
@@ -136,6 +186,9 @@ export interface EnyoNotificationTranslation {
|
|
|
136
186
|
* host via {@link EnergyAppNotification.registerNotificationCategory}.
|
|
137
187
|
* - `rate-limit`: The package has exceeded the host's notification rate
|
|
138
188
|
* limit for the supplied category and must back off before retrying.
|
|
189
|
+
* For `charging-issue` and `battery-issue` the limit is one notification
|
|
190
|
+
* per appliance per 30 minutes; for `authentication-required` it is one
|
|
191
|
+
* per package (or per appliance, for an appliance sign-in) per 24 hours.
|
|
139
192
|
*/
|
|
140
193
|
export type EnyoNotificationSendErrorType = 'not-registered' | 'rate-limit';
|
|
141
194
|
/**
|
package/dist/cjs/version.cjs
CHANGED
|
@@ -9,7 +9,7 @@ exports.getSdkVersion = getSdkVersion;
|
|
|
9
9
|
/**
|
|
10
10
|
* Current version of the enyo Energy App SDK.
|
|
11
11
|
*/
|
|
12
|
-
exports.SDK_VERSION = '1.
|
|
12
|
+
exports.SDK_VERSION = '1.39.0';
|
|
13
13
|
/**
|
|
14
14
|
* Gets the current SDK version.
|
|
15
15
|
* @returns The semantic version string of the SDK
|
package/dist/cjs/version.d.cts
CHANGED
|
@@ -11,6 +11,164 @@ import { EnyoNotificationCategory, EnyoNotificationCategoryRegistration, EnyoNot
|
|
|
11
11
|
* The host may additionally enforce rate limits per category. When the limit
|
|
12
12
|
* is exceeded, {@link sendNotification} fails with a `rate-limit` error and
|
|
13
13
|
* the caller must back off before retrying.
|
|
14
|
+
*
|
|
15
|
+
* ## Sending a `charging-issue`
|
|
16
|
+
*
|
|
17
|
+
* The host relies on these rules and does not re-check them, so every app
|
|
18
|
+
* must send a `charging-issue` under the same conditions.
|
|
19
|
+
*
|
|
20
|
+
* Send it only when **all** of the following hold:
|
|
21
|
+
* - The app itself asked the charger to charge: it sent a start or resume,
|
|
22
|
+
* or it is giving the charger more than 0 W of available power.
|
|
23
|
+
* - The charger has stayed non-charging for at least 5 minutes after that
|
|
24
|
+
* request. Non-charging means its status is not
|
|
25
|
+
* {@link EnyoChargerApplianceStatusEnum.Charging}, or it is `Charging` but
|
|
26
|
+
* draws (almost) no power.
|
|
27
|
+
* - The car is not the one holding the charge: do **not** send while the
|
|
28
|
+
* charger reports {@link EnyoChargerApplianceStatusEnum.Suspended} with
|
|
29
|
+
* reason {@link EnyoChargerApplianceSuspendedReasonEnum.Ev}. That means the
|
|
30
|
+
* car's battery is full or the car paused charging itself, which is not a
|
|
31
|
+
* fault.
|
|
32
|
+
* - No grid-operator limit (§14a /
|
|
33
|
+
* {@link EnyoDataBusMessageEnum.GridOperatorPowerLimitationV1}) is
|
|
34
|
+
* currently pushing the charger to 0.
|
|
35
|
+
*
|
|
36
|
+
* Send it **at most once per plug-in**: after sending, wait until the car is
|
|
37
|
+
* unplugged ({@link EnyoChargerApplianceStatusEnum.Available}) before sending
|
|
38
|
+
* again for that appliance.
|
|
39
|
+
*
|
|
40
|
+
* Always pass `options.applianceId` and
|
|
41
|
+
* `options.target = { type: 'appliance', applianceId }`.
|
|
42
|
+
*
|
|
43
|
+
* The host enforces a rate limit of one `charging-issue` per appliance per
|
|
44
|
+
* 30 minutes. A notification sent within that window is dropped and the call
|
|
45
|
+
* fails with a `rate-limit` error.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const notification = sdk.useNotification();
|
|
50
|
+
*
|
|
51
|
+
* notification.registerNotificationCategory({
|
|
52
|
+
* category: 'charging-issue',
|
|
53
|
+
* name: [
|
|
54
|
+
* {language: 'de', name: 'Ladeprobleme'},
|
|
55
|
+
* {language: 'en', name: 'Charging issues'},
|
|
56
|
+
* ],
|
|
57
|
+
* description: [
|
|
58
|
+
* {language: 'de', name: 'Ladeprobleme', description: 'Wenn dein Auto nicht lädt, obwohl es laden sollte.'},
|
|
59
|
+
* {language: 'en', name: 'Charging issues', description: 'When your car is not charging although it should.'},
|
|
60
|
+
* ],
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* notification.sendNotification(
|
|
64
|
+
* 'charging-issue',
|
|
65
|
+
* {applianceId, target: {type: 'appliance', applianceId}},
|
|
66
|
+
* [
|
|
67
|
+
* {language: 'de', title: 'Dein Auto lädt nicht', body: 'Die Wallbox sollte gerade laden, tut es aber nicht. Prüfe bitte Auto und Ladekabel.'},
|
|
68
|
+
* {language: 'en', title: 'Your car is not charging', body: 'The wallbox should be charging right now but isn\'t. Please check the car and the charging cable.'},
|
|
69
|
+
* ],
|
|
70
|
+
* );
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* ## Sending a `battery-issue`
|
|
74
|
+
*
|
|
75
|
+
* Send it only when **all** of the following hold:
|
|
76
|
+
* - The app itself commanded the battery: it sent a
|
|
77
|
+
* {@link EnyoDataBusMessageEnum.SetStorageControlV2} with mode `Controlled`
|
|
78
|
+
* (or one of the `Start…`/`SetStorage…` storage commands) that is still in
|
|
79
|
+
* effect. Never send while the battery runs on its own logic (`Auto`).
|
|
80
|
+
* - For at least 5 minutes after that command, the battery has not followed
|
|
81
|
+
* it, judged by `batteryPowerW` in
|
|
82
|
+
* {@link EnyoDataBusMessageEnum.BatteryValuesUpdateV1}:
|
|
83
|
+
* - `Charge`: the battery is not charging, or charges at (almost) 0 W.
|
|
84
|
+
* - `Discharge`: the battery is not discharging, or discharges at
|
|
85
|
+
* (almost) 0 W.
|
|
86
|
+
* - `Hold`: the battery charges or discharges noticeably.
|
|
87
|
+
* - The battery is not simply at its limit: do **not** send for a charge
|
|
88
|
+
* command while the state of charge is at or above
|
|
89
|
+
* {@link EnyoBatteryApplianceMetadata.maxSoC} (or 100 %), or for a
|
|
90
|
+
* discharge command while it is at or below
|
|
91
|
+
* {@link EnyoBatteryApplianceMetadata.minSoC}.
|
|
92
|
+
* - A discharge to the house is not capped by low household consumption.
|
|
93
|
+
* Without grid discharging, the battery can only deliver what the house
|
|
94
|
+
* draws, which is not a fault.
|
|
95
|
+
* - No grid-operator limit (§14a / `gridOperatorLimit` in
|
|
96
|
+
* `BatteryValuesUpdateV1`, or
|
|
97
|
+
* {@link EnyoDataBusMessageEnum.GridOperatorPowerLimitationV1}) is
|
|
98
|
+
* currently pushing the battery's power to 0.
|
|
99
|
+
* - Control is allowed: {@link EnyoBatteryApplianceMetadata.controlAllowed}
|
|
100
|
+
* is not `false`. (The app must not command such a battery at all.)
|
|
101
|
+
*
|
|
102
|
+
* Send it **at most once per issue**: after sending, wait until the battery
|
|
103
|
+
* follows a command again, or the app releases it back to `Auto`, before
|
|
104
|
+
* sending again for that appliance.
|
|
105
|
+
*
|
|
106
|
+
* Always pass `options.applianceId` and
|
|
107
|
+
* `options.target = { type: 'appliance', applianceId }`.
|
|
108
|
+
*
|
|
109
|
+
* The host enforces a rate limit of one `battery-issue` per appliance per
|
|
110
|
+
* 30 minutes. A notification sent within that window is dropped and the call
|
|
111
|
+
* fails with a `rate-limit` error.
|
|
112
|
+
*
|
|
113
|
+
* ## Sending an `authentication-required`
|
|
114
|
+
*
|
|
115
|
+
* {@link EnergyAppAuthentication.requestAuthentication} already prompts the
|
|
116
|
+
* user, including for the first sign-in during onboarding. This category is
|
|
117
|
+
* only for a sign-in that **used to work** and was lost.
|
|
118
|
+
*
|
|
119
|
+
* Send it only when **all** of the following hold:
|
|
120
|
+
* - The package was authenticated before
|
|
121
|
+
* ({@link EnyoAuthenticationStateEnum.Authenticated}) and the session is now
|
|
122
|
+
* unusable: the vendor rejects the credentials or token, and a refresh (if
|
|
123
|
+
* the vendor supports one) failed.
|
|
124
|
+
* - The failure is not transient. Timeouts, 5xx responses or the vendor cloud
|
|
125
|
+
* being down are a `connection-issue`, not an `authentication-required`.
|
|
126
|
+
* - The user did not sign out themselves: do **not** send after
|
|
127
|
+
* {@link EnergyAppAuthentication.signOut} or a sign-out reported through
|
|
128
|
+
* {@link EnergyAppAuthentication.listenForSignOut}.
|
|
129
|
+
*
|
|
130
|
+
* Before sending, set the state via
|
|
131
|
+
* {@link EnergyAppAuthentication.setAuthenticationState} (to
|
|
132
|
+
* `AuthenticationFailed` or `Unauthenticated`) and create a new request via
|
|
133
|
+
* {@link EnergyAppAuthentication.requestAuthentication}, so the target has a
|
|
134
|
+
* sign-in to open.
|
|
135
|
+
*
|
|
136
|
+
* Send it **at most once per lost session**: after sending, wait until the
|
|
137
|
+
* package is `Authenticated` again before sending another one.
|
|
138
|
+
*
|
|
139
|
+
* Pass `options.target = { type: 'authentication' }`. For an appliance
|
|
140
|
+
* sign-in, also pass `options.applianceId` and set the target's
|
|
141
|
+
* `applianceId`.
|
|
142
|
+
*
|
|
143
|
+
* The host enforces a rate limit of one `authentication-required` per
|
|
144
|
+
* package (or per appliance, for an appliance sign-in) per 24 hours.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const notification = sdk.useNotification();
|
|
149
|
+
* const auth = sdk.useAuthentication();
|
|
150
|
+
*
|
|
151
|
+
* notification.registerNotificationCategory({
|
|
152
|
+
* category: 'authentication-required',
|
|
153
|
+
* name: [
|
|
154
|
+
* {language: 'de', name: 'Anmeldung erforderlich'},
|
|
155
|
+
* {language: 'en', name: 'Sign-in required'},
|
|
156
|
+
* ],
|
|
157
|
+
* });
|
|
158
|
+
*
|
|
159
|
+
* // The vendor rejected the refresh token: the session is gone for good.
|
|
160
|
+
* await auth.setAuthenticationState({state: EnyoAuthenticationStateEnum.AuthenticationFailed});
|
|
161
|
+
* await auth.requestAuthentication({authenticationType: 'oauth', oauth: {}, oneTimeAuthentication: false});
|
|
162
|
+
*
|
|
163
|
+
* notification.sendNotification(
|
|
164
|
+
* 'authentication-required',
|
|
165
|
+
* {target: {type: 'authentication'}},
|
|
166
|
+
* [
|
|
167
|
+
* {language: 'de', title: 'Bitte erneut anmelden', body: 'Deine Anmeldung ist abgelaufen. Melde dich erneut an, damit wir deine Geräte weiter steuern können.'},
|
|
168
|
+
* {language: 'en', title: 'Please sign in again', body: 'Your sign-in has expired. Sign in again so we can keep controlling your devices.'},
|
|
169
|
+
* ],
|
|
170
|
+
* );
|
|
171
|
+
* ```
|
|
14
172
|
*/
|
|
15
173
|
export interface EnergyAppNotification {
|
|
16
174
|
/**
|
|
@@ -44,9 +202,13 @@ export interface EnergyAppNotification {
|
|
|
44
202
|
* `title` (used for list rows and system banners) and a `body` (used in
|
|
45
203
|
* the expanded detail view). When `options.target` is provided, the host
|
|
46
204
|
* routes the user to that destination on interaction — e.g. an onboarding
|
|
47
|
-
* guide for the `onboarding-required` category
|
|
205
|
+
* guide for the `onboarding-required` category, or the appliance's live
|
|
206
|
+
* view (`{ type: 'appliance', applianceId }`) for `charging-issue` and
|
|
207
|
+
* `battery-issue`, or the pending sign-in (`{ type: 'authentication' }`)
|
|
208
|
+
* for `authentication-required`. The "Sending a …" sections on
|
|
209
|
+
* {@link EnergyAppNotification} describe when those categories may be
|
|
210
|
+
* sent.
|
|
48
211
|
*
|
|
49
|
-
* @param type - Visual style of the notification (info, warning, error, success).
|
|
50
212
|
* @param category - Lifecycle category; must be registered beforehand.
|
|
51
213
|
* @param options - Display/behavior options, including optional routing target.
|
|
52
214
|
* @param translations - Per-language `title`/`body` pairs.
|
|
@@ -12,8 +12,19 @@ import { EnergyAppPackageLanguage } from "../energy-app-package-definition.js";
|
|
|
12
12
|
* an appliance, gateway, or upstream service that requires user attention.
|
|
13
13
|
* - `onboarding-required`: The package needs the user to complete (or revisit)
|
|
14
14
|
* an onboarding flow before it can continue operating normally.
|
|
15
|
+
* - `charging-issue`: The app expected an appliance to charge — it sent a
|
|
16
|
+
* start or resume, gave the charger power, or scheduled a charge — but the
|
|
17
|
+
* appliance is not charging. See "Sending a `charging-issue`" on
|
|
18
|
+
* {@link EnergyAppNotification} for when to send it.
|
|
19
|
+
* - `battery-issue`: The app commanded a battery to charge, discharge or hold,
|
|
20
|
+
* but the battery is not following the command. See "Sending a
|
|
21
|
+
* `battery-issue`" on {@link EnergyAppNotification} for when to send it.
|
|
22
|
+
* - `authentication-required`: A sign-in that used to work was lost (expired
|
|
23
|
+
* or revoked) and the user has to sign in again before the package can
|
|
24
|
+
* continue. See "Sending an `authentication-required`" on
|
|
25
|
+
* {@link EnergyAppNotification} for when to send it.
|
|
15
26
|
*/
|
|
16
|
-
export type EnyoNotificationCategory = 'connection-issue' | 'onboarding-required';
|
|
27
|
+
export type EnyoNotificationCategory = 'connection-issue' | 'onboarding-required' | 'charging-issue' | 'battery-issue' | 'authentication-required';
|
|
17
28
|
/**
|
|
18
29
|
* Registration payload describing a notification category to the host.
|
|
19
30
|
*
|
|
@@ -45,7 +56,7 @@ export interface EnyoNotificationCategoryTranslation {
|
|
|
45
56
|
* they interact with a notification. Discriminated by the `type` field so
|
|
46
57
|
* additional target kinds can be added without breaking existing consumers.
|
|
47
58
|
*/
|
|
48
|
-
export type EnyoNotificationTarget = EnyoNotificationOnboardingTarget | EnyoNotificationEnergyAppSettingsTarget | EnyoNotificationApplianceSettingsTarget | EnyoNotificationSubscriptionOfferTarget;
|
|
59
|
+
export type EnyoNotificationTarget = EnyoNotificationOnboardingTarget | EnyoNotificationEnergyAppSettingsTarget | EnyoNotificationApplianceSettingsTarget | EnyoNotificationSubscriptionOfferTarget | EnyoNotificationApplianceTarget | EnyoNotificationAuthenticationTarget;
|
|
49
60
|
/**
|
|
50
61
|
* Target that opens an onboarding guide previously registered with the host.
|
|
51
62
|
*
|
|
@@ -73,6 +84,9 @@ export interface EnyoNotificationEnergyAppSettingsTarget {
|
|
|
73
84
|
/**
|
|
74
85
|
* Target that opens the settings screen for a specific appliance managed by
|
|
75
86
|
* the energy app package.
|
|
87
|
+
*
|
|
88
|
+
* To show the appliance's live state instead (e.g. for a `charging-issue`),
|
|
89
|
+
* use {@link EnyoNotificationApplianceTarget}.
|
|
76
90
|
*/
|
|
77
91
|
export interface EnyoNotificationApplianceSettingsTarget {
|
|
78
92
|
/** Discriminator identifying this as an appliance settings target. */
|
|
@@ -83,6 +97,42 @@ export interface EnyoNotificationApplianceSettingsTarget {
|
|
|
83
97
|
*/
|
|
84
98
|
applianceId: string;
|
|
85
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Target that opens the live view of a specific appliance (its current
|
|
102
|
+
* state, power and session), as opposed to its settings screen.
|
|
103
|
+
*
|
|
104
|
+
* This is the target to use for `charging-issue` and `battery-issue`
|
|
105
|
+
* notifications.
|
|
106
|
+
*/
|
|
107
|
+
export interface EnyoNotificationApplianceTarget {
|
|
108
|
+
/** Discriminator identifying this as an appliance target. */
|
|
109
|
+
type: 'appliance';
|
|
110
|
+
/**
|
|
111
|
+
* Identifier of the appliance to open. Must match an appliance id known
|
|
112
|
+
* to the host.
|
|
113
|
+
*/
|
|
114
|
+
applianceId: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Target that opens the package's pending sign-in, i.e. the authentication
|
|
118
|
+
* request previously created via
|
|
119
|
+
* {@link EnergyAppAuthentication.requestAuthentication}.
|
|
120
|
+
*
|
|
121
|
+
* This is the target to use for `authentication-required` notifications.
|
|
122
|
+
* Create the authentication request before sending the notification, so that
|
|
123
|
+
* there is a sign-in for the host to open.
|
|
124
|
+
*/
|
|
125
|
+
export interface EnyoNotificationAuthenticationTarget {
|
|
126
|
+
/** Discriminator identifying this as an authentication target. */
|
|
127
|
+
type: 'authentication';
|
|
128
|
+
/**
|
|
129
|
+
* Identifier of the appliance the sign-in belongs to. Set it when the
|
|
130
|
+
* authentication request was created for a specific appliance
|
|
131
|
+
* ({@link EnyoAuthentication.applianceId}); omit it for a package-wide
|
|
132
|
+
* sign-in.
|
|
133
|
+
*/
|
|
134
|
+
applianceId?: string;
|
|
135
|
+
}
|
|
86
136
|
/**
|
|
87
137
|
* Target that opens enyo's offer screen for one of the package's
|
|
88
138
|
* subscription plans, from where the user can buy it.
|
|
@@ -136,6 +186,9 @@ export interface EnyoNotificationTranslation {
|
|
|
136
186
|
* host via {@link EnergyAppNotification.registerNotificationCategory}.
|
|
137
187
|
* - `rate-limit`: The package has exceeded the host's notification rate
|
|
138
188
|
* limit for the supplied category and must back off before retrying.
|
|
189
|
+
* For `charging-issue` and `battery-issue` the limit is one notification
|
|
190
|
+
* per appliance per 30 minutes; for `authentication-required` it is one
|
|
191
|
+
* per package (or per appliance, for an appliance sign-in) per 24 hours.
|
|
139
192
|
*/
|
|
140
193
|
export type EnyoNotificationSendErrorType = 'not-registered' | 'rate-limit';
|
|
141
194
|
/**
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED