fix: make ESM bundle work
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16RequestService.ts
1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
2
3 import type { JSONSchemaType } from 'ajv';
4
5 import type { ChargingStation } from '../../../charging-station';
6 import { OCPPError } from '../../../exception';
7 import {
8 ErrorType,
9 type JsonObject,
10 type JsonType,
11 type OCPP16AuthorizeRequest,
12 type OCPP16BootNotificationRequest,
13 type OCPP16DataTransferRequest,
14 type OCPP16DiagnosticsStatusNotificationRequest,
15 type OCPP16FirmwareStatusNotificationRequest,
16 type OCPP16HeartbeatRequest,
17 type OCPP16MeterValuesRequest,
18 OCPP16RequestCommand,
19 type OCPP16StartTransactionRequest,
20 type OCPP16StatusNotificationRequest,
21 type OCPP16StopTransactionRequest,
22 OCPPVersion,
23 type RequestParams,
24 } from '../../../types';
25 import { Constants, Utils } from '../../../utils';
26 import {
27 OCPP16ServiceUtils,
28 OCPPConstants,
29 OCPPRequestService,
30 type OCPPResponseService,
31 } from '../internal';
32
33 const moduleName = 'OCPP16RequestService';
34
35 export class OCPP16RequestService extends OCPPRequestService {
36 protected jsonSchemas: Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>;
37
38 public constructor(ocppResponseService: OCPPResponseService) {
39 // if (new.target?.name === moduleName) {
40 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
41 // }
42 super(OCPPVersion.VERSION_16, ocppResponseService);
43 this.jsonSchemas = new Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>([
44 [
45 OCPP16RequestCommand.AUTHORIZE,
46 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16AuthorizeRequest>(
47 '../../../assets/json-schemas/ocpp/1.6/Authorize.json',
48 moduleName,
49 'constructor'
50 ),
51 ],
52 [
53 OCPP16RequestCommand.BOOT_NOTIFICATION,
54 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16BootNotificationRequest>(
55 '../../../assets/json-schemas/ocpp/1.6/BootNotification.json',
56 moduleName,
57 'constructor'
58 ),
59 ],
60 [
61 OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION,
62 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16DiagnosticsStatusNotificationRequest>(
63 '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotification.json',
64 moduleName,
65 'constructor'
66 ),
67 ],
68 [
69 OCPP16RequestCommand.HEARTBEAT,
70 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16HeartbeatRequest>(
71 '../../../assets/json-schemas/ocpp/1.6/Heartbeat.json',
72 moduleName,
73 'constructor'
74 ),
75 ],
76 [
77 OCPP16RequestCommand.METER_VALUES,
78 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16MeterValuesRequest>(
79 '../../../assets/json-schemas/ocpp/1.6/MeterValues.json',
80 moduleName,
81 'constructor'
82 ),
83 ],
84 [
85 OCPP16RequestCommand.STATUS_NOTIFICATION,
86 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16StatusNotificationRequest>(
87 '../../../assets/json-schemas/ocpp/1.6/StatusNotification.json',
88 moduleName,
89 'constructor'
90 ),
91 ],
92 [
93 OCPP16RequestCommand.START_TRANSACTION,
94 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16StartTransactionRequest>(
95 '../../../assets/json-schemas/ocpp/1.6/StartTransaction.json',
96 moduleName,
97 'constructor'
98 ),
99 ],
100 [
101 OCPP16RequestCommand.STOP_TRANSACTION,
102 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16StopTransactionRequest>(
103 '../../../assets/json-schemas/ocpp/1.6/StopTransaction.json',
104 moduleName,
105 'constructor'
106 ),
107 ],
108 [
109 OCPP16RequestCommand.DATA_TRANSFER,
110 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16DataTransferRequest>(
111 '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json',
112 moduleName,
113 'constructor'
114 ),
115 ],
116 [
117 OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION,
118 OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16FirmwareStatusNotificationRequest>(
119 '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotification.json',
120 moduleName,
121 'constructor'
122 ),
123 ],
124 ]);
125 this.buildRequestPayload.bind(this);
126 }
127
128 public async requestHandler<RequestType extends JsonType, ResponseType extends JsonType>(
129 chargingStation: ChargingStation,
130 commandName: OCPP16RequestCommand,
131 commandParams?: JsonType,
132 params?: RequestParams
133 ): Promise<ResponseType> {
134 if (OCPP16ServiceUtils.isRequestCommandSupported(chargingStation, commandName) === true) {
135 return (await this.sendMessage(
136 chargingStation,
137 Utils.generateUUID(),
138 this.buildRequestPayload<RequestType>(chargingStation, commandName, commandParams),
139 commandName,
140 params
141 )) as ResponseType;
142 }
143 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
144 throw new OCPPError(
145 ErrorType.NOT_SUPPORTED,
146 `Unsupported OCPP command '${commandName}'`,
147 commandName,
148 commandParams
149 );
150 }
151
152 private buildRequestPayload<Request extends JsonType>(
153 chargingStation: ChargingStation,
154 commandName: OCPP16RequestCommand,
155 commandParams?: JsonType
156 ): Request {
157 let connectorId: number;
158 let energyActiveImportRegister: number;
159 commandParams = commandParams as JsonObject;
160 switch (commandName) {
161 case OCPP16RequestCommand.BOOT_NOTIFICATION:
162 case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION:
163 case OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION:
164 case OCPP16RequestCommand.METER_VALUES:
165 case OCPP16RequestCommand.STATUS_NOTIFICATION:
166 case OCPP16RequestCommand.DATA_TRANSFER:
167 return commandParams as unknown as Request;
168 case OCPP16RequestCommand.AUTHORIZE:
169 return {
170 idTag: Constants.DEFAULT_IDTAG,
171 ...commandParams,
172 } as unknown as Request;
173 case OCPP16RequestCommand.HEARTBEAT:
174 return OCPPConstants.OCPP_REQUEST_EMPTY as unknown as Request;
175 case OCPP16RequestCommand.START_TRANSACTION:
176 return {
177 idTag: Constants.DEFAULT_IDTAG,
178 meterStart: chargingStation.getEnergyActiveImportRegisterByConnectorId(
179 commandParams?.connectorId as number,
180 true
181 ),
182 timestamp: new Date(),
183 ...commandParams,
184 } as unknown as Request;
185 case OCPP16RequestCommand.STOP_TRANSACTION:
186 chargingStation.getTransactionDataMeterValues() &&
187 (connectorId = chargingStation.getConnectorIdByTransactionId(
188 commandParams?.transactionId as number
189 ));
190 energyActiveImportRegister = chargingStation.getEnergyActiveImportRegisterByTransactionId(
191 commandParams?.transactionId as number,
192 true
193 );
194 return {
195 idTag: chargingStation.getTransactionIdTag(commandParams?.transactionId as number),
196 meterStop: energyActiveImportRegister,
197 timestamp: new Date(),
198 ...(chargingStation.getTransactionDataMeterValues() && {
199 transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues(
200 chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue,
201 OCPP16ServiceUtils.buildTransactionEndMeterValue(
202 chargingStation,
203 connectorId,
204 energyActiveImportRegister
205 )
206 ),
207 }),
208 ...commandParams,
209 } as unknown as Request;
210 default:
211 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
212 throw new OCPPError(
213 ErrorType.NOT_SUPPORTED,
214 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
215 `Unsupported OCPP command '${commandName}'`,
216 commandName,
217 commandParams
218 );
219 }
220 }
221 }