kirby-ocpp 0.1.2 → 0.2.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.
Files changed (121) hide show
  1. package/README.md +134 -95
  2. package/THIRD_PARTY_NOTICES.md +6 -2
  3. package/bin/kirby-ocpp.js +55 -0
  4. package/package.json +22 -44
  5. package/dist/cli.d.ts +0 -2
  6. package/dist/cli.js +0 -72
  7. package/dist/config.d.ts +0 -2
  8. package/dist/config.js +0 -53
  9. package/dist/ocpp/client.d.ts +0 -59
  10. package/dist/ocpp/client.js +0 -299
  11. package/dist/ocpp/schema-validator.d.ts +0 -15
  12. package/dist/ocpp/schema-validator.js +0 -75
  13. package/dist/ocpp/schemas/json/Authorize.json +0 -16
  14. package/dist/ocpp/schemas/json/AuthorizeResponse.json +0 -40
  15. package/dist/ocpp/schemas/json/BootNotification.json +0 -49
  16. package/dist/ocpp/schemas/json/BootNotificationResponse.json +0 -30
  17. package/dist/ocpp/schemas/json/CancelReservation.json +0 -15
  18. package/dist/ocpp/schemas/json/CancelReservationResponse.json +0 -20
  19. package/dist/ocpp/schemas/json/ChangeAvailability.json +0 -24
  20. package/dist/ocpp/schemas/json/ChangeAvailabilityResponse.json +0 -21
  21. package/dist/ocpp/schemas/json/ChangeConfiguration.json +0 -21
  22. package/dist/ocpp/schemas/json/ChangeConfigurationResponse.json +0 -22
  23. package/dist/ocpp/schemas/json/ClearCache.json +0 -8
  24. package/dist/ocpp/schemas/json/ClearCacheResponse.json +0 -20
  25. package/dist/ocpp/schemas/json/ClearChargingProfile.json +0 -27
  26. package/dist/ocpp/schemas/json/ClearChargingProfileResponse.json +0 -20
  27. package/dist/ocpp/schemas/json/DataTransfer.json +0 -23
  28. package/dist/ocpp/schemas/json/DataTransferResponse.json +0 -25
  29. package/dist/ocpp/schemas/json/DiagnosticsStatusNotification.json +0 -22
  30. package/dist/ocpp/schemas/json/DiagnosticsStatusNotificationResponse.json +0 -8
  31. package/dist/ocpp/schemas/json/FirmwareStatusNotification.json +0 -25
  32. package/dist/ocpp/schemas/json/FirmwareStatusNotificationResponse.json +0 -8
  33. package/dist/ocpp/schemas/json/GetCompositeSchedule.json +0 -27
  34. package/dist/ocpp/schemas/json/GetCompositeScheduleResponse.json +0 -79
  35. package/dist/ocpp/schemas/json/GetConfiguration.json +0 -16
  36. package/dist/ocpp/schemas/json/GetConfigurationResponse.json +0 -40
  37. package/dist/ocpp/schemas/json/GetDiagnostics.json +0 -30
  38. package/dist/ocpp/schemas/json/GetDiagnosticsResponse.json +0 -13
  39. package/dist/ocpp/schemas/json/GetLocalListVersion.json +0 -8
  40. package/dist/ocpp/schemas/json/GetLocalListVersionResponse.json +0 -15
  41. package/dist/ocpp/schemas/json/Heartbeat.json +0 -8
  42. package/dist/ocpp/schemas/json/HeartbeatResponse.json +0 -16
  43. package/dist/ocpp/schemas/json/MeterValues.json +0 -151
  44. package/dist/ocpp/schemas/json/MeterValuesResponse.json +0 -8
  45. package/dist/ocpp/schemas/json/RemoteStartTransaction.json +0 -127
  46. package/dist/ocpp/schemas/json/RemoteStartTransactionResponse.json +0 -20
  47. package/dist/ocpp/schemas/json/RemoteStopTransaction.json +0 -15
  48. package/dist/ocpp/schemas/json/RemoteStopTransactionResponse.json +0 -20
  49. package/dist/ocpp/schemas/json/ReserveNow.json +0 -33
  50. package/dist/ocpp/schemas/json/ReserveNowResponse.json +0 -23
  51. package/dist/ocpp/schemas/json/Reset.json +0 -20
  52. package/dist/ocpp/schemas/json/ResetResponse.json +0 -20
  53. package/dist/ocpp/schemas/json/SendLocalList.json +0 -68
  54. package/dist/ocpp/schemas/json/SendLocalListResponse.json +0 -22
  55. package/dist/ocpp/schemas/json/SetChargingProfile.json +0 -124
  56. package/dist/ocpp/schemas/json/SetChargingProfileResponse.json +0 -21
  57. package/dist/ocpp/schemas/json/StartTransaction.json +0 -32
  58. package/dist/ocpp/schemas/json/StartTransactionResponse.json +0 -44
  59. package/dist/ocpp/schemas/json/StatusNotification.json +0 -70
  60. package/dist/ocpp/schemas/json/StatusNotificationResponse.json +0 -8
  61. package/dist/ocpp/schemas/json/StopTransaction.json +0 -177
  62. package/dist/ocpp/schemas/json/StopTransactionResponse.json +0 -37
  63. package/dist/ocpp/schemas/json/TriggerMessage.json +0 -27
  64. package/dist/ocpp/schemas/json/TriggerMessageResponse.json +0 -21
  65. package/dist/ocpp/schemas/json/UnlockConnector.json +0 -15
  66. package/dist/ocpp/schemas/json/UnlockConnectorResponse.json +0 -21
  67. package/dist/ocpp/schemas/json/UpdateFirmware.json +0 -27
  68. package/dist/ocpp/schemas/json/UpdateFirmwareResponse.json +0 -8
  69. package/dist/ocpp/types.d.ts +0 -106
  70. package/dist/ocpp/types.js +0 -1
  71. package/dist/station/authorization.d.ts +0 -20
  72. package/dist/station/authorization.js +0 -78
  73. package/dist/station/charging-profile-registry.d.ts +0 -18
  74. package/dist/station/charging-profile-registry.js +0 -125
  75. package/dist/station/configuration-commands.d.ts +0 -11
  76. package/dist/station/configuration-commands.js +0 -29
  77. package/dist/station/configuration-registry.d.ts +0 -13
  78. package/dist/station/configuration-registry.js +0 -39
  79. package/dist/station/configuration.d.ts +0 -7
  80. package/dist/station/configuration.js +0 -88
  81. package/dist/station/connector-registry.d.ts +0 -25
  82. package/dist/station/connector-registry.js +0 -89
  83. package/dist/station/connector-status.d.ts +0 -7
  84. package/dist/station/connector-status.js +0 -66
  85. package/dist/station/local-auth-list.d.ts +0 -8
  86. package/dist/station/local-auth-list.js +0 -31
  87. package/dist/station/maintenance-lifecycle.d.ts +0 -25
  88. package/dist/station/maintenance-lifecycle.js +0 -110
  89. package/dist/station/meter-value-scheduler.d.ts +0 -21
  90. package/dist/station/meter-value-scheduler.js +0 -78
  91. package/dist/station/metering.d.ts +0 -15
  92. package/dist/station/metering.js +0 -138
  93. package/dist/station/ocpp-message.d.ts +0 -2
  94. package/dist/station/ocpp-message.js +0 -9
  95. package/dist/station/offline-transaction-sync.d.ts +0 -29
  96. package/dist/station/offline-transaction-sync.js +0 -99
  97. package/dist/station/payload.d.ts +0 -4
  98. package/dist/station/payload.js +0 -12
  99. package/dist/station/persistence.d.ts +0 -28
  100. package/dist/station/persistence.js +0 -206
  101. package/dist/station/reservation-rules.d.ts +0 -3
  102. package/dist/station/reservation-rules.js +0 -18
  103. package/dist/station/reservation-scheduler.d.ts +0 -11
  104. package/dist/station/reservation-scheduler.js +0 -33
  105. package/dist/station/smart-charging.d.ts +0 -45
  106. package/dist/station/smart-charging.js +0 -251
  107. package/dist/station/status-scheduler.d.ts +0 -16
  108. package/dist/station/status-scheduler.js +0 -58
  109. package/dist/station/transaction-message-retry.d.ts +0 -3
  110. package/dist/station/transaction-message-retry.js +0 -7
  111. package/dist/station/transaction-rules.d.ts +0 -7
  112. package/dist/station/transaction-rules.js +0 -34
  113. package/dist/station/trigger-message.d.ts +0 -2
  114. package/dist/station/trigger-message.js +0 -11
  115. package/dist/station-store.d.ts +0 -41
  116. package/dist/station-store.js +0 -104
  117. package/dist/station.d.ts +0 -113
  118. package/dist/station.js +0 -1204
  119. package/dist/tui.d.ts +0 -96
  120. package/dist/tui.js +0 -1656
  121. package/docs/OCPP_1.6J_CONFORMANCE.md +0 -61
