@enyo-energy/energy-app-sdk 0.0.144 → 0.0.145

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.
Files changed (39) hide show
  1. package/dist/cjs/packages/eebus/eebus-cevc-client.d.cts +19 -0
  2. package/dist/cjs/packages/eebus/eebus-device-management.d.cts +26 -1
  3. package/dist/cjs/packages/eebus/eebus-evcc-client.d.cts +53 -1
  4. package/dist/cjs/packages/eebus/eebus-evcem-client.d.cts +8 -0
  5. package/dist/cjs/packages/eebus/eebus-evsoc-client.d.cts +10 -0
  6. package/dist/cjs/packages/eebus/eebus-feature-catalog.d.cts +52 -0
  7. package/dist/cjs/packages/eebus/eebus-lpc-client.d.cts +86 -2
  8. package/dist/cjs/packages/eebus/eebus-mgcp-client.d.cts +10 -0
  9. package/dist/cjs/packages/eebus/eebus-mpc-client.d.cts +43 -1
  10. package/dist/cjs/packages/eebus/eebus-use-case-client.d.cts +50 -17
  11. package/dist/cjs/packages/eebus/eebus-vabd-client.d.cts +11 -0
  12. package/dist/cjs/packages/eebus/eebus-vapd-client.d.cts +8 -0
  13. package/dist/cjs/packages/eebus/energy-app-eebus.d.cts +4 -4
  14. package/dist/cjs/types/enyo-battery-appliance.cjs +18 -4
  15. package/dist/cjs/types/enyo-battery-appliance.d.cts +19 -5
  16. package/dist/cjs/types/enyo-eebus-use-cases.d.cts +148 -0
  17. package/dist/cjs/types/enyo-eebus.d.cts +28 -0
  18. package/dist/cjs/version.cjs +1 -1
  19. package/dist/cjs/version.d.cts +1 -1
  20. package/dist/packages/eebus/eebus-cevc-client.d.ts +19 -0
  21. package/dist/packages/eebus/eebus-device-management.d.ts +26 -1
  22. package/dist/packages/eebus/eebus-evcc-client.d.ts +53 -1
  23. package/dist/packages/eebus/eebus-evcem-client.d.ts +8 -0
  24. package/dist/packages/eebus/eebus-evsoc-client.d.ts +10 -0
  25. package/dist/packages/eebus/eebus-feature-catalog.d.ts +52 -0
  26. package/dist/packages/eebus/eebus-lpc-client.d.ts +86 -2
  27. package/dist/packages/eebus/eebus-mgcp-client.d.ts +10 -0
  28. package/dist/packages/eebus/eebus-mpc-client.d.ts +43 -1
  29. package/dist/packages/eebus/eebus-use-case-client.d.ts +50 -17
  30. package/dist/packages/eebus/eebus-vabd-client.d.ts +11 -0
  31. package/dist/packages/eebus/eebus-vapd-client.d.ts +8 -0
  32. package/dist/packages/eebus/energy-app-eebus.d.ts +4 -4
  33. package/dist/types/enyo-battery-appliance.d.ts +19 -5
  34. package/dist/types/enyo-battery-appliance.js +18 -4
  35. package/dist/types/enyo-eebus-use-cases.d.ts +148 -0
  36. package/dist/types/enyo-eebus.d.ts +28 -0
  37. package/dist/version.d.ts +1 -1
  38. package/dist/version.js +1 -1
  39. package/package.json +1 -1
