@enyo-energy/energy-app-sdk 0.0.39 → 0.0.41

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 (41) hide show
  1. package/dist/cjs/energy-app-permission.type.cjs +1 -0
  2. package/dist/cjs/energy-app-permission.type.d.cts +3 -2
  3. package/dist/cjs/enyo-energy-app-sdk.d.cts +3 -0
  4. package/dist/cjs/implementations/appliances/appliance-manager.cjs +52 -24
  5. package/dist/cjs/implementations/appliances/appliance-manager.d.cts +19 -14
  6. package/dist/cjs/implementations/appliances/identifier-strategies.cjs +5 -39
  7. package/dist/cjs/implementations/appliances/identifier-strategies.d.cts +6 -31
  8. package/dist/cjs/implementations/appliances/in-memory-appliance-manager.cjs +36 -25
  9. package/dist/cjs/implementations/appliances/in-memory-appliance-manager.d.cts +2 -3
  10. package/dist/cjs/implementations/modbus/EnergyAppModbusDataTypeConverter.cjs +8 -0
  11. package/dist/cjs/implementations/modbus/interfaces.d.cts +5 -1
  12. package/dist/cjs/index.cjs +9 -0
  13. package/dist/cjs/index.d.cts +8 -0
  14. package/dist/cjs/packages/energy-app-secret-manager.cjs +2 -0
  15. package/dist/cjs/packages/energy-app-secret-manager.d.cts +61 -0
  16. package/dist/cjs/types/enyo-data-bus-value.d.cts +14 -3
  17. package/dist/cjs/types/enyo-secret-manager.cjs +15 -0
  18. package/dist/cjs/types/enyo-secret-manager.d.cts +33 -0
  19. package/dist/cjs/version.cjs +1 -1
  20. package/dist/cjs/version.d.cts +1 -1
  21. package/dist/energy-app-permission.type.d.ts +3 -2
  22. package/dist/energy-app-permission.type.js +1 -0
  23. package/dist/enyo-energy-app-sdk.d.ts +3 -0
  24. package/dist/implementations/appliances/appliance-manager.d.ts +19 -14
  25. package/dist/implementations/appliances/appliance-manager.js +52 -24
  26. package/dist/implementations/appliances/identifier-strategies.d.ts +6 -31
  27. package/dist/implementations/appliances/identifier-strategies.js +4 -37
  28. package/dist/implementations/appliances/in-memory-appliance-manager.d.ts +2 -3
  29. package/dist/implementations/appliances/in-memory-appliance-manager.js +36 -25
  30. package/dist/implementations/modbus/EnergyAppModbusDataTypeConverter.js +8 -0
  31. package/dist/implementations/modbus/interfaces.d.ts +5 -1
  32. package/dist/index.d.ts +8 -0
  33. package/dist/index.js +9 -0
  34. package/dist/packages/energy-app-secret-manager.d.ts +61 -0
  35. package/dist/packages/energy-app-secret-manager.js +1 -0
  36. package/dist/types/enyo-data-bus-value.d.ts +14 -3
  37. package/dist/types/enyo-secret-manager.d.ts +33 -0
  38. package/dist/types/enyo-secret-manager.js +10 -0
  39. package/dist/version.d.ts +1 -1
  40. package/dist/version.js +1 -1
  41. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import { EnyoApplianceConnectionType, EnyoApplianceStateEnum } from "../../types/enyo-appliance.js";
2
2
  import { ApplianceManager } from "./appliance-manager.js";
3
+ import { randomUUID } from "node:crypto";
3
4
  /**
4
5
  * Demo implementation of ApplianceManager that stores all data in memory.
5
6
  * This class provides the same interface as ApplianceManager but doesn't
@@ -19,48 +20,58 @@ export class InMemoryApplianceManager extends ApplianceManager {
19
20
  }
20
21
  /**
21
22
  * Creates or updates an appliance in memory.
22
- * @param config The appliance configuration
23
- * @param existingApplianceId Optional ID of an existing appliance to update
23
+ * @param appliance The appliance configuration
24
24
  * @returns The ID of the created or updated appliance
25
25
  */
