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