@@ -60,6 +60,25 @@ export interface EebusCevcClient extends EebusUseCaseClient {
60
60
  * heat pumps. Uses {@link EebusOhpcfIncentiveTable} verbatim.
61
61
  */
62
62
  publishIncentiveTable: (table: EebusOhpcfIncentiveTable) => Promise<void>;
63
+ /**
64
+ * Return the most recent time-series charging plan the SDK has
65
+ * observed on this peer, without dispatching a wire read.
66
+ * Synchronous and side-effect-free.
67
+ *
68
+ * Returns `undefined` until the first plan notify has landed, and
69
+ * will keep returning `undefined` on peers that do not implement
70
+ * `TimeSeries` until that client lands in `@enyo-energy/eebus`.
71
+ */
72
+ getLastTimeSeriesPlan: () => EebusCevcChargingPlan | undefined;
73
+ /**
74
+ * Return the most recent incentive table the SDK has observed on
75
+ * this peer, without dispatching a wire read. Synchronous and
76
+ * side-effect-free.
77
+ *
78
+ * Returns `undefined` until the first `incentiveTableData` notify
79
+ * has landed.
80
+ */
81
+ getLastIncentiveTable: () => EebusOhpcfIncentiveTable | undefined;
63
82
  /**
64
83
  * Subscribe to plan-state updates published by the EV (e.g. revised
65
84
  * plan after the EV revised its capacity estimate).
@@ -1,4 +1,4 @@
1
- import { EebusConnectionStatusEnum, EebusDevice, EebusDiscoveredDevice } from '../../types/enyo-eebus.cjs';
1
+ import { EebusConnectionStatusEnum, EebusDevice, EebusDiscoveredDevice, EebusPeerManufacturerData } from '../../types/enyo-eebus.cjs';
2
2
  /**
3
3
  * SHIP-level device lifecycle management for EEbus devices.
4
4
  *
@@ -62,6 +62,31 @@ export interface EebusDeviceManagement {
62
62
  * @returns The current connection status (Connected, Disconnected, or Connecting)
63
63
  */
64
64
  getConnectionStatus: (ski: string) => Promise<EebusConnectionStatusEnum>;
65
+ /**
66
+ * Read the cached `DeviceClassification.ManufacturerData` payload
67
+ * the peer published after the SHIP handshake — the compact
68
+ * identity record vendor packages need to gate vendor-specific
69
+ * behaviour (e.g. enabling partial LoadControl writes on Vaillant
70
+ * VR940 firmware).
71
+ *
72
+ * Synchronous on the wire — the lib auto-fetches the payload after
73
+ * connect and surfaces the cached value here. Returns:
74
+ * - the populated record once the peer has answered the post-handshake fetch
75
+ * - `null` when the peer is paired but has not answered the fetch yet
76
+ * - `undefined` when the SDK has no record of the peer (never paired or fully forgotten)
77
+ *
78
+ * The async wrapper is preserved for symmetry with the other
79
+ * `EebusDeviceManagement` methods; the result resolves immediately
80
+ * from the cached snapshot.
81
+ *
82
+ * Prefer this over reaching for {@link EebusIdentityService.get}
83
+ * when all you need is vendor sniffing — it avoids waking the full
84
+ * identity pipeline and keeps vendor matching at the consumer
85
+ * boundary.
86
+ *
87
+ * @param ski Subject Key Identifier of the remote node
88
+ */
89
+ getPeerManufacturerData: (ski: string) => Promise<EebusPeerManufacturerData | null | undefined>;
65
90
  /**
66
91
  * Register a listener for connection status changes of EEbus devices.
67
92
  * The listener is invoked whenever any paired device's connection status changes.
@@ -1,5 +1,5 @@
1
1
  import { SpineRemoteTarget } from '../../types/enyo-eebus.cjs';
2
- import { EebusEvCommunicationStandardEnum, EebusEvConnectionState, EebusEvIdentification } from '../../types/enyo-eebus-use-cases.cjs';
2
+ import { EebusEvCommunicationStandardEnum, EebusEvConfigurationSnapshot, EebusEvConnectionState, EebusEvElectricalLimits, EebusEvIdentification } from '../../types/enyo-eebus-use-cases.cjs';
3
3
  import { SpineEntityType } from '../../types/enyo-spine.cjs';
4
4
  import { EebusUseCaseClient } from './eebus-use-case-client.cjs';
5
5
  /**
@@ -48,6 +48,58 @@ export interface EebusEvccClient extends EebusUseCaseClient {
48
48
  * Read whether the EV supports asymmetric (per-phase) charging.
49
49
  */
50
50
  getEvAsymmetricChargingSupport: () => Promise<boolean>;
51
+ /**
52
+ * Return the most recent EV identification (EVCCID + identification
53
+ * type) the SDK has observed on this peer, without dispatching a
54
+ * wire read. Synchronous and side-effect-free.
55
+ *
56
+ * Returns `undefined` until the first `identificationListData`
57
+ * notify has landed.
58
+ */
59
+ getLastEvIdentification: () => EebusEvIdentification | undefined;
60
+ /**
61
+ * Return the most recent `DeviceConfiguration.keyValueListData`
62
+ * snapshot the SDK has observed on this peer. Surfaces every
63
+ * configuration key the EV advertises with its current value;
64
+ * consumers that only need a specific key can use
65
+ * {@link getCommunicationStandard} or
66
+ * {@link supportsAsymmetricCharging} which already narrow the
67
+ * lookup.
68
+ *
69
+ * Returns `undefined` until the first notify has landed.
70
+ */
71
+ getLastEvConfiguration: () => EebusEvConfigurationSnapshot | undefined;
72
+ /**
73
+ * Return the most recent EV electrical permitted-value snapshot the
74
+ * SDK has observed on this peer — per-phase minimum / maximum
75
+ * current and total power the EV reports as allowable.
76
+ *
77
+ * Returns `undefined` until the first
78
+ * `permittedValueSetListData` notify has landed.
79
+ */
80
+ getLastEvElectricalLimits: () => EebusEvElectricalLimits | undefined;
81
+ /**
82
+ * Read the EV's negotiated communication standard from the cached
83
+ * configuration snapshot — `'IEC61851'`, `'ISO15118-2'`,
84
+ * `'ISO15118-20'`, etc. Synchronous; does not hit the wire.
85
+ *
86
+ * Distinct from {@link getEvCommunicationStandard} (async, returns
87
+ * the typed enum) — this getter returns the raw wire string for
88
+ * vendor-specific values the enum doesn't cover, and `undefined`
89
+ * when the key is not yet cached.
90
+ */
91
+ getCommunicationStandard: () => string | undefined;
92
+ /**
93
+ * Read whether the EV advertises asymmetric (per-phase) charging
94
+ * support from the cached configuration snapshot. Synchronous;
95
+ * does not hit the wire.
96
+ *
97
+ * Returns `undefined` when the key is not yet cached (handshake
98
+ * still in progress, or the EV does not publish the key at all).
99
+ * Callers that need a boolean-only answer should treat `undefined`
100
+ * as `false` only after {@link ready} reports the client is bound.
101
+ */
102
+ supportsAsymmetricCharging: () => boolean | undefined;
51
103
  /**
52
104
  * Subscribe to EV-connect events (vehicle plugged in).
53
105
  */
@@ -30,6 +30,14 @@ export interface EebusEvcemClient extends EebusUseCaseClient {
30
30
  * Read the most recent telemetry sample from the EV charging session.
31
31
  */
32
32
  getCurrentMeasurement: () => Promise<EebusEvcemReading>;
33
+ /**
34
+ * Return the most recent telemetry sample the SDK has observed on
35
+ * this peer, without dispatching a wire read. Synchronous and
36
+ * side-effect-free.
37
+ *
38
+ * Returns `undefined` until the first inbound notify has landed.
39
+ */
40
+ getLastMeasurement: () => EebusEvcemReading | undefined;
33
41
  /**
34
42
  * Subscribe to per-update telemetry samples.
35
43
  *
@@ -29,6 +29,16 @@ export interface EebusEvsocClient extends EebusUseCaseClient {
29
29
  * Read the most recent SoC sample, in percent (0–100).
30
30
  */
31
31
  getStateOfChargePercent: () => Promise<number>;
32
+ /**
33
+ * Return the most recent SoC sample the SDK has observed on this
34
+ * peer, without dispatching a wire read. Synchronous and
35
+ * side-effect-free.
36
+ *
37
+ * Returns `undefined` until the first SoC notify has landed — and
38
+ * may stay `undefined` indefinitely on vehicles that do not publish
39
+ * their SoC over EEBUS (see the class-level note).
40
+ */
41
+ getLastStateOfCharge: () => EebusEvSocReading | undefined;
32
42
  /**
33
43
  * Subscribe to SoC updates.
34
44
  *
@@ -1,5 +1,38 @@
1
1
  import { EebusFeatureRole, EebusRemoteFeatureCatalog } from '../../types/enyo-eebus-features.cjs';
2
2
  import { SpineEntityType, SpineFeatureType, SpineFunctionType } from '../../types/enyo-spine.cjs';
3
+ /**
4
+ * Options for {@link EebusFeatureCatalog.findFeatureAddressForClient}.
5
+ *
6
+ * Mirrors the lib's priority-ordered resolver used internally by the
7
+ * typed use-case clients. Consumers that needed to reimplement this
8
+ * resolver (heat pumps that host the same feature type on several
9
+ * entities) can now call into the SDK instead.
10
+ */
11
+ export interface EebusFindFeatureForClientOptions {
12
+ /** SPINE feature type to look up (e.g. `SpineFeatureType.LOAD_CONTROL`). */
13
+ featureType: SpineFeatureType;
14
+ /** SPINE role to match (`'server'` or `'client'`). */
15
+ role: EebusFeatureRole;
16
+ /**
17
+ * Entity types to prefer, in priority order. The resolver picks the
18
+ * first feature found whose host entity matches the earliest entry
19
+ * in this list. Mix {@link SpineEntityType} values with raw wire
20
+ * strings for vendor-specific entity types that pre-date the
21
+ * catalogue.
22
+ *
23
+ * Omit to skip preference-based matching and fall straight back to
24
+ * {@link fallbackToAny}.
25
+ */
26
+ preferredEntityTypes?: Array<SpineEntityType | string>;
27
+ /**
28
+ * When no entity in {@link preferredEntityTypes} hosts the feature,
29
+ * return the first match from any entity instead of resolving to
30
+ * `undefined`. Defaults to `true` — preserves the legacy
31
+ * "first-match-wins" behaviour. Set `false` to force a strict match
32
+ * on {@link preferredEntityTypes}.
33
+ */
34
+ fallbackToAny?: boolean;
35
+ }
3
36
  /**
4
37
  * One match returned by {@link EebusFeatureCatalog.findFeatureAddresses}.
5
38
  *
@@ -137,6 +170,25 @@ export interface EebusFeatureCatalog {
137
170
  * @returns Every matching feature address on the peer, in catalog order
138
171
  */
139
172
  findFeatureAddresses: (ski: string, featureType: SpineFeatureType, role: EebusFeatureRole) => Promise<EebusFeatureAddressMatch[]>;
173
+ /**
174
+ * Resolve a single best-fit feature address for a typed client
175
+ * binding, applying the lib's priority-ordered resolver.
176
+ *
177
+ * Walks {@link findFeatureAddresses} and picks the first match that
178
+ * (a) sits on one of {@link EebusFindFeatureForClientOptions.preferredEntityTypes}
179
+ * in the supplied order, or (b) — when no preferred entity hosts the
180
+ * feature and {@link EebusFindFeatureForClientOptions.fallbackToAny}
181
+ * is `true` (the default) — the first match from any entity.
182
+ *
183
+ * Returns `undefined` when the peer is not connected, when no
184
+ * entity hosts a matching feature, or when
185
+ * `fallbackToAny: false` is set and no entity in the preferred
186
+ * list hosts one.
187
+ *
188
+ * @param ski Subject Key Identifier of the remote node
189
+ * @param opts Match parameters; see {@link EebusFindFeatureForClientOptions}
190
+ */
191
+ findFeatureAddressForClient: (ski: string, opts: EebusFindFeatureForClientOptions) => Promise<EebusFeatureAddressMatch | undefined>;
140
192
  /**
141
193
  * Remove a feature-catalog listener previously registered via
142
194
  * {@link onFeaturesChanged}.
@@ -1,7 +1,56 @@
1
1
  import { SpineRemoteTarget } from '../../types/enyo-eebus.cjs';
2
- import { EebusLpcAck, EebusLpcFailsafe, EebusLpcLimit, EebusLpcNack } from '../../types/enyo-eebus-use-cases.cjs';
2
+ import { EebusLpcAck, EebusLpcFailsafe, EebusLpcLimit, EebusLpcLimitCategory, EebusLpcLimitDescriptor, EebusLpcLimitDirection, EebusLpcNack } from '../../types/enyo-eebus-use-cases.cjs';
3
3
  import { SpineEntityType } from '../../types/enyo-spine.cjs';
4
4
  import { EebusUseCaseClient } from './eebus-use-case-client.cjs';
5
+ /**
6
+ * Options for {@link EebusLpcClient.findLimit} — used to disambiguate
7
+ * peers that advertise more than one LoadControl limit slot.
8
+ */
9
+ export interface FindLpcLimitOptions {
10
+ /**
11
+ * Limit direction to match — `'consume'` for LPC obligations on a
12
+ * controllable load, `'produce'` for production limits on a
13
+ * battery / inverter.
14
+ */
15
+ direction: EebusLpcLimitDirection;
16
+ /**
17
+ * Optional limit category to match. Omit to accept either category
18
+ * (the resolver picks the first match it finds in description-list
19
+ * order). Pin when the peer advertises both an obligation and a
20
+ * recommendation in the same direction.
21
+ */
22
+ category?: EebusLpcLimitCategory;
23
+ }
24
+ /**
25
+ * Options for {@link EebusLpcClient.findPerPhaseLimitIds} — used by EMS
26
+ * code that needs to write per-phase limits (OPEV-style) over the
27
+ * LoadControl feature.
28
+ */
29
+ export interface FindPerPhaseLimitIdsOptions {
30
+ /**
31
+ * Limit category to match — see
32
+ * {@link FindLpcLimitOptions.category}.
33
+ */
34
+ category: EebusLpcLimitCategory;
35
+ }
36
+ /**
37
+ * Options for {@link EebusLpcClient.setConsumptionLimit}.
38
+ */
39
+ export interface SetConsumptionLimitOptions {
40
+ /**
41
+ * When `true`, write the limit as a partial
42
+ * `LoadControlLimitListData` payload (only the addressed limit slot,
43
+ * not the full list). Some non-conformant firmwares — notably
44
+ * Vaillant VR940 — reject the full-list write the spec mandates;
45
+ * partial writes are the only way to push a limit there.
46
+ *
47
+ * Default `false` — the spec-conformant full-list write. Consumers
48
+ * should gate `true` on
49
+ * {@link EebusDeviceManagement.getPeerManufacturerData} so the
50
+ * vendor sniff stays at the consumer boundary.
51
+ */
52
+ partial?: boolean;
53
+ }
5
54
  /**
6
55
  * Per-call configuration for {@link EebusUseCaseRegistry.lpc}.
7
56
  *
@@ -69,9 +118,17 @@ export interface EebusLpcClient extends EebusUseCaseClient {
69
118
  * {@link onConsumptionLimitNack} to observe the CS's downstream
70
119
  * decision.
71
120
  *
121
+ * Pass `{ partial: true }` in {@link options} for peers that only
122
+ * accept partial `LoadControlLimitListData` writes — currently
123
+ * Vaillant VR940 firmware, which rejects the full-list write the
124
+ * SPINE spec mandates. Default is a bare full-list write; consumers
125
+ * should gate `partial: true` on
126
+ * {@link EebusDeviceManagement.getPeerManufacturerData}.
127
+ *
72
128
  * @param limit The consumption limit to apply
129
+ * @param options Optional write-style configuration
73
130
  */
74
- setConsumptionLimit: (limit: EebusLpcLimit) => Promise<void>;
131
+ setConsumptionLimit: (limit: EebusLpcLimit, options?: SetConsumptionLimitOptions) => Promise<void>;
75
132
  /**
76
133
  * Configure the controllable system's failsafe limit — the value it
77
134
  * falls back to when the SHIP connection to this EMS drops. The
@@ -155,4 +212,31 @@ export interface EebusLpcClient extends EebusUseCaseClient {
155
212
  * @param listenerId The ID returned by the registration method
156
213
  */
157
214
  removeListener: (listenerId: string) => void;
215
+ /**
216
+ * Resolve the descriptor for a LoadControl limit slot on the peer,
217
+ * using the SDK's cached `loadControlLimitDescriptionListData`.
218
+ * Synchronous; does not hit the wire.
219
+ *
220
+ * Returns the matching descriptor, or `undefined` when no slot on
221
+ * the resolved entity satisfies the requested
222
+ * {@link FindLpcLimitOptions.direction} (and, when supplied,
223
+ * {@link FindLpcLimitOptions.category}). On peers that advertise
224
+ * several matching slots the resolver returns the first one in
225
+ * description-list order — consumers that need a different slot
226
+ * should use {@link EebusFeatureCatalog.findFeatureAddressForClient}
227
+ * + a per-slot enumeration.
228
+ */
229
+ findLimit: (opts: FindLpcLimitOptions) => EebusLpcLimitDescriptor | undefined;
230
+ /**
231
+ * Resolve the per-phase `limitId`s advertised by the peer for a
232
+ * given limit {@link FindPerPhaseLimitIdsOptions.category}, in
233
+ * phase order (L1, L2, L3). Used by EMS code that pushes per-phase
234
+ * current limits over LoadControl (the OPEV / OSCEV path on
235
+ * wallboxes that don't expose a dedicated OPEV feature).
236
+ *
237
+ * Returns `undefined` when the peer does not advertise per-phase
238
+ * slots for the requested category. Synchronous; does not hit the
239
+ * wire.
240
+ */
241
+ findPerPhaseLimitIds: (opts: FindPerPhaseLimitIdsOptions) => number[] | undefined;
158
242
  }
@@ -16,6 +16,16 @@ export interface EebusMgcpClient extends EebusUseCaseClient {
16
16
  * Read the latest telemetry from the grid connection point.
17
17
  */
18
18
  getReading: () => Promise<EebusMgcpReading>;
19
+ /**
20
+ * Return the most recent reading the SDK has observed on this peer
21
+ * without dispatching a wire read. Synchronous and side-effect-free.
22
+ *
23
+ * Returns `undefined` until the first inbound notify lands.
24
+ * Subsequent notifies update the snapshot — callers that only need
25
+ * to poll the latest value can drop their {@link onReading}
26
+ * subscription in favour of this getter.
27
+ */
28
+ getLastReading: () => EebusMgcpReading | undefined;
19
29
  /**
20
30
  * Subscribe to updates whenever the grid connection point publishes new telemetry.
21
31
  * @param listener Callback invoked with each new reading
@@ -1,7 +1,24 @@
1
1
  import { SpineRemoteTarget } from '../../types/enyo-eebus.cjs';
2
- import { EebusMpcReading } from '../../types/enyo-eebus-use-cases.cjs';
2
+ import { EebusMpcMeasurementDescriptor, EebusMpcReading } from '../../types/enyo-eebus-use-cases.cjs';
3
3
  import { SpineEntityType } from '../../types/enyo-spine.cjs';
4
4
  import { EebusUseCaseClient } from './eebus-use-case-client.cjs';
5
+ /**
6
+ * Options for {@link EebusMpcClient.findMeasurement} — disambiguates
7
+ * peers that advertise more than one measurement slot.
8
+ */
9
+ export interface FindMpcMeasurementOptions {
10
+ /**
11
+ * SPINE scope-type wire string to match (e.g. `'acPowerTotal'`,
12
+ * `'acEnergyConsumed'`). Identifies *what* the slot represents.
13
+ */
14
+ scope: string;
15
+ /**
16
+ * Optional SPINE commodity-type wire string (e.g. `'electricity'`,
17
+ * `'heat'`). Pin when the peer advertises the same scope across
18
+ * commodities — uncommon outside multi-commodity heat-pump peers.
19
+ */
20
+ commodity?: string;
21
+ }
5
22
  /**
6
23
  * Per-call configuration for {@link EebusUseCaseRegistry.mpc}.
7
24
  *
@@ -68,6 +85,18 @@ export interface EebusMpcClient extends EebusUseCaseClient {
68
85
  * Read the latest consumption telemetry from the controllable system.
69
86
  */
70
87
  getReading: () => Promise<EebusMpcReading>;
88
+ /**
89
+ * Return the most recent reading the SDK has observed on this peer
90
+ * without dispatching a wire read. Synchronous and side-effect-free.
91
+ *
92
+ * Returns `undefined` until the first `measurementListData` notify
93
+ * lands after attach (the SPINE binding is in progress, or the peer
94
+ * has not pushed any sample yet). Once populated, the snapshot
95
+ * tracks every subsequent notify — callers do not need to combine
96
+ * this with a manual {@link onReading} subscription unless they
97
+ * want push-style delivery.
98
+ */
99
+ getLastReading: () => EebusMpcReading | undefined;
71
100
  /**
72
101
  * Subscribe to updates whenever the controllable system publishes new telemetry.
73
102
  * @param listener Callback invoked with each new reading
@@ -85,4 +114,17 @@ export interface EebusMpcClient extends EebusUseCaseClient {
85
114
  * @param listenerId The ID returned by the registration method
86
115
  */
87
116
  removeListener: (listenerId: string) => void;
117
+ /**
118
+ * Resolve the descriptor for a Measurement slot on the peer, using
119
+ * the SDK's cached `measurementDescriptionListData`. Synchronous;
120
+ * does not hit the wire.
121
+ *
122
+ * Returns the matching descriptor, or `undefined` when no slot on
123
+ * the resolved entity satisfies the requested
124
+ * {@link FindMpcMeasurementOptions.scope} (and, when supplied,
125
+ * {@link FindMpcMeasurementOptions.commodity}). On peers that
126
+ * advertise several matching slots the resolver returns the first
127
+ * one in description-list order.
128
+ */
129
+ findMeasurement: (opts: FindMpcMeasurementOptions) => EebusMpcMeasurementDescriptor | undefined;
88
130
  }
@@ -1,26 +1,59 @@
1
+ /**
2
+ * Why this peer is (or is not) ready to service calls on a typed use-case
3
+ * client. The shape mirrors the underlying lib's `ready(ski)` probe — the
4
+ * SDK simply surfaces what the lib already keeps cached.
5
+ *
6
+ * The {@link reason} strings are the canonical set the lib publishes; the
7
+ * type widens with `string` so a lib upgrade that adds a new variant does
8
+ * not break consumers that pattern-match on it.
9
+ */
10
+ export interface EebusUseCaseReadiness {
11
+ /**
12
+ * `true` once the SHIP session is live, the peer advertises a
13
+ * compatible entity for this use case, and the SPINE binding +
14
+ * subscription have landed. `false` while any of those preconditions
15
+ * is outstanding.
16
+ */
17
+ ready: boolean;
18
+ /**
19
+ * Why the peer is not yet ready. Populated only when {@link ready}
20
+ * is `false`. The canonical values published by the lib are:
21
+ *
22
+ * - `'no connection for ski'` — no SHIP session for this peer.
23
+ * - `'peer advertises no compatible entity with scenarios for this use case'` —
24
+ * the peer is connected but its `NodeManagement` view does not
25
+ * include an entity that hosts the scenarios this use case needs.
26
+ * - `'peer session not yet bound/subscribed'` — the binding /
27
+ * subscription is still in flight; usually transient (resolves
28
+ * within a couple of seconds of the connection coming up).
29
+ */
30
+ reason?: 'no connection for ski' | 'peer advertises no compatible entity with scenarios for this use case' | 'peer session not yet bound/subscribed' | string;
31
+ }
1
32
  /**
2
33
  * Common shape inherited by every typed EEBUS use-case client.
3
34
  *
4
- * Adding a shared base avoids each client growing its own warm-up
5
- * vocabulary. Today vendor packages trigger the lazy SPINE handshake
6
- * by issuing a fake call (e.g. `onReading(noop)` on
7
- * {@link EebusMpcClient}) just to make the description-list reads
8
- * happen. {@link ready} replaces that ritual with an explicit hook.
35
+ * The lib drives the SPINE binding + description-list reads automatically
36
+ * once a use-case client is created consumers do not have to "warm it
37
+ * up" with a noop call any more. {@link ready} surfaces the lib's cached
38
+ * readiness state so a consumer can answer "is this peer ready for me to
39
+ * use this use case yet?" without firing any wire traffic.
40
+ *
41
+ * The probe is synchronous and side-effect-free: it neither triggers nor
42
+ * waits for the handshake. Call it from a render path, an event handler,
43
+ * or a polling loop without worrying about cost.
9
44
  */
10
45
  export interface EebusUseCaseClient {
11
46
  /**
12
- * Drive the SPINE binding + description-list reads for this
13
- * use-case client to completion without dispatching any real
14
- * read, write, or subscription. Resolves once the handshake has
15
- * landed (or rejects with an {@link EebusFeatureUnavailableError}
16
- * / {@link EebusFeatureNotResolvedError} /
17
- * {@link EebusRequestTimeoutError} if the peer cannot satisfy it
18
- * within the client's configured `descriptionReadTimeoutMs`).
47
+ * Probe the lib's cached readiness state for this use-case client.
48
+ *
49
+ * Returns `{ ready: true }` once the peer is fully bound and
50
+ * subscribed. Returns `{ ready: false, reason }` while any
51
+ * precondition is outstanding — {@link EebusUseCaseReadiness.reason}
52
+ * carries the lib-published explanation so callers can distinguish
53
+ * "peer is offline" from "peer does not support this use case" from
54
+ * "binding is still in flight".
19
55
  *
20
- * Idempotent: subsequent calls resolve as soon as the handshake
21
- * has succeeded once. Safe to call from package start-up to
22
- * surface "peer is not ready" early instead of letting the first
23
- * real call fail later.
56
+ * Synchronous and side-effect-free. Safe to call from hot paths.
24
57
  */
25
- ready: () => Promise<void>;
58
+ ready: () => EebusUseCaseReadiness;
26
59
  }
@@ -42,6 +42,17 @@ export interface EebusVabdClient extends EebusUseCaseClient {
42
42
  * Read the battery's nominal capacity in Watt-hours, if advertised.
43
43
  */
44
44
  getBatteryNominalCapacityWh: () => Promise<number | undefined>;
45
+ /**
46
+ * Return the most recent consolidated battery telemetry the SDK has
47
+ * observed on this peer, without dispatching a wire read.
48
+ * Synchronous and side-effect-free.
49
+ *
50
+ * Returns `undefined` until the first `measurementListData` notify
51
+ * has landed. Once populated, the snapshot tracks every subsequent
52
+ * notify — callers can drop their {@link onTelemetry} subscription
53
+ * if they only need to poll the latest value.
54
+ */
55
+ getLastTelemetry: () => EebusVabdTelemetry | undefined;
45
56
  /**
46
57
  * Subscribe to consolidated battery telemetry updates.
47
58
  */
@@ -36,6 +36,14 @@ export interface EebusVapdClient extends EebusUseCaseClient {
36
36
  * Read the PV system's nominal peak power in Watts, if advertised.
37
37
  */
38
38
  getPvNominalPeakPowerW: () => Promise<number | undefined>;
39
+ /**
40
+ * Return the most recent consolidated PV telemetry the SDK has
41
+ * observed on this peer, without dispatching a wire read.
42
+ * Synchronous and side-effect-free.
43
+ *
44
+ * Returns `undefined` until the first inbound notify has landed.
45
+ */
46
+ getLastTelemetry: () => EebusVapdTelemetry | undefined;
39
47
  /**
40
48
  * Subscribe to consolidated PV telemetry updates.
41
49
  */
@@ -4,16 +4,16 @@ import { EebusIdentityService } from './eebus-identity-service.cjs';
4
4
  import { EebusSpineLowLevel } from './eebus-spine-low-level.cjs';
5
5
  import { EebusUseCaseRegistry } from './eebus-use-case-registry.cjs';
6
6
  export { EebusDeviceManagement } from './eebus-device-management.cjs';
7
- export { EebusFeatureCatalog, EebusFeatureAddressMatch } from './eebus-feature-catalog.cjs';
7
+ export { EebusFeatureCatalog, EebusFeatureAddressMatch, EebusFindFeatureForClientOptions, } from './eebus-feature-catalog.cjs';
8
8
  export { EebusIdentityService } from './eebus-identity-service.cjs';
9
9
  export { EebusSpineLowLevel } from './eebus-spine-low-level.cjs';
10
- export { EebusUseCaseClient } from './eebus-use-case-client.cjs';
10
+ export { EebusUseCaseClient, EebusUseCaseReadiness } from './eebus-use-case-client.cjs';
11
11
  export { EebusUseCaseRegistry } from './eebus-use-case-registry.cjs';
12
12
  export { EebusHvacClient, HvacClientOptions } from './eebus-hvac-client.cjs';
13
- export { EebusLpcClient, LpcClientOptions } from './eebus-lpc-client.cjs';
13
+ export { EebusLpcClient, LpcClientOptions, FindLpcLimitOptions, FindPerPhaseLimitIdsOptions, SetConsumptionLimitOptions, } from './eebus-lpc-client.cjs';
14
14
  export { EebusLppClient } from './eebus-lpp-client.cjs';
15
15
  export { EebusMgcpClient } from './eebus-mgcp-client.cjs';
16
- export { EebusMpcClient, MpcClientOptions } from './eebus-mpc-client.cjs';
16
+ export { EebusMpcClient, MpcClientOptions, FindMpcMeasurementOptions } from './eebus-mpc-client.cjs';
17
17
  export { EebusOhpcfClient, OhpcfClientOptions } from './eebus-ohpcf-client.cjs';
18
18
  export { EebusSetpointClient, SetpointClientOptions } from './eebus-setpoint-client.cjs';
19
19
  export { EebusCevcClient, CevcClientOptions } from './eebus-cevc-client.cjs';
@@ -11,14 +11,28 @@ var EnyoBatteryStorageMode;
11
11
  })(EnyoBatteryStorageMode || (exports.EnyoBatteryStorageMode = EnyoBatteryStorageMode = {}));
12
12
  var EnyoBatteryFeature;
13
13
  (function (EnyoBatteryFeature) {
14
- /** If the battery supports being charged from the grid */
14
+ /**
15
+ * If the battery supports being charged from the grid
16
+ */
15
17
  EnyoBatteryFeature["GridCharging"] = "grid-charging";
16
- /** If the battery supports discharging into the grid */
18
+ /**
19
+ * If the battery supports discharging into the grid
20
+ */
17
21
  EnyoBatteryFeature["GridDischarging"] = "grid-discharging";
18
- /** If the battery supports discharge power limitation */
22
+ /**
23
+ * If the battery supports discharge power limitation
24
+ * @deprecated
25
+ */
19
26
  EnyoBatteryFeature["DischargeLimitation"] = "discharge-limitation";
20
- /** If the battery supports charge power limitation */
27
+ /**
28
+ * If the battery supports charge power limitation
29
+ * @deprecated
30
+ */
21
31
  EnyoBatteryFeature["ChargeLimitation"] = "charge-limitation";
22
32
  /** If the battery is connected between DC strings and the inverter */
23
33
  EnyoBatteryFeature["BetweenDcStringAndInverter"] = "between-dc-string-and-inverter";
34
+ /** If the battery supports manual charging */
35
+ EnyoBatteryFeature["ManualCharge"] = "manual-charge";
36
+ /** If the battery supports manual discharging */
37
+ EnyoBatteryFeature["ManualDischarge"] = "manual-discharge";
24
38
  })(EnyoBatteryFeature || (exports.EnyoBatteryFeature = EnyoBatteryFeature = {}));
@@ -6,16 +6,30 @@ export declare enum EnyoBatteryStorageMode {
6
6
  Unknown = "unknown"
7
7
  }
8
8
  export declare enum EnyoBatteryFeature {
9
- /** If the battery supports being charged from the grid */
9
+ /**
10
+ * If the battery supports being charged from the grid
11
+ */
10
12
  GridCharging = "grid-charging",
11
- /** If the battery supports discharging into the grid */
13
+ /**
14
+ * If the battery supports discharging into the grid
15
+ */
12
16
  GridDischarging = "grid-discharging",
13
- /** If the battery supports discharge power limitation */
17
+ /**
18
+ * If the battery supports discharge power limitation
19
+ * @deprecated
20
+ */
14
21
  DischargeLimitation = "discharge-limitation",
15
- /** If the battery supports charge power limitation */
22
+ /**
23
+ * If the battery supports charge power limitation
24
+ * @deprecated
25
+ */
16
26
  ChargeLimitation = "charge-limitation",
17
27
  /** If the battery is connected between DC strings and the inverter */
18
- BetweenDcStringAndInverter = "between-dc-string-and-inverter"
28
+ BetweenDcStringAndInverter = "between-dc-string-and-inverter",
29
+ /** If the battery supports manual charging */
30
+ ManualCharge = "manual-charge",
31
+ /** If the battery supports manual discharging */
32
+ ManualDischarge = "manual-discharge"
19
33
  }
20
34
  export interface EnyoBatteryApplianceMetadata {
21
35
  connectedToApplianceId?: string;