26
- async createOrUpdateAppliance(config, existingApplianceId) {
27
- const applianceId = existingApplianceId || `appliance_${this.nextId++}`;
26
+ async createOrUpdateAppliance(appliance) {
28
27
  // Build network device IDs list
29
- const networkDeviceIds = config.networkDevices?.map(d => d.id) ?? [];
30
- // Get existing metadata if updating
31
- const existingAppliance = existingApplianceId ? this.memoryStore.get(existingApplianceId) : null;
28
+ const networkDeviceIds = appliance.networkDevices?.map(d => d.id) ?? [];
29
+ // Try to find existing appliance using identifier strategy
30
+ let existingAppliance;
31
+ const identifier = this.config.identifierStrategy.extract(appliance);
32
+ if (identifier) {
33
+ const existing = await this.findByIdentifier(identifier);
34
+ if (existing.length > 0) {
35
+ existingAppliance = existing[0];
36
+ if (this.config.enableLogging) {
37
+ console.log(`Found existing appliance with ID ${existingAppliance.id} for identifier ${identifier}`);
38
+ }
39
+ }
40
+ }
32
41
  // Merge metadata with defaults and existing values
33
42
  const metadata = {
34
- connectionType: config.metadata?.connectionType ||
43
+ connectionType: appliance.metadata?.connectionType ||
35
44
  existingAppliance?.metadata?.connectionType ||
36
45
  EnyoApplianceConnectionType.Connector,
37
- state: config.metadata?.state ||
46
+ state: appliance.metadata?.state ||
38
47
  existingAppliance?.metadata?.state ||
39
48
  EnyoApplianceStateEnum.Connected,
40
- ...config.metadata
49
+ ...appliance.metadata
41
50
  };
42
51
  // Build appliance data
52
+ const applianceId = existingAppliance?.id || randomUUID();
43
53
  const applianceData = {
44
54
  id: applianceId,
45
- name: config.name,
46
- type: config.type,
55
+ name: appliance.name,
56
+ type: appliance.type,
47
57
  networkDeviceIds,
48
58
  metadata,
49
- ...(config.topology && { topology: config.topology })
59
+ ...(appliance.topology && { topology: appliance.topology }),
60
+ meter: appliance.meter,
61
+ heatpump: appliance.heatpump,
62
+ battery: appliance.battery,
63
+ charger: appliance.charger,
64
+ inverter: appliance.inverter,
50
65
  };
51
- // Add type-specific metadata
52
- if (config.typeMetadata) {
53
- Object.assign(applianceData, config.typeMetadata);
54
- }
55
66
  // Save to memory store
56
67
  this.memoryStore.set(applianceId, applianceData);
57
68
  // Store network devices if provided
58
- if (config.networkDevices) {
59
- this.networkDevicesStore.set(applianceId, config.networkDevices);
69
+ if (appliance.networkDevices) {
70
+ this.networkDevicesStore.set(applianceId, appliance.networkDevices);
60
71
  }
61
72
  // Update cache
62
- this.updateCache(applianceData, config.networkDevices?.[0]);
63
- console.log(`[DEMO] ${existingApplianceId ? 'Updated' : 'Created'} appliance ${applianceId} of type ${config.type}`);
73
+ this.updateCache(applianceData);
74
+ console.log(`[DEMO] ${existingAppliance ? 'Updated' : 'Created'} appliance ${applianceId} of type ${appliance.type}`);
64
75
  return applianceId;
65
76
  }
66
77
  /**
@@ -96,10 +107,10 @@ export class InMemoryApplianceManager extends ApplianceManager {
96
107
  const strategy = this.getIdentifierStrategy();
97
108
  for (const appliance of this.memoryStore.values()) {
98
109
  const networkDevices = await this.getNetworkDevicesForApplianceDemo(appliance);
99
- const extractedId = strategy.extract(appliance, networkDevices[0]);
110
+ const extractedId = strategy.extract(appliance);
100
111
  if (extractedId === identifier) {
101
112
  matches.push(appliance);
102
- this.updateCache(appliance, networkDevices[0]);
113
+ this.updateCache(appliance);
103
114
  }
104
115
  }
105
116
  return matches;
@@ -114,7 +125,7 @@ export class InMemoryApplianceManager extends ApplianceManager {
114
125
  for (const strategy of strategies) {
115
126
  for (const appliance of this.memoryStore.values()) {
116
127
  const networkDevices = await this.getNetworkDevicesForApplianceDemo(appliance);
117
- const identifier = strategy.extract(appliance, networkDevices[0]);
128
+ const identifier = strategy.extract(appliance);
118
129
  if (identifier === searchValue) {
119
130
  return {
120
131
  appliance,
@@ -254,7 +265,7 @@ export class InMemoryApplianceManager extends ApplianceManager {
254
265
  this.clearCache();
255
266
  for (const appliance of this.memoryStore.values()) {
256
267
  const networkDevices = await this.getNetworkDevicesForApplianceDemo(appliance);
257
- this.updateCache(appliance, networkDevices[0]);
268
+ this.updateCache(appliance);
258
269
  }
259
270
  }
260
271
  /**
@@ -16,6 +16,10 @@ export class EnergyAppModbusDataTypeConverter {
16
16
  convertFromBuffer(buffer, dataType, scale, quantity) {
17
17
  try {
18
18
  switch (dataType) {
19
+ case 'acc16': {
20
+ const value = buffer.readUInt16BE(0);
21
+ return this.applyScale(value, scale);
22
+ }
19
23
  case 'uint16': {
20
24
  const value = buffer.readUInt16BE(0);
21
25
  return this.applyScale(value, scale);
@@ -24,6 +28,10 @@ export class EnergyAppModbusDataTypeConverter {
24
28
  const value = buffer.readInt16BE(0);
25
29
  return this.applyScale(value, scale);
26
30
  }
31
+ case 'acc32': {
32
+ const value = buffer.readUInt32BE(0);
33
+ return this.applyScale(value, scale);
34
+ }
27
35
  case 'uint32': {
28
36
  const value = buffer.readUInt32BE(0);
29
37
  return this.applyScale(value, scale);
@@ -6,7 +6,7 @@ import type { EnyoApplianceName, EnyoApplianceTopology } from "../../types/enyo-
6
6
  * - Numeric types: uint16, int16, uint32, int32, float32
7
7
  * - String type: string (requires length property in register config)
8
8
  */
9
- export type EnergyAppModbusDataType = 'uint16' | 'int16' | 'uint32' | 'int32' | 'float32' | 'string';
9
+ export type EnergyAppModbusDataType = 'uint16' | 'int16' | 'uint32' | 'int32' | 'float32' | 'string' | 'acc32' | 'acc16';
10
10
  export interface EnergyAppModbusStateValueMapping<T> {
11
11
  value: number;
12
12
  mappedState: T;
@@ -55,6 +55,10 @@ export interface RegisterReadResult<T = any> {
55
55
  export interface IRegisterReader {
56
56
  readHoldingRegisters(startAddress: number, quantity: number): Promise<RegisterReadResult<Buffer>>;
57
57
  readInputRegisters?(startAddress: number, quantity: number): Promise<RegisterReadResult<Buffer>>;
58
+ readHoldingRegisterWithType<T = any>(address: number, dataType: EnergyAppModbusDataType, options?: {
59
+ scale?: number;
60
+ quantity?: number;
61
+ }): Promise<RegisterReadResult<T>>;
58
62
  isHealthy(): boolean;
59
63
  }
60
64
  export interface IRegisterMapper {
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ import { EnergyAppAuthentication } from "./packages/energy-app-authentication.js
13
13
  import { EnergyAppSettings } from "./packages/energy-app-settings.js";
14
14
  import { EnergyAppElectricityPrices } from "./packages/energy-app-electricity-prices.js";
15
15
  import { EnergyAppNotification } from "./packages/energy-app-notification.js";
16
+ import { EnergyAppSecretManager } from "./packages/energy-app-secret-manager.js";
16
17
  export * from './energy-app-package-definition.js';
17
18
  export * from './version.js';
18
19
  export * from './implementations/ocpp/ocpp16.js';
@@ -23,6 +24,7 @@ export * from './types/enyo-settings.js';
23
24
  export * from './types/enyo-energy-tariff.js';
24
25
  export * from './types/enyo-electricity-prices.js';
25
26
  export * from './types/enyo-notification.js';
27
+ export * from './types/enyo-secret-manager.js';
26
28
  export * from './implementations/appliances/appliance-manager.js';
27
29
  export * from './implementations/appliances/identifier-strategies.js';
28
30
  export declare class EnergyApp implements EnyoEnergyAppSdk {
@@ -47,6 +49,12 @@ export declare class EnergyApp implements EnyoEnergyAppSdk {
47
49
  useSettings(): EnergyAppSettings;
48
50
  useElectricityPrices(): EnergyAppElectricityPrices;
49
51
  useNotification(): EnergyAppNotification;
52
+ /**
53
+ * Gets the Secret Manager API for retrieving secrets from the developer organization.
54
+ * Provides methods to fetch secrets that have been configured in the developer org's secret store.
55
+ * @returns The Secret Manager API instance
56
+ */
57
+ useSecretManager(): EnergyAppSecretManager;
50
58
  /**
51
59
  * Gets the current SDK version.
52
60
  * @returns The semantic version string of the SDK
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ export * from './types/enyo-settings.js';
9
9
  export * from './types/enyo-energy-tariff.js';
10
10
  export * from './types/enyo-electricity-prices.js';
11
11
  export * from './types/enyo-notification.js';
12
+ export * from './types/enyo-secret-manager.js';
12
13
  export * from './implementations/appliances/appliance-manager.js';
13
14
  export * from './implementations/appliances/identifier-strategies.js';
14
15
  export class EnergyApp {
@@ -88,6 +89,14 @@ export class EnergyApp {
88
89
  useNotification() {
89
90
  return this.energyAppSdk.useNotification();
90
91
  }
92
+ /**
93
+ * Gets the Secret Manager API for retrieving secrets from the developer organization.
94
+ * Provides methods to fetch secrets that have been configured in the developer org's secret store.
95
+ * @returns The Secret Manager API instance
96
+ */
97
+ useSecretManager() {
98
+ return this.energyAppSdk.useSecretManager();
99
+ }
91
100
  /**
92
101
  * Gets the current SDK version.
93
102
  * @returns The semantic version string of the SDK
@@ -0,0 +1,61 @@
1
+ import { SecretValue } from "../types/enyo-secret-manager.js";
2
+ export interface EnergyAppSecretManager {
3
+ /**
4
+ * Retrieves and decrypts a single secret from the developer organization's secret store.
5
+ * The secret must have been previously configured in the developer org using the enyo CLI.
6
+ *
7
+ * @param secretName - The name of the secret to retrieve (e.g., "ostrom_oauth")
8
+ * @param encryptionKey - The encryption key used to decrypt the secret
9
+ * @returns Promise that resolves to an object containing the decrypted secret's key-value pairs
10
+ * @throws {SecretNotFoundError} If the secret does not exist
11
+ * @throws {SecretRetrievalError} If there's an error retrieving or decrypting the secret
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const secretManager = energyApp.useSecretManager();
16
+ * const oauthSecret = await secretManager.getSecret("oauth", encryptionKey);
17
+ * // Returns: { client_id: "...", client_secret: "..." }
18
+ * ```
19
+ */
20
+ getSecret(secretName: string, encryptionKey: string): Promise<SecretValue>;
21
+ /**
22
+ * Retrieves and decrypts multiple secrets from the developer organization's secret store in a single request.
23
+ * This is more efficient than making multiple individual requests.
24
+ * All secrets must have been previously configured using the enyo CLI.
25
+ *
26
+ * @param secretNames - Array of secret names to retrieve
27
+ * @param encryptionKey - The encryption key used to decrypt the secrets
28
+ * @returns Promise that resolves to a record mapping secret names to their decrypted values
29
+ * @throws {SecretNotFoundError} If any of the secrets do not exist
30
+ * @throws {SecretRetrievalError} If there's an error retrieving or decrypting the secrets
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const secretManager = energyApp.useSecretManager();
35
+ * const encryptionKey = process.env.SECRET_ENCRYPTION_KEY;
36
+ * const secrets = await secretManager.getSecrets(["api_keys", "oauth_config"], encryptionKey);
37
+ * // Returns: {
38
+ * // "api_keys": { api_key: "...", api_secret: "..." },
39
+ * // "oauth_config": { client_id: "...", client_secret: "..." }
40
+ * // }
41
+ * ```
42
+ */
43
+ getSecrets(secretNames: string[], encryptionKey: string): Promise<Record<string, SecretValue>>;
44
+ /**
45
+ * Lists all available secret names that can be retrieved from the developer organization.
46
+ * This can be useful for discovering what secrets have been configured.
47
+ * Note: This returns only the names of secrets, not their values.
48
+ *
49
+ * @returns Promise that resolves to an array of available secret names
50
+ * @throws {SecretRetrievalError} If there's an error listing the secrets
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const secretManager = energyApp.useSecretManager();
55
+ * const encryptionKey = process.env.SECRET_ENCRYPTION_KEY;
56
+ * const availableSecrets = await secretManager.listAvailableSecrets(encryptionKey);
57
+ * // Returns: ["oauth", "api_keys", "database_config"]
58
+ * ```
59
+ */
60
+ listAvailableSecrets(): Promise<string[]>;
61
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -207,16 +207,27 @@ export interface EnyoDataBusInverterValuesV1 extends EnyoDataBusMessage {
207
207
  /** ID of the appliance that delivered these values */
208
208
  applianceId: string;
209
209
  data: {
210
+ /** Operation State of the inverter */
210
211
  state?: EnyoInverterStateEnum;
211
212
  /** Current PV Production (in Watt) */
212
213
  pvPowerW: number;
213
- /** voltage of Phase L1 to N*/
214
+ /** voltage of Phase L1 to N in V */
214
215
  voltageL1: number;
215
- /** voltage of Phase L2 to N*/
216
+ /** voltage of Phase L2 to N in V */
216
217
  voltageL2?: number;
217
- /** voltage of Phase L3 to N*/
218
+ /** voltage of Phase L3 to N in V */
218
219
  voltageL3?: number;
220
+ /** Current of Phase L1 to N in A */
221
+ currentL1?: number;
222
+ /** Current of Phase L2 to N in A */
223
+ currentL2?: number;
224
+ /** Current of Phase L3 to N in A */
225
+ currentL3?: number;
226
+ /** DC Power in W */
227
+ dcPowerW?: number;
228
+ /** Active power Limitation of the Inverter */
219
229
  activePowerLimitationW?: number;
230
+ /** DC String values. Please only provide active strings */
220
231
  strings?: EnyoDataBusInverterValuesV1String[];
221
232
  };
222
233
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Represents a secret value object containing key-value pairs.
3
+ * The secret is retrieved from the developer organization's secret store.
4
+ */
5
+ export interface SecretValue {
6
+ [key: string]: string;
7
+ }
8
+ /**
9
+ * Request structure for fetching a single secret.
10
+ */
11
+ export interface SecretRequest {
12
+ /** The name of the secret to retrieve */
13
+ secretName: string;
14
+ }
15
+ /**
16
+ * Response structure for secret retrieval operations.
17
+ */
18
+ export interface SecretResponse {
19
+ /** The name of the secret */
20
+ secretName: string;
21
+ /** The secret values as key-value pairs */
22
+ values: SecretValue;
23
+ }
24
+ /**
25
+ * Error that occurs when a secret cannot be found.
26
+ */
27
+ export declare class SecretNotFoundError extends Error {
28
+ }
29
+ /**
30
+ * Error that occurs when secret retrieval fails.
31
+ */
32
+ export declare class SecretRetrievalError extends Error {
33
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Error that occurs when a secret cannot be found.
3
+ */
4
+ export class SecretNotFoundError extends Error {
5
+ }
6
+ /**
7
+ * Error that occurs when secret retrieval fails.
8
+ */
9
+ export class SecretRetrievalError extends Error {
10
+ }
package/dist/version.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export declare const SDK_VERSION = "0.0.39";
8
+ export declare const SDK_VERSION = "0.0.41";
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
package/dist/version.js CHANGED
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * Current version of the enyo Energy App SDK.
7
7
  */
8
- export const SDK_VERSION = '0.0.39';
8
+ export const SDK_VERSION = '0.0.41';
9
9
  /**
10
10
  * Gets the current SDK version.
11
11
  * @returns The semantic version string of the SDK
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enyo-energy/energy-app-sdk",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
4
4
  "description": "enyo Energy App SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",