@@ -1,125 +0,0 @@
1
- import { canStoreChargingProfile, effectiveChargingProfiles, isChargingProfileExpired, limitTransitionOffsets, matchesChargingProfileFilter, periodAt, readChargingProfile, readChargingRateUnit } from "./smart-charging.js";
2
- import { readNumber } from "./payload.js";
3
- export class ChargingProfileRegistry {
4
- profiles = [];
5
- get length() {
6
- return this.profiles.length;
7
- }
8
- entries() {
9
- return [...this.profiles];
10
- }
11
- replace(entries) {
12
- this.profiles.splice(0, this.profiles.length, ...entries);
13
- }
14
- set(connectorId, profilePayload, options) {
15
- const profile = readChargingProfile(profilePayload);
16
- if (!profile || !canStoreChargingProfile(connectorId, profile, options)) {
17
- return "Rejected";
18
- }
19
- const existingIndex = this.profiles.findIndex((entry) => entry.profile.chargingProfileId === profile.chargingProfileId);
20
- if (existingIndex >= 0) {
21
- this.profiles.splice(existingIndex, 1);
22
- }
23
- this.profiles.push({ connectorId, profile });
24
- return "Accepted";
25
- }
26
- clear(payload) {
27
- this.pruneExpired();
28
- const before = this.profiles.length;
29
- const remaining = this.profiles.filter((entry) => !matchesChargingProfileFilter(entry, payload));
30
- this.profiles.splice(0, this.profiles.length, ...remaining);
31
- return before - this.profiles.length > 0 ? "Accepted" : "Unknown";
32
- }
33
- clearForTransaction(transactionId) {
34
- const before = this.profiles.length;
35
- const remaining = this.profiles.filter((entry) => entry.profile.chargingProfilePurpose !== "TxProfile" || entry.profile.transactionId !== transactionId);
36
- this.profiles.splice(0, this.profiles.length, ...remaining);
37
- return this.profiles.length !== before;
38
- }
39
- pruneExpired(at = new Date()) {
40
- const before = this.profiles.length;
41
- const remaining = this.profiles.filter((entry) => !isChargingProfileExpired(entry.profile, at));
42
- this.profiles.splice(0, this.profiles.length, ...remaining);
43
- return this.profiles.length !== before;
44
- }
45
- compositeSchedulePayload(payload, transactionId, transactionStartedAt) {
46
- const prunedExpired = this.pruneExpired();
47
- const connectorId = readNumber(payload.connectorId, -1);
48
- const duration = readNumber(payload.duration, 0);
49
- const requestedUnit = readChargingRateUnit(payload.chargingRateUnit);
50
- if (duration <= 0) {
51
- return undefined;
52
- }
53
- const scheduleStart = new Date();
54
- const defaultUnit = requestedUnit ?? effectiveChargingProfiles(this.profiles, connectorId, transactionId, scheduleStart)[0]?.profile.chargingSchedule.chargingRateUnit ?? "A";
55
- const unit = defaultUnit;
56
- const relativeStart = transactionStartedAt ? new Date(transactionStartedAt) : undefined;
57
- const composite = compositeSchedule(this.profiles, connectorId, transactionId, unit, scheduleStart, duration, relativeStart);
58
- if (composite.chargingSchedulePeriod.length === 0) {
59
- return undefined;
60
- }
61
- const chargingSchedule = {
62
- duration,
63
- startSchedule: scheduleStart.toISOString(),
64
- chargingRateUnit: unit,
65
- chargingSchedulePeriod: composite.chargingSchedulePeriod
66
- };
67
- if (composite.minChargingRate !== undefined) {
68
- chargingSchedule.minChargingRate = composite.minChargingRate;
69
- }
70
- return {
71
- prunedExpired,
72
- payload: {
73
- status: "Accepted",
74
- connectorId,
75
- scheduleStart: scheduleStart.toISOString(),
76
- chargingSchedule
77
- }
78
- };
79
- }
80
- }
81
- function compositeSchedule(entries, connectorId, transactionId, unit, scheduleStart, duration, relativeStart) {
82
- const offsets = new Set([0]);
83
- const unitEntries = entries.filter((entry) => entry.profile.chargingSchedule.chargingRateUnit === unit);
84
- for (const entry of unitEntries) {
85
- for (const offset of limitTransitionOffsets(entry.profile, scheduleStart, duration, relativeStart)) {
86
- offsets.add(offset);
87
- }
88
- }
89
- let minChargingRate;
90
- const chargingSchedulePeriod = [...offsets]
91
- .sort((left, right) => left - right)
92
- .map((offset) => {
93
- const at = new Date(scheduleStart.getTime() + offset * 1000);
94
- const activeProfiles = effectiveChargingProfiles(unitEntries, connectorId, transactionId, at, unit);
95
- const activePeriods = activeProfiles
96
- .map((entry) => ({ entry, period: periodAt(entry.profile, at, relativeStart, scheduleStart) }))
97
- .filter((item) => item.period !== undefined);
98
- for (const { entry } of activePeriods) {
99
- const profileMin = entry.profile.chargingSchedule.minChargingRate;
100
- if (profileMin !== undefined) {
101
- minChargingRate = minChargingRate === undefined ? profileMin : Math.max(minChargingRate, profileMin);
102
- }
103
- }
104
- if (activePeriods.length === 0) {
105
- return undefined;
106
- }
107
- const limit = Math.min(...activePeriods.map(({ period }) => period.limit));
108
- const limitingPhases = activePeriods
109
- .filter(({ period }) => period.limit === limit)
110
- .map(({ period }) => period.numberPhases)
111
- .filter((numberPhases) => typeof numberPhases === "number" && Number.isFinite(numberPhases));
112
- const period = { startPeriod: offset, limit };
113
- if (limitingPhases.length > 0) {
114
- period.numberPhases = Math.min(...limitingPhases);
115
- }
116
- return period;
117
- })
118
- .filter((period) => period !== undefined);
119
- return {
120
- chargingSchedulePeriod: chargingSchedulePeriod.filter((period, index) => index === 0 ||
121
- period.limit !== chargingSchedulePeriod[index - 1]?.limit ||
122
- period.numberPhases !== chargingSchedulePeriod[index - 1]?.numberPhases),
123
- minChargingRate
124
- };
125
- }
@@ -1,11 +0,0 @@
1
- import type { ConfigurationRegistry } from "./configuration-registry.js";
2
- export interface ChangeConfigurationResult {
3
- status: "Accepted" | "Rejected" | "NotSupported";
4
- key: string;
5
- value: string;
6
- }
7
- export declare function changeConfiguration(configuration: ConfigurationRegistry, payload: Record<string, unknown>): ChangeConfigurationResult;
8
- export declare function getConfiguration(configuration: ConfigurationRegistry, payload: Record<string, unknown>): {
9
- configurationKey: Record<string, unknown>[];
10
- unknownKey: string[];
11
- };
@@ -1,29 +0,0 @@
1
- import { readString } from "./payload.js";
2
- export function changeConfiguration(configuration, payload) {
3
- const key = readString(payload.key, "");
4
- const value = readString(payload.value, "");
5
- const existing = configuration.get(key);
6
- if (!existing) {
7
- return { status: "NotSupported", key, value };
8
- }
9
- if (existing.readonly || (existing.validate && !existing.validate(value))) {
10
- return { status: "Rejected", key, value };
11
- }
12
- configuration.setValue(key, value);
13
- return { status: "Accepted", key, value };
14
- }
15
- export function getConfiguration(configuration, payload) {
16
- const requestedKeys = Array.isArray(payload.key) ? payload.key.filter((key) => typeof key === "string") : [];
17
- const keys = requestedKeys.length > 0 ? requestedKeys : configuration.keys();
18
- const configurationKey = [];
19
- const unknownKey = [];
20
- for (const key of keys) {
21
- const entry = configuration.get(key);
22
- if (!entry) {
23
- unknownKey.push(key);
24
- continue;
25
- }
26
- configurationKey.push({ key, readonly: entry.readonly, value: entry.value });
27
- }
28
- return { configurationKey, unknownKey };
29
- }
@@ -1,13 +0,0 @@
1
- import type { StationConfig } from "../ocpp/types.js";
2
- import { type ConfigurationKey } from "./configuration.js";
3
- import { type Measurand, type MeteringConfigurationKey } from "./metering.js";
4
- export declare class ConfigurationRegistry {
5
- readonly values: Map<string, ConfigurationKey>;
6
- constructor(config: StationConfig);
7
- get(key: string): ConfigurationKey | undefined;
8
- keys(): string[];
9
- setValue(key: string, value: string): void;
10
- boolean(key: string, fallback: boolean): boolean;
11
- integer(key: string, fallback: number): number;
12
- measurands(key: MeteringConfigurationKey): Measurand[];
13
- }
@@ -1,39 +0,0 @@
1
- import { createDefaultConfiguration } from "./configuration.js";
2
- import { readConfiguredMeasurands } from "./metering.js";
3
- export class ConfigurationRegistry {
4
- values;
5
- constructor(config) {
6
- this.values = createDefaultConfiguration(config);
7
- }
8
- get(key) {
9
- return this.values.get(key);
10
- }
11
- keys() {
12
- return [...this.values.keys()];
13
- }
14
- setValue(key, value) {
15
- const existing = this.values.get(key);
16
- if (!existing) {
17
- return;
18
- }
19
- this.values.set(key, { ...existing, value });
20
- }
21
- boolean(key, fallback) {
22
- const value = this.values.get(key)?.value;
23
- if (value === undefined) {
24
- return fallback;
25
- }
26
- return value.toLowerCase() === "true";
27
- }
28
- integer(key, fallback) {
29
- const value = this.values.get(key)?.value;
30
- if (value === undefined) {
31
- return fallback;
32
- }
33
- const parsed = Number.parseInt(value, 10);
34
- return Number.isSafeInteger(parsed) ? parsed : fallback;
35
- }
36
- measurands(key) {
37
- return readConfiguredMeasurands(this.values.get(key)?.value);
38
- }
39
- }
@@ -1,7 +0,0 @@
1
- import type { StationConfig } from "../ocpp/types.js";
2
- export interface ConfigurationKey {
3
- readonly: boolean;
4
- value: string;
5
- validate?: (value: string) => boolean;
6
- }
7
- export declare function createDefaultConfiguration(config: StationConfig): Map<string, ConfigurationKey>;
@@ -1,88 +0,0 @@
1
- import { DEFAULT_SAMPLED_DATA, isValidSampledDataConfiguration, MEASURANDS } from "./metering.js";
2
- const SUPPORTED_FEATURE_PROFILES = [
3
- "Core",
4
- "FirmwareManagement",
5
- "LocalAuthListManagement",
6
- "Reservation",
7
- "RemoteTrigger",
8
- "SmartCharging"
9
- ];
10
- const CONNECTOR_PHASE_ROTATIONS = new Set([
11
- "NotApplicable",
12
- "Unknown",
13
- "RST",
14
- "RTS",
15
- "SRT",
16
- "STR",
17
- "TRS",
18
- "TSR"
19
- ]);
20
- const DEFAULT_SAMPLED_DATA_CONFIGURATION = DEFAULT_SAMPLED_DATA.join(",");
21
- export function createDefaultConfiguration(config) {
22
- const configuration = new Map();
23
- const boolean = (value) => isBooleanConfigurationValue(value);
24
- const nonNegativeInteger = (value) => isIntegerConfigurationValue(value, 0);
25
- const positiveInteger = (value) => isIntegerConfigurationValue(value, 1);
26
- const sampledData = (value) => isValidSampledDataConfiguration(value);
27
- const set = (key, readonly, value, validate) => {
28
- configuration.set(key, { readonly, value, validate });
29
- };
30
- set("AllowOfflineTxForUnknownId", false, "false", boolean);
31
- set("AuthorizationCacheEnabled", false, "true", boolean);
32
- set("AuthorizeRemoteTxRequests", false, "false", boolean);
33
- set("BlinkRepeat", false, "0", nonNegativeInteger);
34
- set("ChargePointModel", true, config.model);
35
- set("ChargePointSerialNumber", true, config.chargePointId);
36
- set("ChargePointVendor", true, config.vendor);
37
- set("ClockAlignedDataInterval", false, "0", nonNegativeInteger);
38
- set("ConnectionTimeOut", false, "60", positiveInteger);
39
- set("ConnectorPhaseRotation", false, "Unknown", isConnectorPhaseRotationConfiguration);
40
- set("ConnectorPhaseRotationMaxLength", true, String(Math.max(1, config.connectorCount)));
41
- set("GetConfigurationMaxKeys", true, "50");
42
- set("HeartbeatInterval", false, String(config.heartbeatIntervalSeconds), positiveInteger);
43
- set("LightIntensity", false, "0", nonNegativeInteger);
44
- set("LocalAuthListEnabled", false, "true", boolean);
45
- set("LocalAuthListMaxLength", true, "1000");
46
- set("LocalAuthorizeOffline", false, "false", boolean);
47
- set("LocalPreAuthorize", false, "false", boolean);
48
- set("MaxEnergyOnInvalidId", false, "0", nonNegativeInteger);
49
- set("MeterValuesAlignedData", false, DEFAULT_SAMPLED_DATA_CONFIGURATION, sampledData);
50
- set("MeterValuesAlignedDataMaxLength", true, String(MEASURANDS.size));
51
- set("MeterValuesSampledData", false, DEFAULT_SAMPLED_DATA_CONFIGURATION, sampledData);
52
- set("MeterValuesSampledDataMaxLength", true, String(MEASURANDS.size));
53
- set("MeterValueSampleInterval", false, "60", nonNegativeInteger);
54
- set("MinimumStatusDuration", false, "0", nonNegativeInteger);
55
- set("NumberOfConnectors", true, String(config.connectorCount));
56
- set("ResetRetries", false, "0", nonNegativeInteger);
57
- set("SendLocalListMaxLength", true, "1000");
58
- set("StopTransactionOnEVSideDisconnect", false, "true", boolean);
59
- set("StopTransactionOnInvalidId", false, "false", boolean);
60
- set("StopTxnAlignedData", false, DEFAULT_SAMPLED_DATA_CONFIGURATION, sampledData);
61
- set("StopTxnAlignedDataMaxLength", true, String(MEASURANDS.size));
62
- set("StopTxnSampledData", false, DEFAULT_SAMPLED_DATA_CONFIGURATION, sampledData);
63
- set("StopTxnSampledDataMaxLength", true, String(MEASURANDS.size));
64
- set("SupportedFeatureProfiles", true, SUPPORTED_FEATURE_PROFILES.join(","));
65
- set("SupportedFeatureProfilesMaxLength", true, String(SUPPORTED_FEATURE_PROFILES.length));
66
- set("TransactionMessageAttempts", false, "1", positiveInteger);
67
- set("TransactionMessageRetryInterval", false, "30", positiveInteger);
68
- set("UnlockConnectorOnEVSideDisconnect", false, "false", boolean);
69
- set("WebSocketPingInterval", false, "0", nonNegativeInteger);
70
- return configuration;
71
- }
72
- function isBooleanConfigurationValue(value) {
73
- return value === "true" || value === "false";
74
- }
75
- function isIntegerConfigurationValue(value, minimum) {
76
- if (!/^\d+$/.test(value)) {
77
- return false;
78
- }
79
- const parsed = Number.parseInt(value, 10);
80
- return Number.isSafeInteger(parsed) && parsed >= minimum;
81
- }
82
- function isConnectorPhaseRotationConfiguration(value) {
83
- const items = value
84
- .split(",")
85
- .map((item) => item.trim())
86
- .filter(Boolean);
87
- return items.length > 0 && items.every((item) => CONNECTOR_PHASE_ROTATIONS.has(item));
88
- }
@@ -1,25 +0,0 @@
1
- import type { ConnectorState } from "../ocpp/types.js";
2
- export declare class ConnectorRegistry {
3
- private readonly primaryConnectorId;
4
- private readonly connectors;
5
- private onChange?;
6
- constructor(primaryConnectorId: number, count: number);
7
- setOnChange(onChange: () => void): void;
8
- get size(): number;
9
- has(id: number): boolean;
10
- get(id: number): ConnectorState;
11
- find(id: number): ConnectorState | undefined;
12
- all(): ConnectorState[];
13
- add(): ConnectorState;
14
- ensureCount(count: number): void;
15
- patch(id: number, patch: Partial<ConnectorState>): void;
16
- snapshot(): {
17
- connectors: ConnectorState[];
18
- primary?: ConnectorState;
19
- };
20
- findAvailable(): ConnectorState | undefined;
21
- findByTransaction(transactionId: number): ConnectorState | undefined;
22
- findByReservation(reservationId: number): ConnectorState | undefined;
23
- private nextId;
24
- private notifyChange;
25
- }
@@ -1,89 +0,0 @@
1
- export class ConnectorRegistry {
2
- primaryConnectorId;
3
- connectors = new Map();
4
- onChange;
5
- constructor(primaryConnectorId, count) {
6
- this.primaryConnectorId = primaryConnectorId;
7
- const connectorCount = Math.max(validConnectorCount(count), primaryConnectorId);
8
- for (let connectorId = 1; connectorId <= connectorCount; connectorId += 1) {
9
- this.connectors.set(connectorId, createConnector(connectorId));
10
- }
11
- }
12
- setOnChange(onChange) {
13
- this.onChange = onChange;
14
- }
15
- get size() {
16
- return this.connectors.size;
17
- }
18
- has(id) {
19
- return this.connectors.has(id);
20
- }
21
- get(id) {
22
- const connector = this.connectors.get(id);
23
- if (!connector) {
24
- throw new Error(`Connector ${id} does not exist`);
25
- }
26
- return connector;
27
- }
28
- find(id) {
29
- return this.connectors.get(id);
30
- }
31
- all() {
32
- return [...this.connectors.values()].sort((left, right) => left.id - right.id);
33
- }
34
- add() {
35
- const connector = createConnector(this.nextId());
36
- this.connectors.set(connector.id, connector);
37
- this.notifyChange();
38
- return connector;
39
- }
40
- ensureCount(count) {
41
- const initialSize = this.connectors.size;
42
- while (this.connectors.size < count) {
43
- const connector = createConnector(this.nextId());
44
- this.connectors.set(connector.id, connector);
45
- }
46
- if (this.connectors.size !== initialSize) {
47
- this.notifyChange();
48
- }
49
- }
50
- patch(id, patch) {
51
- Object.assign(this.get(id), patch);
52
- this.notifyChange();
53
- }
54
- snapshot() {
55
- const connectors = this.all().map((connector) => ({ ...connector }));
56
- const primary = this.connectors.get(this.primaryConnectorId) ?? connectors[0];
57
- return { connectors, primary };
58
- }
59
- findAvailable() {
60
- return this.all().find((connector) => !connector.transactionId &&
61
- connector.availability === "Operative" &&
62
- connector.status === "Available");
63
- }
64
- findByTransaction(transactionId) {
65
- return this.all().find((connector) => connector.transactionId === transactionId);
66
- }
67
- findByReservation(reservationId) {
68
- return this.all().find((connector) => connector.reservationId === reservationId);
69
- }
70
- nextId() {
71
- return Math.max(0, ...this.connectors.keys()) + 1;
72
- }
73
- notifyChange() {
74
- this.onChange?.();
75
- }
76
- }
77
- function validConnectorCount(count) {
78
- return Number.isInteger(count) && count > 0 ? count : 1;
79
- }
80
- function createConnector(id) {
81
- return {
82
- id,
83
- status: "Available",
84
- availability: "Operative",
85
- errorCode: "NoError",
86
- evConnected: false,
87
- meterWh: 0
88
- };
89
- }
@@ -1,7 +0,0 @@
1
- import type { AvailabilityType, ChargePointErrorCode, ConnectorState, ConnectorStatus } from "../ocpp/types.js";
2
- export declare const CONNECTOR_STATUS_SEQUENCE: ConnectorStatus[];
3
- export declare function nextConnectorStatus(status: ConnectorStatus): ConnectorStatus;
4
- export declare function faultErrorCode(connector: ConnectorState): ChargePointErrorCode;
5
- export declare function statusAfterReservationClear(connector: ConnectorState): ConnectorStatus;
6
- export declare function statusAfterFaultClear(connector: ConnectorState): ConnectorStatus;
7
- export declare function statusAfterAvailabilityChange(connector: ConnectorState, availability: AvailabilityType): ConnectorStatus;
@@ -1,66 +0,0 @@
1
- export const CONNECTOR_STATUS_SEQUENCE = [
2
- "Available",
3
- "Preparing",
4
- "Charging",
5
- "SuspendedEVSE",
6
- "SuspendedEV",
7
- "Finishing",
8
- "Reserved",
9
- "Unavailable",
10
- "Faulted"
11
- ];
12
- export function nextConnectorStatus(status) {
13
- const currentIndex = CONNECTOR_STATUS_SEQUENCE.indexOf(status);
14
- return CONNECTOR_STATUS_SEQUENCE[(currentIndex + 1) % CONNECTOR_STATUS_SEQUENCE.length] ?? "Available";
15
- }
16
- export function faultErrorCode(connector) {
17
- return connector.errorCode === "NoError" ? "OtherError" : connector.errorCode;
18
- }
19
- export function statusAfterReservationClear(connector) {
20
- if (connector.availability === "Inoperative" || connector.status === "Unavailable") {
21
- return "Unavailable";
22
- }
23
- if (connector.status === "Faulted") {
24
- return "Faulted";
25
- }
26
- if (connector.transactionId) {
27
- return "Charging";
28
- }
29
- if (connector.evConnected) {
30
- return "Preparing";
31
- }
32
- return "Available";
33
- }
34
- export function statusAfterFaultClear(connector) {
35
- if (connector.availability === "Inoperative") {
36
- return "Unavailable";
37
- }
38
- if (connector.transactionId) {
39
- return "Charging";
40
- }
41
- if (connector.evConnected) {
42
- return "Preparing";
43
- }
44
- if (connector.reservationId) {
45
- return "Reserved";
46
- }
47
- return "Available";
48
- }
49
- export function statusAfterAvailabilityChange(connector, availability) {
50
- if (connector.status === "Faulted") {
51
- return "Faulted";
52
- }
53
- if (availability === "Inoperative") {
54
- return "Unavailable";
55
- }
56
- if (connector.status === "Finishing") {
57
- return "Finishing";
58
- }
59
- if (connector.reservationId) {
60
- return "Reserved";
61
- }
62
- if (connector.evConnected) {
63
- return "Preparing";
64
- }
65
- return "Available";
66
- }
@@ -1,8 +0,0 @@
1
- export interface LocalAuthListUpdateResult {
2
- status: "Accepted" | "Failed" | "NotSupported" | "VersionMismatch";
3
- listVersion: number;
4
- }
5
- export declare function applyLocalAuthListUpdate(localAuthorizationList: Map<string, Record<string, unknown> | undefined>, currentVersion: number, payload: Record<string, unknown>, options: {
6
- enabled: boolean;
7
- maxLength: number;
8
- }): LocalAuthListUpdateResult;
@@ -1,31 +0,0 @@
1
- import { readNumber, readObject, readString } from "./payload.js";
2
- export function applyLocalAuthListUpdate(localAuthorizationList, currentVersion, payload, options) {
3
- const listVersion = readNumber(payload.listVersion, currentVersion);
4
- const updateType = readString(payload.updateType, "Full");
5
- const entries = Array.isArray(payload.localAuthorizationList) ? payload.localAuthorizationList : [];
6
- if (!options.enabled) {
7
- return { status: "NotSupported", listVersion: currentVersion };
8
- }
9
- if (entries.length > options.maxLength) {
10
- return { status: "Failed", listVersion: currentVersion };
11
- }
12
- if (updateType === "Differential" && listVersion <= currentVersion) {
13
- return { status: "VersionMismatch", listVersion: currentVersion };
14
- }
15
- if (updateType === "Full") {
16
- localAuthorizationList.clear();
17
- }
18
- for (const item of entries) {
19
- const entry = readObject(item);
20
- const idTag = readString(entry.idTag, "");
21
- if (!idTag) {
22
- continue;
23
- }
24
- if (updateType === "Differential" && !("idTagInfo" in entry)) {
25
- localAuthorizationList.delete(idTag);
26
- continue;
27
- }
28
- localAuthorizationList.set(idTag, "idTagInfo" in entry ? readObject(entry.idTagInfo) : undefined);
29
- }
30
- return { status: "Accepted", listVersion };
31
- }
@@ -1,25 +0,0 @@
1
- import type { DiagnosticsStatus, FirmwareStatus } from "../ocpp/types.js";
2
- export type DiagnosticsOutcome = "success" | "uploadFailure";
3
- export type FirmwareOutcome = "success" | "downloadFailure" | "installationFailure";
4
- export declare class MaintenanceLifecycle {
5
- private readonly options;
6
- private diagnosticsTimers;
7
- private firmwareTimers;
8
- private diagnosticsOutcome;
9
- private firmwareOutcome;
10
- constructor(options: {
11
- run: (task: () => Promise<void>) => void;
12
- diagnosticsStatus: (status: DiagnosticsStatus) => Promise<void>;
13
- firmwareStatus: (status: FirmwareStatus) => Promise<void>;
14
- log: (level: "info" | "warn", message: string) => void;
15
- });
16
- setDiagnosticsOutcome(outcome: DiagnosticsOutcome): void;
17
- setFirmwareOutcome(outcome: FirmwareOutcome): void;
18
- startDiagnostics(payload: Record<string, unknown>): string;
19
- startFirmware(payload: Record<string, unknown>): void;
20
- clearAll(): void;
21
- private clearDiagnostics;
22
- private clearFirmware;
23
- private schedule;
24
- private clear;
25
- }