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