chore: version 1.1.94
[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
78202038 5import { OCPP16ServiceUtils } from './OCPP16ServiceUtils';
8114d10e 6import OCPPError from '../../../exception/OCPPError';
6c1761d4
JB
7import type { JsonObject, JsonType } from '../../../types/JsonType';
8import type { OCPP16MeterValuesRequest } from '../../../types/ocpp/1.6/MeterValues';
b52c969d 9import {
27782dbc
JB
10 type OCPP16BootNotificationRequest,
11 type OCPP16DataTransferRequest,
c9a4f9ea 12 type OCPP16DiagnosticsStatusNotificationRequest,
e9a4164c 13 type OCPP16FirmwareStatusNotificationRequest,
27782dbc 14 type OCPP16HeartbeatRequest,
b52c969d 15 OCPP16RequestCommand,
27782dbc 16 type OCPP16StatusNotificationRequest,
b52c969d 17} from '../../../types/ocpp/1.6/Requests';
6c1761d4 18import type {
b52c969d
JB
19 OCPP16AuthorizeRequest,
20 OCPP16StartTransactionRequest,
21 OCPP16StopTransactionRequest,
22} from '../../../types/ocpp/1.6/Transaction';
8114d10e 23import { ErrorType } from '../../../types/ocpp/ErrorType';
d270cc87 24import { OCPPVersion } from '../../../types/ocpp/OCPPVersion';
6c1761d4 25import type { RequestParams } from '../../../types/ocpp/Requests';
8114d10e 26import Constants from '../../../utils/Constants';
c0560973 27import Utils from '../../../utils/Utils';
8114d10e 28import type ChargingStation from '../../ChargingStation';
4d20f040 29import OCPPConstants from '../OCPPConstants';
8114d10e
JB
30import OCPPRequestService from '../OCPPRequestService';
31import type OCPPResponseService from '../OCPPResponseService';
c0560973 32
909dcf2d
JB
33const moduleName = 'OCPP16RequestService';
34
c0560973 35export default class OCPP16RequestService extends OCPPRequestService {
b3fc3ff5 36 protected jsonSchemas: Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>;
b52c969d 37
08f130a0 38 public constructor(ocppResponseService: OCPPResponseService) {
909dcf2d 39 if (new.target?.name === moduleName) {
06127450 40 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
9f2e3130 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
6c1761d4 141 )) as unknown 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}