kirby-ocpp 0.1.2 → 0.3.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/LICENSE +1 -1
- package/README.md +192 -88
- package/THIRD_PARTY_NOTICES.md +6 -2
- package/bin/kirby-ocpp.js +77 -0
- package/package.json +23 -44
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -72
- package/dist/config.d.ts +0 -2
- package/dist/config.js +0 -53
- package/dist/ocpp/client.d.ts +0 -59
- package/dist/ocpp/client.js +0 -299
- package/dist/ocpp/schema-validator.d.ts +0 -15
- package/dist/ocpp/schema-validator.js +0 -75
- package/dist/ocpp/schemas/json/Authorize.json +0 -16
- package/dist/ocpp/schemas/json/AuthorizeResponse.json +0 -40
- package/dist/ocpp/schemas/json/BootNotification.json +0 -49
- package/dist/ocpp/schemas/json/BootNotificationResponse.json +0 -30
- package/dist/ocpp/schemas/json/CancelReservation.json +0 -15
- package/dist/ocpp/schemas/json/CancelReservationResponse.json +0 -20
- package/dist/ocpp/schemas/json/ChangeAvailability.json +0 -24
- package/dist/ocpp/schemas/json/ChangeAvailabilityResponse.json +0 -21
- package/dist/ocpp/schemas/json/ChangeConfiguration.json +0 -21
- package/dist/ocpp/schemas/json/ChangeConfigurationResponse.json +0 -22
- package/dist/ocpp/schemas/json/ClearCache.json +0 -8
- package/dist/ocpp/schemas/json/ClearCacheResponse.json +0 -20
- package/dist/ocpp/schemas/json/ClearChargingProfile.json +0 -27
- package/dist/ocpp/schemas/json/ClearChargingProfileResponse.json +0 -20
- package/dist/ocpp/schemas/json/DataTransfer.json +0 -23
- package/dist/ocpp/schemas/json/DataTransferResponse.json +0 -25
- package/dist/ocpp/schemas/json/DiagnosticsStatusNotification.json +0 -22
- package/dist/ocpp/schemas/json/DiagnosticsStatusNotificationResponse.json +0 -8
- package/dist/ocpp/schemas/json/FirmwareStatusNotification.json +0 -25
- package/dist/ocpp/schemas/json/FirmwareStatusNotificationResponse.json +0 -8
- package/dist/ocpp/schemas/json/GetCompositeSchedule.json +0 -27
- package/dist/ocpp/schemas/json/GetCompositeScheduleResponse.json +0 -79
- package/dist/ocpp/schemas/json/GetConfiguration.json +0 -16
- package/dist/ocpp/schemas/json/GetConfigurationResponse.json +0 -40
- package/dist/ocpp/schemas/json/GetDiagnostics.json +0 -30
- package/dist/ocpp/schemas/json/GetDiagnosticsResponse.json +0 -13
- package/dist/ocpp/schemas/json/GetLocalListVersion.json +0 -8
- package/dist/ocpp/schemas/json/GetLocalListVersionResponse.json +0 -15
- package/dist/ocpp/schemas/json/Heartbeat.json +0 -8
- package/dist/ocpp/schemas/json/HeartbeatResponse.json +0 -16
- package/dist/ocpp/schemas/json/MeterValues.json +0 -151
- package/dist/ocpp/schemas/json/MeterValuesResponse.json +0 -8
- package/dist/ocpp/schemas/json/RemoteStartTransaction.json +0 -127
- package/dist/ocpp/schemas/json/RemoteStartTransactionResponse.json +0 -20
- package/dist/ocpp/schemas/json/RemoteStopTransaction.json +0 -15
- package/dist/ocpp/schemas/json/RemoteStopTransactionResponse.json +0 -20
- package/dist/ocpp/schemas/json/ReserveNow.json +0 -33
- package/dist/ocpp/schemas/json/ReserveNowResponse.json +0 -23
- package/dist/ocpp/schemas/json/Reset.json +0 -20
- package/dist/ocpp/schemas/json/ResetResponse.json +0 -20
- package/dist/ocpp/schemas/json/SendLocalList.json +0 -68
- package/dist/ocpp/schemas/json/SendLocalListResponse.json +0 -22
- package/dist/ocpp/schemas/json/SetChargingProfile.json +0 -124
- package/dist/ocpp/schemas/json/SetChargingProfileResponse.json +0 -21
- package/dist/ocpp/schemas/json/StartTransaction.json +0 -32
- package/dist/ocpp/schemas/json/StartTransactionResponse.json +0 -44
- package/dist/ocpp/schemas/json/StatusNotification.json +0 -70
- package/dist/ocpp/schemas/json/StatusNotificationResponse.json +0 -8
- package/dist/ocpp/schemas/json/StopTransaction.json +0 -177
- package/dist/ocpp/schemas/json/StopTransactionResponse.json +0 -37
- package/dist/ocpp/schemas/json/TriggerMessage.json +0 -27
- package/dist/ocpp/schemas/json/TriggerMessageResponse.json +0 -21
- package/dist/ocpp/schemas/json/UnlockConnector.json +0 -15
- package/dist/ocpp/schemas/json/UnlockConnectorResponse.json +0 -21
- package/dist/ocpp/schemas/json/UpdateFirmware.json +0 -27
- package/dist/ocpp/schemas/json/UpdateFirmwareResponse.json +0 -8
- package/dist/ocpp/types.d.ts +0 -106
- package/dist/ocpp/types.js +0 -1
- package/dist/station/authorization.d.ts +0 -20
- package/dist/station/authorization.js +0 -78
- package/dist/station/charging-profile-registry.d.ts +0 -18
- package/dist/station/charging-profile-registry.js +0 -125
- package/dist/station/configuration-commands.d.ts +0 -11
- package/dist/station/configuration-commands.js +0 -29
- package/dist/station/configuration-registry.d.ts +0 -13
- package/dist/station/configuration-registry.js +0 -39
- package/dist/station/configuration.d.ts +0 -7
- package/dist/station/configuration.js +0 -88
- package/dist/station/connector-registry.d.ts +0 -25
- package/dist/station/connector-registry.js +0 -89
- package/dist/station/connector-status.d.ts +0 -7
- package/dist/station/connector-status.js +0 -66
- package/dist/station/local-auth-list.d.ts +0 -8
- package/dist/station/local-auth-list.js +0 -31
- package/dist/station/maintenance-lifecycle.d.ts +0 -25
- package/dist/station/maintenance-lifecycle.js +0 -110
- package/dist/station/meter-value-scheduler.d.ts +0 -21
- package/dist/station/meter-value-scheduler.js +0 -78
- package/dist/station/metering.d.ts +0 -15
- package/dist/station/metering.js +0 -138
- package/dist/station/ocpp-message.d.ts +0 -2
- package/dist/station/ocpp-message.js +0 -9
- package/dist/station/offline-transaction-sync.d.ts +0 -29
- package/dist/station/offline-transaction-sync.js +0 -99
- package/dist/station/payload.d.ts +0 -4
- package/dist/station/payload.js +0 -12
- package/dist/station/persistence.d.ts +0 -28
- package/dist/station/persistence.js +0 -206
- package/dist/station/reservation-rules.d.ts +0 -3
- package/dist/station/reservation-rules.js +0 -18
- package/dist/station/reservation-scheduler.d.ts +0 -11
- package/dist/station/reservation-scheduler.js +0 -33
- package/dist/station/smart-charging.d.ts +0 -45
- package/dist/station/smart-charging.js +0 -251
- package/dist/station/status-scheduler.d.ts +0 -16
- package/dist/station/status-scheduler.js +0 -58
- package/dist/station/transaction-message-retry.d.ts +0 -3
- package/dist/station/transaction-message-retry.js +0 -7
- package/dist/station/transaction-rules.d.ts +0 -7
- package/dist/station/transaction-rules.js +0 -34
- package/dist/station/trigger-message.d.ts +0 -2
- package/dist/station/trigger-message.js +0 -11
- package/dist/station-store.d.ts +0 -41
- package/dist/station-store.js +0 -104
- package/dist/station.d.ts +0 -113
- package/dist/station.js +0 -1204
- package/dist/tui.d.ts +0 -96
- package/dist/tui.js +0 -1656
- package/docs/OCPP_1.6J_CONFORMANCE.md +0 -61
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_SAMPLED_DATA } from "./metering.js";
|
|
2
|
-
import { readChargingProfileEntry, readLegacyChargingProfileEntry } from "./smart-charging.js";
|
|
3
|
-
export function buildPersistedStationState(options) {
|
|
4
|
-
const primaryConnector = options.connectors.find((connector) => connector.id === options.connectorId) ?? options.connectors[0];
|
|
5
|
-
return {
|
|
6
|
-
version: 1,
|
|
7
|
-
chargePointId: options.chargePointId,
|
|
8
|
-
connectorCount: options.connectors.length,
|
|
9
|
-
connectorMeterValues: serializeConnectorMeterValues(options.connectors),
|
|
10
|
-
connectorReservations: serializeConnectorReservations(options.connectors),
|
|
11
|
-
connectorTransactions: serializeConnectorTransactions(options.connectors),
|
|
12
|
-
localListVersion: options.localListVersion,
|
|
13
|
-
localAuthorizationList: serializeAuthorizationEntries(options.localAuthorizationList),
|
|
14
|
-
authorizationCache: serializeAuthorizationEntries(options.authorizationCache),
|
|
15
|
-
chargingProfiles: options.chargingProfiles,
|
|
16
|
-
configurationValues: serializeMutableConfiguration(options.configuration),
|
|
17
|
-
meterWh: primaryConnector?.meterWh ?? 0
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
export function restorePersistedStationState(options) {
|
|
21
|
-
const { persisted } = options;
|
|
22
|
-
const persistedConnectorCount = Math.max(persisted.connectorCount ?? 1, options.connectorId);
|
|
23
|
-
options.connectors.ensureCount(persistedConnectorCount);
|
|
24
|
-
options.configuration.setValue("NumberOfConnectors", String(options.connectors.size));
|
|
25
|
-
const chargingProfiles = persisted.chargingProfiles
|
|
26
|
-
.map((entry) => readChargingProfileEntry(entry) ?? readLegacyChargingProfileEntry(entry, options.connectorId))
|
|
27
|
-
.filter(isDefined);
|
|
28
|
-
for (const [connectorId, meterWh] of Object.entries(persisted.connectorMeterValues ?? {})) {
|
|
29
|
-
const numericConnectorId = Number.parseInt(connectorId, 10);
|
|
30
|
-
if (Number.isInteger(numericConnectorId) && options.connectors.has(numericConnectorId)) {
|
|
31
|
-
options.connectors.patch(numericConnectorId, { meterWh });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
for (const [connectorId, reservation] of Object.entries(persisted.connectorReservations ?? {})) {
|
|
35
|
-
const numericConnectorId = Number.parseInt(connectorId, 10);
|
|
36
|
-
if (!Number.isInteger(numericConnectorId) || !options.connectors.has(numericConnectorId)) {
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if (Date.parse(reservation.expiryDate) <= Date.now()) {
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
options.connectors.patch(numericConnectorId, {
|
|
43
|
-
reservationId: reservation.reservationId,
|
|
44
|
-
reservationIdTag: reservation.idTag,
|
|
45
|
-
reservationParentIdTag: reservation.parentIdTag,
|
|
46
|
-
reservationExpiryDate: reservation.expiryDate,
|
|
47
|
-
status: "Reserved"
|
|
48
|
-
});
|
|
49
|
-
options.scheduleReservation(numericConnectorId);
|
|
50
|
-
}
|
|
51
|
-
for (const [connectorId, transaction] of Object.entries(persisted.connectorTransactions ?? {})) {
|
|
52
|
-
const numericConnectorId = Number.parseInt(connectorId, 10);
|
|
53
|
-
if (!Number.isInteger(numericConnectorId) || !options.connectors.has(numericConnectorId)) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
options.connectors.patch(numericConnectorId, {
|
|
57
|
-
transactionId: transaction.transactionId,
|
|
58
|
-
transactionStartedAt: transaction.transactionStartedAt,
|
|
59
|
-
lastIdTag: transaction.lastIdTag,
|
|
60
|
-
evConnected: transaction.evConnected,
|
|
61
|
-
status: readPersistedConnectorStatus(transaction.status),
|
|
62
|
-
stopTransactionAtWh: transaction.stopTransactionAtWh,
|
|
63
|
-
pendingStartTransaction: readPersistedPendingStart(transaction.pendingStartTransaction),
|
|
64
|
-
pendingStopTransaction: readPersistedPendingStop(transaction.pendingStopTransaction)
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
if (Object.keys(persisted.connectorMeterValues ?? {}).length === 0 && options.connectors.has(options.connectorId)) {
|
|
68
|
-
options.connectors.patch(options.connectorId, { meterWh: persisted.meterWh });
|
|
69
|
-
}
|
|
70
|
-
options.localAuthorizationList.clear();
|
|
71
|
-
for (const entry of persisted.localAuthorizationList) {
|
|
72
|
-
options.localAuthorizationList.set(entry.idTag, entry.idTagInfo);
|
|
73
|
-
}
|
|
74
|
-
options.authorizationCache.clear();
|
|
75
|
-
for (const entry of persisted.authorizationCache ?? []) {
|
|
76
|
-
options.authorizationCache.set(entry.idTag, entry.idTagInfo);
|
|
77
|
-
}
|
|
78
|
-
for (const [key, value] of Object.entries(persisted.configurationValues)) {
|
|
79
|
-
options.configuration.setValue(key, restoredConfigurationValue(key, value));
|
|
80
|
-
}
|
|
81
|
-
return { localListVersion: persisted.localListVersion, chargingProfiles };
|
|
82
|
-
}
|
|
83
|
-
function restoredConfigurationValue(key, value) {
|
|
84
|
-
if (isMeteringConfigurationKey(key) && value === "Energy.Active.Import.Register") {
|
|
85
|
-
return DEFAULT_SAMPLED_DATA.join(",");
|
|
86
|
-
}
|
|
87
|
-
return value;
|
|
88
|
-
}
|
|
89
|
-
function isMeteringConfigurationKey(key) {
|
|
90
|
-
return key === "MeterValuesAlignedData" ||
|
|
91
|
-
key === "MeterValuesSampledData" ||
|
|
92
|
-
key === "StopTxnAlignedData" ||
|
|
93
|
-
key === "StopTxnSampledData";
|
|
94
|
-
}
|
|
95
|
-
function serializeAuthorizationEntries(entries) {
|
|
96
|
-
return [...entries.entries()].map(([idTag, idTagInfo]) => {
|
|
97
|
-
if (!idTagInfo) {
|
|
98
|
-
return { idTag };
|
|
99
|
-
}
|
|
100
|
-
return { idTag, idTagInfo };
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
function serializeMutableConfiguration(configuration) {
|
|
104
|
-
return Object.fromEntries([...configuration.entries()].filter(([, value]) => !value.readonly).map(([key, value]) => [key, value.value]));
|
|
105
|
-
}
|
|
106
|
-
function serializeConnectorMeterValues(connectors) {
|
|
107
|
-
return Object.fromEntries(connectors.map((connector) => [String(connector.id), connector.meterWh]));
|
|
108
|
-
}
|
|
109
|
-
function serializeConnectorReservations(connectors) {
|
|
110
|
-
return Object.fromEntries(connectors
|
|
111
|
-
.filter((connector) => connector.reservationId && connector.reservationIdTag && connector.reservationExpiryDate)
|
|
112
|
-
.map((connector) => {
|
|
113
|
-
const reservation = {
|
|
114
|
-
reservationId: connector.reservationId ?? 0,
|
|
115
|
-
idTag: connector.reservationIdTag ?? "",
|
|
116
|
-
expiryDate: connector.reservationExpiryDate ?? ""
|
|
117
|
-
};
|
|
118
|
-
if (connector.reservationParentIdTag) {
|
|
119
|
-
reservation.parentIdTag = connector.reservationParentIdTag;
|
|
120
|
-
}
|
|
121
|
-
return [String(connector.id), reservation];
|
|
122
|
-
}));
|
|
123
|
-
}
|
|
124
|
-
function serializeConnectorTransactions(connectors) {
|
|
125
|
-
return Object.fromEntries(connectors
|
|
126
|
-
.filter((connector) => connector.transactionId || connector.pendingStartTransaction || connector.pendingStopTransaction)
|
|
127
|
-
.map((connector) => [
|
|
128
|
-
String(connector.id),
|
|
129
|
-
{
|
|
130
|
-
transactionId: connector.transactionId ?? 0,
|
|
131
|
-
transactionStartedAt: connector.transactionStartedAt,
|
|
132
|
-
lastIdTag: connector.lastIdTag,
|
|
133
|
-
evConnected: connector.evConnected,
|
|
134
|
-
status: connector.status,
|
|
135
|
-
stopTransactionAtWh: connector.stopTransactionAtWh,
|
|
136
|
-
pendingStartTransaction: connector.pendingStartTransaction,
|
|
137
|
-
pendingStopTransaction: connector.pendingStopTransaction
|
|
138
|
-
}
|
|
139
|
-
]));
|
|
140
|
-
}
|
|
141
|
-
function readPersistedConnectorStatus(value) {
|
|
142
|
-
return value === "Available" ||
|
|
143
|
-
value === "Preparing" ||
|
|
144
|
-
value === "Charging" ||
|
|
145
|
-
value === "SuspendedEVSE" ||
|
|
146
|
-
value === "SuspendedEV" ||
|
|
147
|
-
value === "Finishing" ||
|
|
148
|
-
value === "Reserved" ||
|
|
149
|
-
value === "Unavailable" ||
|
|
150
|
-
value === "Faulted"
|
|
151
|
-
? value
|
|
152
|
-
: "Charging";
|
|
153
|
-
}
|
|
154
|
-
function readPersistedPendingStart(value) {
|
|
155
|
-
if (!value) {
|
|
156
|
-
return undefined;
|
|
157
|
-
}
|
|
158
|
-
const connectorId = typeof value.connectorId === "number" ? value.connectorId : undefined;
|
|
159
|
-
const idTag = typeof value.idTag === "string" ? value.idTag : undefined;
|
|
160
|
-
const meterStart = typeof value.meterStart === "number" ? value.meterStart : undefined;
|
|
161
|
-
const timestamp = typeof value.timestamp === "string" ? value.timestamp : undefined;
|
|
162
|
-
if (connectorId === undefined || idTag === undefined || meterStart === undefined || timestamp === undefined) {
|
|
163
|
-
return undefined;
|
|
164
|
-
}
|
|
165
|
-
const pendingStart = { connectorId, idTag, meterStart, timestamp };
|
|
166
|
-
if (typeof value.reservationId === "number") {
|
|
167
|
-
return { ...pendingStart, reservationId: value.reservationId };
|
|
168
|
-
}
|
|
169
|
-
return pendingStart;
|
|
170
|
-
}
|
|
171
|
-
function readPersistedPendingStop(value) {
|
|
172
|
-
if (!value) {
|
|
173
|
-
return undefined;
|
|
174
|
-
}
|
|
175
|
-
const meterStop = typeof value.meterStop === "number" ? value.meterStop : undefined;
|
|
176
|
-
const timestamp = typeof value.timestamp === "string" ? value.timestamp : undefined;
|
|
177
|
-
const reason = typeof value.reason === "string" ? value.reason : undefined;
|
|
178
|
-
const transactionData = Array.isArray(value.transactionData) ? value.transactionData.filter(isRecord) : [];
|
|
179
|
-
if (meterStop === undefined || timestamp === undefined || !isStopReason(reason)) {
|
|
180
|
-
return undefined;
|
|
181
|
-
}
|
|
182
|
-
const pendingStop = { meterStop, timestamp, reason, transactionData };
|
|
183
|
-
if (typeof value.idTag === "string") {
|
|
184
|
-
return { ...pendingStop, idTag: value.idTag };
|
|
185
|
-
}
|
|
186
|
-
return pendingStop;
|
|
187
|
-
}
|
|
188
|
-
function isStopReason(value) {
|
|
189
|
-
return value === "EmergencyStop" ||
|
|
190
|
-
value === "EVDisconnected" ||
|
|
191
|
-
value === "HardReset" ||
|
|
192
|
-
value === "Local" ||
|
|
193
|
-
value === "Other" ||
|
|
194
|
-
value === "PowerLoss" ||
|
|
195
|
-
value === "Reboot" ||
|
|
196
|
-
value === "Remote" ||
|
|
197
|
-
value === "SoftReset" ||
|
|
198
|
-
value === "UnlockCommand" ||
|
|
199
|
-
value === "DeAuthorized";
|
|
200
|
-
}
|
|
201
|
-
function isRecord(value) {
|
|
202
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
203
|
-
}
|
|
204
|
-
function isDefined(value) {
|
|
205
|
-
return value !== undefined;
|
|
206
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { ConnectorState } from "../ocpp/types.js";
|
|
2
|
-
export type ReserveNowStatus = "Accepted" | "Faulted" | "Occupied" | "Rejected" | "Unavailable";
|
|
3
|
-
export declare function reserveNowRejection(connector: ConnectorState | undefined, expiryDate: string): Exclude<ReserveNowStatus, "Accepted"> | undefined;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export function reserveNowRejection(connector, expiryDate) {
|
|
2
|
-
if (!connector) {
|
|
3
|
-
return "Unavailable";
|
|
4
|
-
}
|
|
5
|
-
if (connector.transactionId || connector.reservationId || connector.status === "Reserved") {
|
|
6
|
-
return "Occupied";
|
|
7
|
-
}
|
|
8
|
-
if (connector.status === "Faulted") {
|
|
9
|
-
return "Faulted";
|
|
10
|
-
}
|
|
11
|
-
if (connector.availability === "Inoperative" || connector.status === "Unavailable") {
|
|
12
|
-
return "Unavailable";
|
|
13
|
-
}
|
|
14
|
-
if (!expiryDate || Date.parse(expiryDate) <= Date.now()) {
|
|
15
|
-
return "Rejected";
|
|
16
|
-
}
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export declare class ReservationScheduler {
|
|
2
|
-
private readonly options;
|
|
3
|
-
private readonly timers;
|
|
4
|
-
constructor(options: {
|
|
5
|
-
expiryDate: (connectorId: number) => string | undefined;
|
|
6
|
-
expire: (connectorId: number) => void;
|
|
7
|
-
});
|
|
8
|
-
schedule(connectorId: number): void;
|
|
9
|
-
clear(connectorId: number): void;
|
|
10
|
-
clearAll(): void;
|
|
11
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export class ReservationScheduler {
|
|
2
|
-
options;
|
|
3
|
-
timers = new Map();
|
|
4
|
-
constructor(options) {
|
|
5
|
-
this.options = options;
|
|
6
|
-
}
|
|
7
|
-
schedule(connectorId) {
|
|
8
|
-
this.clear(connectorId);
|
|
9
|
-
const expiryDate = this.options.expiryDate(connectorId);
|
|
10
|
-
if (!expiryDate) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
const delay = Date.parse(expiryDate) - Date.now();
|
|
14
|
-
if (delay <= 0) {
|
|
15
|
-
this.options.expire(connectorId);
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
this.timers.set(connectorId, setTimeout(() => this.options.expire(connectorId), delay));
|
|
19
|
-
}
|
|
20
|
-
clear(connectorId) {
|
|
21
|
-
const timer = this.timers.get(connectorId);
|
|
22
|
-
if (!timer) {
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
clearTimeout(timer);
|
|
26
|
-
this.timers.delete(connectorId);
|
|
27
|
-
}
|
|
28
|
-
clearAll() {
|
|
29
|
-
for (const connectorId of [...this.timers.keys()]) {
|
|
30
|
-
this.clear(connectorId);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
export type ChargingProfilePurpose = "ChargePointMaxProfile" | "TxDefaultProfile" | "TxProfile";
|
|
2
|
-
export type ChargingProfileKind = "Absolute" | "Recurring" | "Relative";
|
|
3
|
-
export type ChargingRateUnit = "A" | "W";
|
|
4
|
-
export interface ChargingSchedulePeriod {
|
|
5
|
-
startPeriod: number;
|
|
6
|
-
limit: number;
|
|
7
|
-
numberPhases?: number;
|
|
8
|
-
}
|
|
9
|
-
export interface ChargingSchedule {
|
|
10
|
-
duration?: number;
|
|
11
|
-
startSchedule?: string;
|
|
12
|
-
chargingRateUnit: ChargingRateUnit;
|
|
13
|
-
chargingSchedulePeriod: ChargingSchedulePeriod[];
|
|
14
|
-
minChargingRate?: number;
|
|
15
|
-
}
|
|
16
|
-
export interface ChargingProfile {
|
|
17
|
-
chargingProfileId: number;
|
|
18
|
-
transactionId?: number;
|
|
19
|
-
stackLevel: number;
|
|
20
|
-
chargingProfilePurpose: ChargingProfilePurpose;
|
|
21
|
-
chargingProfileKind: ChargingProfileKind;
|
|
22
|
-
recurrencyKind?: "Daily" | "Weekly";
|
|
23
|
-
validFrom?: string;
|
|
24
|
-
validTo?: string;
|
|
25
|
-
chargingSchedule: ChargingSchedule;
|
|
26
|
-
}
|
|
27
|
-
export interface ChargingProfileEntry {
|
|
28
|
-
connectorId: number;
|
|
29
|
-
profile: ChargingProfile;
|
|
30
|
-
}
|
|
31
|
-
export declare function readChargingProfile(value: unknown): ChargingProfile | undefined;
|
|
32
|
-
export declare function readChargingProfileEntry(value: unknown): ChargingProfileEntry | undefined;
|
|
33
|
-
export declare function readLegacyChargingProfileEntry(value: unknown, defaultConnectorId: number): ChargingProfileEntry | undefined;
|
|
34
|
-
export declare function readChargingRateUnit(value: unknown): ChargingRateUnit | undefined;
|
|
35
|
-
export declare function canStoreChargingProfile(connectorId: number, profile: ChargingProfile, options: {
|
|
36
|
-
hasConnector: (connectorId: number) => boolean;
|
|
37
|
-
transactionIdForConnector: (connectorId: number) => number | undefined;
|
|
38
|
-
}): boolean;
|
|
39
|
-
export declare function matchesChargingProfileFilter(entry: ChargingProfileEntry, payload: Record<string, unknown>): boolean;
|
|
40
|
-
export declare function applicableChargingProfiles(entries: ChargingProfileEntry[], connectorId: number, transactionId: number | undefined, at: Date): ChargingProfileEntry[];
|
|
41
|
-
export declare function effectiveChargingProfiles(entries: ChargingProfileEntry[], connectorId: number, transactionId: number | undefined, at: Date, chargingRateUnit?: ChargingRateUnit): ChargingProfileEntry[];
|
|
42
|
-
export declare function limitAt(profile: ChargingProfile, at: Date, relativeStart?: Date, defaultStart?: Date): number | undefined;
|
|
43
|
-
export declare function periodAt(profile: ChargingProfile, at: Date, relativeStart?: Date, defaultStart?: Date): ChargingSchedulePeriod | undefined;
|
|
44
|
-
export declare function limitTransitionOffsets(profile: ChargingProfile, scheduleStart: Date, duration: number, relativeStart?: Date): number[];
|
|
45
|
-
export declare function isChargingProfileExpired(profile: ChargingProfile, at: Date): boolean;
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
const PURPOSE_PRIORITY = ["TxProfile", "TxDefaultProfile", "ChargePointMaxProfile"];
|
|
2
|
-
export function readChargingProfile(value) {
|
|
3
|
-
const payload = readObject(value);
|
|
4
|
-
const chargingSchedule = readChargingSchedule(payload.chargingSchedule);
|
|
5
|
-
const chargingProfilePurpose = readChargingProfilePurpose(payload.chargingProfilePurpose);
|
|
6
|
-
const chargingProfileKind = readChargingProfileKind(payload.chargingProfileKind);
|
|
7
|
-
if (!chargingSchedule || !chargingProfilePurpose || !chargingProfileKind) {
|
|
8
|
-
return undefined;
|
|
9
|
-
}
|
|
10
|
-
const profile = {
|
|
11
|
-
chargingProfileId: readNumber(payload.chargingProfileId, -1),
|
|
12
|
-
stackLevel: readNumber(payload.stackLevel, -1),
|
|
13
|
-
chargingProfilePurpose,
|
|
14
|
-
chargingProfileKind,
|
|
15
|
-
chargingSchedule
|
|
16
|
-
};
|
|
17
|
-
const transactionId = readOptionalNumber(payload.transactionId);
|
|
18
|
-
const recurrencyKind = readRecurrencyKind(payload.recurrencyKind);
|
|
19
|
-
const validFrom = readOptionalString(payload.validFrom);
|
|
20
|
-
const validTo = readOptionalString(payload.validTo);
|
|
21
|
-
if (transactionId !== undefined) {
|
|
22
|
-
profile.transactionId = transactionId;
|
|
23
|
-
}
|
|
24
|
-
if (recurrencyKind) {
|
|
25
|
-
profile.recurrencyKind = recurrencyKind;
|
|
26
|
-
}
|
|
27
|
-
if (validFrom) {
|
|
28
|
-
profile.validFrom = validFrom;
|
|
29
|
-
}
|
|
30
|
-
if (validTo) {
|
|
31
|
-
profile.validTo = validTo;
|
|
32
|
-
}
|
|
33
|
-
return profile.chargingProfileId >= 0 && profile.stackLevel >= 0 ? profile : undefined;
|
|
34
|
-
}
|
|
35
|
-
export function readChargingProfileEntry(value) {
|
|
36
|
-
const payload = readObject(value);
|
|
37
|
-
const connectorId = readOptionalNumber(payload.connectorId);
|
|
38
|
-
const profile = readChargingProfile(payload.profile);
|
|
39
|
-
if (connectorId === undefined || !profile) {
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
return { connectorId, profile };
|
|
43
|
-
}
|
|
44
|
-
export function readLegacyChargingProfileEntry(value, defaultConnectorId) {
|
|
45
|
-
const profile = readChargingProfile(value);
|
|
46
|
-
return profile ? { connectorId: defaultConnectorId, profile } : undefined;
|
|
47
|
-
}
|
|
48
|
-
export function readChargingRateUnit(value) {
|
|
49
|
-
return value === "A" || value === "W" ? value : undefined;
|
|
50
|
-
}
|
|
51
|
-
export function canStoreChargingProfile(connectorId, profile, options) {
|
|
52
|
-
if (!Number.isInteger(connectorId) || connectorId < 0) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
if (profile.chargingProfilePurpose === "ChargePointMaxProfile") {
|
|
56
|
-
return connectorId === 0;
|
|
57
|
-
}
|
|
58
|
-
if (connectorId !== 0 && !options.hasConnector(connectorId)) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
if (profile.chargingProfilePurpose === "TxProfile") {
|
|
62
|
-
const transactionId = connectorId > 0 ? options.transactionIdForConnector(connectorId) : undefined;
|
|
63
|
-
if (!transactionId) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
return profile.transactionId === undefined || profile.transactionId === transactionId;
|
|
67
|
-
}
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
export function matchesChargingProfileFilter(entry, payload) {
|
|
71
|
-
const hasFilter = "id" in payload || "connectorId" in payload || "chargingProfilePurpose" in payload || "stackLevel" in payload;
|
|
72
|
-
if (!hasFilter) {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
const id = readOptionalNumber(payload.id);
|
|
76
|
-
const connectorId = readOptionalNumber(payload.connectorId);
|
|
77
|
-
const purpose = readChargingProfilePurpose(payload.chargingProfilePurpose);
|
|
78
|
-
const stackLevel = readOptionalNumber(payload.stackLevel);
|
|
79
|
-
return ((id === undefined || entry.profile.chargingProfileId === id) &&
|
|
80
|
-
(connectorId === undefined || entry.connectorId === connectorId) &&
|
|
81
|
-
(purpose === undefined || entry.profile.chargingProfilePurpose === purpose) &&
|
|
82
|
-
(stackLevel === undefined || entry.profile.stackLevel === stackLevel));
|
|
83
|
-
}
|
|
84
|
-
export function applicableChargingProfiles(entries, connectorId, transactionId, at) {
|
|
85
|
-
return entries
|
|
86
|
-
.filter((entry) => entry.connectorId === 0 || entry.connectorId === connectorId)
|
|
87
|
-
.filter((entry) => isChargingProfileActive(entry.profile, at))
|
|
88
|
-
.filter((entry) => {
|
|
89
|
-
if (entry.profile.chargingProfilePurpose !== "TxProfile") {
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
return Boolean(transactionId) && (entry.profile.transactionId === undefined || entry.profile.transactionId === transactionId);
|
|
93
|
-
})
|
|
94
|
-
.sort((left, right) => right.profile.stackLevel - left.profile.stackLevel);
|
|
95
|
-
}
|
|
96
|
-
export function effectiveChargingProfiles(entries, connectorId, transactionId, at, chargingRateUnit) {
|
|
97
|
-
const applicable = applicableChargingProfiles(entries, connectorId, transactionId, at).filter((entry) => chargingRateUnit === undefined || entry.profile.chargingSchedule.chargingRateUnit === chargingRateUnit);
|
|
98
|
-
return PURPOSE_PRIORITY.flatMap((purpose) => {
|
|
99
|
-
const candidates = applicable.filter((entry) => entry.profile.chargingProfilePurpose === purpose);
|
|
100
|
-
if (candidates.length === 0) {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
return candidates.reduce((best, entry) => (entry.profile.stackLevel >= best.profile.stackLevel ? entry : best));
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
export function limitAt(profile, at, relativeStart, defaultStart) {
|
|
107
|
-
return periodAt(profile, at, relativeStart, defaultStart)?.limit;
|
|
108
|
-
}
|
|
109
|
-
export function periodAt(profile, at, relativeStart, defaultStart) {
|
|
110
|
-
if (!isChargingProfileActive(profile, at)) {
|
|
111
|
-
return undefined;
|
|
112
|
-
}
|
|
113
|
-
const schedule = profile.chargingSchedule;
|
|
114
|
-
const elapsedSeconds = scheduleElapsedSeconds(profile, at, relativeStart, defaultStart);
|
|
115
|
-
if (schedule.duration !== undefined && elapsedSeconds >= schedule.duration) {
|
|
116
|
-
return undefined;
|
|
117
|
-
}
|
|
118
|
-
let activePeriod;
|
|
119
|
-
for (const period of schedule.chargingSchedulePeriod) {
|
|
120
|
-
if (period.startPeriod <= elapsedSeconds) {
|
|
121
|
-
activePeriod = period;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return activePeriod;
|
|
125
|
-
}
|
|
126
|
-
export function limitTransitionOffsets(profile, scheduleStart, duration, relativeStart) {
|
|
127
|
-
const offsets = new Set();
|
|
128
|
-
const elapsedSeconds = scheduleElapsedSeconds(profile, scheduleStart, relativeStart, scheduleStart);
|
|
129
|
-
const schedule = profile.chargingSchedule;
|
|
130
|
-
offsets.add(0);
|
|
131
|
-
if (profile.validTo) {
|
|
132
|
-
addOffset(offsets, Math.ceil((Date.parse(profile.validTo) - scheduleStart.getTime()) / 1000), duration);
|
|
133
|
-
}
|
|
134
|
-
if (profile.validFrom) {
|
|
135
|
-
addOffset(offsets, Math.ceil((Date.parse(profile.validFrom) - scheduleStart.getTime()) / 1000), duration);
|
|
136
|
-
}
|
|
137
|
-
if (profile.chargingProfileKind === "Recurring") {
|
|
138
|
-
const recurrenceSeconds = profile.recurrencyKind === "Weekly" ? 7 * 24 * 60 * 60 : 24 * 60 * 60;
|
|
139
|
-
for (let cycle = 0; cycle <= elapsedSeconds + duration + recurrenceSeconds; cycle += recurrenceSeconds) {
|
|
140
|
-
addScheduleOffsets(offsets, schedule, duration, elapsedSeconds, cycle);
|
|
141
|
-
}
|
|
142
|
-
return [...offsets].sort((left, right) => left - right);
|
|
143
|
-
}
|
|
144
|
-
addScheduleOffsets(offsets, schedule, duration, elapsedSeconds, 0);
|
|
145
|
-
return [...offsets].sort((left, right) => left - right);
|
|
146
|
-
}
|
|
147
|
-
export function isChargingProfileExpired(profile, at) {
|
|
148
|
-
const validTo = profile.validTo ? Date.parse(profile.validTo) : undefined;
|
|
149
|
-
return validTo !== undefined && !Number.isNaN(validTo) && at.getTime() > validTo;
|
|
150
|
-
}
|
|
151
|
-
function readChargingSchedule(value) {
|
|
152
|
-
const payload = readObject(value);
|
|
153
|
-
const chargingRateUnit = readChargingRateUnit(payload.chargingRateUnit);
|
|
154
|
-
const periods = Array.isArray(payload.chargingSchedulePeriod)
|
|
155
|
-
? payload.chargingSchedulePeriod.map((period) => readChargingSchedulePeriod(period)).filter(isDefined)
|
|
156
|
-
: [];
|
|
157
|
-
if (!chargingRateUnit || periods.length === 0) {
|
|
158
|
-
return undefined;
|
|
159
|
-
}
|
|
160
|
-
const schedule = {
|
|
161
|
-
chargingRateUnit,
|
|
162
|
-
chargingSchedulePeriod: periods.sort((left, right) => left.startPeriod - right.startPeriod)
|
|
163
|
-
};
|
|
164
|
-
const duration = readOptionalNumber(payload.duration);
|
|
165
|
-
const startSchedule = readOptionalString(payload.startSchedule);
|
|
166
|
-
const minChargingRate = readOptionalNumber(payload.minChargingRate);
|
|
167
|
-
if (duration !== undefined) {
|
|
168
|
-
schedule.duration = duration;
|
|
169
|
-
}
|
|
170
|
-
if (startSchedule) {
|
|
171
|
-
schedule.startSchedule = startSchedule;
|
|
172
|
-
}
|
|
173
|
-
if (minChargingRate !== undefined) {
|
|
174
|
-
schedule.minChargingRate = minChargingRate;
|
|
175
|
-
}
|
|
176
|
-
return schedule;
|
|
177
|
-
}
|
|
178
|
-
function readChargingSchedulePeriod(value) {
|
|
179
|
-
const payload = readObject(value);
|
|
180
|
-
const startPeriod = readOptionalNumber(payload.startPeriod);
|
|
181
|
-
const limit = readOptionalNumber(payload.limit);
|
|
182
|
-
if (startPeriod === undefined || limit === undefined) {
|
|
183
|
-
return undefined;
|
|
184
|
-
}
|
|
185
|
-
const period = { startPeriod, limit };
|
|
186
|
-
const numberPhases = readOptionalNumber(payload.numberPhases);
|
|
187
|
-
if (numberPhases !== undefined) {
|
|
188
|
-
period.numberPhases = numberPhases;
|
|
189
|
-
}
|
|
190
|
-
return period;
|
|
191
|
-
}
|
|
192
|
-
function readChargingProfilePurpose(value) {
|
|
193
|
-
return value === "ChargePointMaxProfile" || value === "TxDefaultProfile" || value === "TxProfile" ? value : undefined;
|
|
194
|
-
}
|
|
195
|
-
function readChargingProfileKind(value) {
|
|
196
|
-
return value === "Absolute" || value === "Recurring" || value === "Relative" ? value : undefined;
|
|
197
|
-
}
|
|
198
|
-
function readRecurrencyKind(value) {
|
|
199
|
-
return value === "Daily" || value === "Weekly" ? value : undefined;
|
|
200
|
-
}
|
|
201
|
-
function isChargingProfileActive(profile, at) {
|
|
202
|
-
const validFrom = profile.validFrom ? Date.parse(profile.validFrom) : undefined;
|
|
203
|
-
const validTo = profile.validTo ? Date.parse(profile.validTo) : undefined;
|
|
204
|
-
const time = at.getTime();
|
|
205
|
-
return ((validFrom === undefined || Number.isNaN(validFrom) || time >= validFrom) &&
|
|
206
|
-
(validTo === undefined || Number.isNaN(validTo) || time <= validTo));
|
|
207
|
-
}
|
|
208
|
-
function addScheduleOffsets(offsets, schedule, duration, elapsedSeconds, elapsedBase) {
|
|
209
|
-
for (const period of schedule.chargingSchedulePeriod) {
|
|
210
|
-
addOffset(offsets, elapsedBase + period.startPeriod - elapsedSeconds, duration);
|
|
211
|
-
}
|
|
212
|
-
if (schedule.duration !== undefined) {
|
|
213
|
-
addOffset(offsets, elapsedBase + schedule.duration - elapsedSeconds, duration);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
function addOffset(offsets, offset, duration) {
|
|
217
|
-
if (Number.isInteger(offset) && offset > 0 && offset < duration) {
|
|
218
|
-
offsets.add(offset);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function scheduleElapsedSeconds(profile, at, relativeStart, defaultStart) {
|
|
222
|
-
if (profile.chargingProfileKind === "Relative") {
|
|
223
|
-
return Math.max(0, Math.floor((at.getTime() - (relativeStart?.getTime() ?? at.getTime())) / 1000));
|
|
224
|
-
}
|
|
225
|
-
const start = profile.chargingSchedule.startSchedule
|
|
226
|
-
? Date.parse(profile.chargingSchedule.startSchedule)
|
|
227
|
-
: profile.validFrom
|
|
228
|
-
? Date.parse(profile.validFrom)
|
|
229
|
-
: defaultStart?.getTime() ?? at.getTime();
|
|
230
|
-
const rawElapsed = Math.max(0, Math.floor((at.getTime() - (Number.isNaN(start) ? at.getTime() : start)) / 1000));
|
|
231
|
-
if (profile.chargingProfileKind !== "Recurring") {
|
|
232
|
-
return rawElapsed;
|
|
233
|
-
}
|
|
234
|
-
const periodSeconds = profile.recurrencyKind === "Weekly" ? 7 * 24 * 60 * 60 : 24 * 60 * 60;
|
|
235
|
-
return rawElapsed % periodSeconds;
|
|
236
|
-
}
|
|
237
|
-
function readObject(value) {
|
|
238
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
239
|
-
}
|
|
240
|
-
function readNumber(value, fallback) {
|
|
241
|
-
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
242
|
-
}
|
|
243
|
-
function readOptionalNumber(value) {
|
|
244
|
-
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
245
|
-
}
|
|
246
|
-
function readOptionalString(value) {
|
|
247
|
-
return typeof value === "string" ? value : undefined;
|
|
248
|
-
}
|
|
249
|
-
function isDefined(value) {
|
|
250
|
-
return value !== undefined;
|
|
251
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { ConnectorStatus } from "../ocpp/types.js";
|
|
2
|
-
export declare class StatusNotificationScheduler {
|
|
3
|
-
private readonly options;
|
|
4
|
-
private readonly pending;
|
|
5
|
-
private readonly lastSent;
|
|
6
|
-
constructor(options: {
|
|
7
|
-
minimumSeconds: () => number;
|
|
8
|
-
currentStatus: (connectorId: number) => ConnectorStatus | undefined;
|
|
9
|
-
send: (connectorId: number, status: ConnectorStatus) => void;
|
|
10
|
-
});
|
|
11
|
-
schedule(connectorId: number, status: ConnectorStatus): boolean;
|
|
12
|
-
markSent(connectorId: number, status: ConnectorStatus): void;
|
|
13
|
-
clear(connectorId: number): void;
|
|
14
|
-
clearAll(): void;
|
|
15
|
-
flush(): void;
|
|
16
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
export class StatusNotificationScheduler {
|
|
2
|
-
options;
|
|
3
|
-
pending = new Map();
|
|
4
|
-
lastSent = new Map();
|
|
5
|
-
constructor(options) {
|
|
6
|
-
this.options = options;
|
|
7
|
-
}
|
|
8
|
-
schedule(connectorId, status) {
|
|
9
|
-
const pending = this.pending.get(connectorId);
|
|
10
|
-
if (pending?.status === status) {
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
if (pending) {
|
|
14
|
-
this.clear(connectorId);
|
|
15
|
-
}
|
|
16
|
-
if (this.lastSent.get(connectorId) === status) {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
const minimumSeconds = this.options.minimumSeconds();
|
|
20
|
-
if (minimumSeconds <= 0) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
this.pending.set(connectorId, {
|
|
24
|
-
status,
|
|
25
|
-
timer: setTimeout(() => {
|
|
26
|
-
this.pending.delete(connectorId);
|
|
27
|
-
this.options.send(connectorId, status);
|
|
28
|
-
}, minimumSeconds * 1000)
|
|
29
|
-
});
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
markSent(connectorId, status) {
|
|
33
|
-
this.lastSent.set(connectorId, status);
|
|
34
|
-
}
|
|
35
|
-
clear(connectorId) {
|
|
36
|
-
const pending = this.pending.get(connectorId);
|
|
37
|
-
if (!pending) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
clearTimeout(pending.timer);
|
|
41
|
-
this.pending.delete(connectorId);
|
|
42
|
-
}
|
|
43
|
-
clearAll() {
|
|
44
|
-
for (const connectorId of [...this.pending.keys()]) {
|
|
45
|
-
this.clear(connectorId);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
flush() {
|
|
49
|
-
const connectorIds = [...this.pending.keys()];
|
|
50
|
-
this.clearAll();
|
|
51
|
-
for (const connectorId of connectorIds) {
|
|
52
|
-
const status = this.options.currentStatus(connectorId);
|
|
53
|
-
if (status) {
|
|
54
|
-
this.options.send(connectorId, status);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export const TRANSACTION_MESSAGE_ACTIONS = new Set(["StartTransaction", "StopTransaction", "MeterValues"]);
|
|
2
|
-
export function isTransactionMessage(action) {
|
|
3
|
-
return TRANSACTION_MESSAGE_ACTIONS.has(action);
|
|
4
|
-
}
|
|
5
|
-
export function retryDelay(intervalSeconds) {
|
|
6
|
-
return new Promise((resolve) => setTimeout(resolve, Math.max(0, intervalSeconds) * 1000));
|
|
7
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { AvailabilityType, ConnectorState, ConnectorStatus, StopReason } from "../ocpp/types.js";
|
|
2
|
-
export declare function startTransactionRejection(connector: ConnectorState, idTag: string): string | undefined;
|
|
3
|
-
export declare function canRemoteStart(connector: ConnectorState | undefined): boolean;
|
|
4
|
-
export declare function statusAfterStopTransaction(reason: StopReason, evConnected: boolean, availability: AvailabilityType): {
|
|
5
|
-
evConnected: boolean;
|
|
6
|
-
status: ConnectorStatus;
|
|
7
|
-
};
|