build: temporary silence linter errors
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / OCPPRequestService.ts
CommitLineData
ec0eebcc 1import Ajv, { type JSONSchemaType, type ValidateFunction } from 'ajv';
b52c969d
JB
2import ajvFormats from 'ajv-formats';
3
a6ef1ece
JB
4import { OCPPConstants } from './OCPPConstants.js';
5import type { OCPPResponseService } from './OCPPResponseService.js';
6import { OCPPServiceUtils } from './OCPPServiceUtils.js';
7import type { ChargingStation } from '../../charging-station/index.js';
8import { OCPPError } from '../../exception/index.js';
9import { PerformanceStatistics } from '../../performance/index.js';
e7aeea18 10import {
8baae8ee 11 ChargingStationEvents,
27782dbc 12 type ErrorCallback,
268a74bb
JB
13 type ErrorResponse,
14 ErrorType,
27782dbc 15 type IncomingRequestCommand,
268a74bb
JB
16 type JsonType,
17 MessageType,
18 type OCPPVersion,
27782dbc 19 type OutgoingRequest,
e7aeea18 20 RequestCommand,
27782dbc 21 type RequestParams,
268a74bb 22 type Response,
27782dbc 23 type ResponseCallback,
e0b0ee21 24 type ResponseType,
a6ef1ece 25} from '../../types/index.js';
2b94ad12
JB
26import {
27 cloneObject,
28 formatDurationMilliSeconds,
29 handleSendMessageError,
30 isNullOrUndefined,
31 logger,
a6ef1ece 32} from '../../utils/index.js';
c0560973 33
e3018bc4
JB
34const moduleName = 'OCPPRequestService';
35
b9da1bc2
JB
36const defaultRequestParams: RequestParams = {
37 skipBufferingOnError: false,
38 triggerMessage: false,
39 throwError: false,
40};
41
268a74bb 42export abstract class OCPPRequestService {
08f130a0 43 private static instance: OCPPRequestService | null = null;
d270cc87 44 private readonly version: OCPPVersion;
012ae1a9 45 private readonly ajv: Ajv;
9f2e3130 46 private readonly ocppResponseService: OCPPResponseService;
291b5ec8
JB
47 private readonly jsonValidateFunctions: Map<RequestCommand, ValidateFunction<JsonType>>;
48 protected abstract jsonSchemas: Map<RequestCommand, JSONSchemaType<JsonType>>;
c0560973 49
d270cc87
JB
50 protected constructor(version: OCPPVersion, ocppResponseService: OCPPResponseService) {
51 this.version = version;
8fc5fda4 52 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
45988780 53 this.ajv = new Ajv({
98fc1389 54 keywords: ['javaType'],
45988780
JB
55 multipleOfPrecision: 2,
56 });
9952c548 57 ajvFormats(this.ajv);
291b5ec8 58 this.jsonValidateFunctions = new Map<RequestCommand, ValidateFunction<JsonType>>();
d270cc87 59 this.ocppResponseService = ocppResponseService;
31f59c6d 60 this.requestHandler = this.requestHandler.bind(this) as <
e1d9a0f4 61 // eslint-disable-next-line @typescript-eslint/no-unused-vars
31f59c6d 62 ReqType extends JsonType,
5edd8ba0 63 ResType extends JsonType,
31f59c6d
JB
64 >(
65 chargingStation: ChargingStation,
66 commandName: RequestCommand,
67 commandParams?: JsonType,
5edd8ba0 68 params?: RequestParams,
31f59c6d
JB
69 ) => Promise<ResType>;
70 this.sendMessage = this.sendMessage.bind(this) as (
71 chargingStation: ChargingStation,
72 messageId: string,
73 messagePayload: JsonType,
74 commandName: RequestCommand,
5edd8ba0 75 params?: RequestParams,
31f59c6d
JB
76 ) => Promise<ResponseType>;
77 this.sendResponse = this.sendResponse.bind(this) as (
78 chargingStation: ChargingStation,
79 messageId: string,
80 messagePayload: JsonType,
5edd8ba0 81 commandName: IncomingRequestCommand,
31f59c6d
JB
82 ) => Promise<ResponseType>;
83 this.sendError = this.sendError.bind(this) as (
84 chargingStation: ChargingStation,
85 messageId: string,
86 ocppError: OCPPError,
5edd8ba0 87 commandName: RequestCommand | IncomingRequestCommand,
31f59c6d
JB
88 ) => Promise<ResponseType>;
89 this.internalSendMessage = this.internalSendMessage.bind(this) as (
90 chargingStation: ChargingStation,
91 messageId: string,
92 messagePayload: JsonType | OCPPError,
93 messageType: MessageType,
94 commandName: RequestCommand | IncomingRequestCommand,
5edd8ba0 95 params?: RequestParams,
31f59c6d
JB
96 ) => Promise<ResponseType>;
97 this.buildMessageToSend = this.buildMessageToSend.bind(this) as (
98 chargingStation: ChargingStation,
99 messageId: string,
100 messagePayload: JsonType | OCPPError,
101 messageType: MessageType,
102 commandName: RequestCommand | IncomingRequestCommand,
31f59c6d 103 ) => string;
291b5ec8 104 this.validateRequestPayload = this.validateRequestPayload.bind(this) as <T extends JsonType>(
31f59c6d
JB
105 chargingStation: ChargingStation,
106 commandName: RequestCommand | IncomingRequestCommand,
5edd8ba0 107 payload: T,
31f59c6d
JB
108 ) => boolean;
109 this.validateIncomingRequestResponsePayload = this.validateIncomingRequestResponsePayload.bind(
5edd8ba0 110 this,
291b5ec8 111 ) as <T extends JsonType>(
31f59c6d
JB
112 chargingStation: ChargingStation,
113 commandName: RequestCommand | IncomingRequestCommand,
5edd8ba0 114 payload: T,
31f59c6d 115 ) => boolean;
c0560973
JB
116 }
117
e7aeea18 118 public static getInstance<T extends OCPPRequestService>(
08f130a0 119 this: new (ocppResponseService: OCPPResponseService) => T,
5edd8ba0 120 ocppResponseService: OCPPResponseService,
e7aeea18 121 ): T {
1ca780f9 122 if (OCPPRequestService.instance === null) {
08f130a0 123 OCPPRequestService.instance = new this(ocppResponseService);
9f2e3130 124 }
08f130a0 125 return OCPPRequestService.instance as T;
9f2e3130
JB
126 }
127
c75a6675 128 public async sendResponse(
08f130a0 129 chargingStation: ChargingStation,
e7aeea18 130 messageId: string,
5cc4b63b 131 messagePayload: JsonType,
5edd8ba0 132 commandName: IncomingRequestCommand,
5eaabe90 133 ): Promise<ResponseType> {
5e0c67e8 134 try {
c75a6675 135 // Send response message
e7aeea18 136 return await this.internalSendMessage(
08f130a0 137 chargingStation,
e7aeea18
JB
138 messageId,
139 messagePayload,
140 MessageType.CALL_RESULT_MESSAGE,
5edd8ba0 141 commandName,
e7aeea18 142 );
5e0c67e8 143 } catch (error) {
fa5995d6 144 handleSendMessageError(chargingStation, commandName, error as Error, {
07561812 145 throwError: true,
dc922667 146 });
e1d9a0f4 147 return null;
5e0c67e8
JB
148 }
149 }
150
e7aeea18 151 public async sendError(
08f130a0 152 chargingStation: ChargingStation,
e7aeea18
JB
153 messageId: string,
154 ocppError: OCPPError,
5edd8ba0 155 commandName: RequestCommand | IncomingRequestCommand,
e7aeea18 156 ): Promise<ResponseType> {
5e0c67e8
JB
157 try {
158 // Send error message
e7aeea18 159 return await this.internalSendMessage(
08f130a0 160 chargingStation,
e7aeea18
JB
161 messageId,
162 ocppError,
163 MessageType.CALL_ERROR_MESSAGE,
5edd8ba0 164 commandName,
e7aeea18 165 );
5e0c67e8 166 } catch (error) {
fa5995d6 167 handleSendMessageError(chargingStation, commandName, error as Error);
e1d9a0f4 168 return null;
5e0c67e8
JB
169 }
170 }
171
e7aeea18 172 protected async sendMessage(
08f130a0 173 chargingStation: ChargingStation,
e7aeea18 174 messageId: string,
5cc4b63b 175 messagePayload: JsonType,
e7aeea18 176 commandName: RequestCommand,
7f3decca 177 params?: RequestParams,
e7aeea18 178 ): Promise<ResponseType> {
7b5dbe91 179 params = {
b9da1bc2 180 ...defaultRequestParams,
7b5dbe91
JB
181 ...params,
182 };
5e0c67e8 183 try {
e7aeea18 184 return await this.internalSendMessage(
08f130a0 185 chargingStation,
e7aeea18
JB
186 messageId,
187 messagePayload,
188 MessageType.CALL_MESSAGE,
189 commandName,
5edd8ba0 190 params,
e7aeea18 191 );
5e0c67e8 192 } catch (error) {
fa5995d6 193 handleSendMessageError(chargingStation, commandName, error as Error, {
8ec8e3d0
JB
194 throwError: params.throwError,
195 });
e1d9a0f4 196 return null;
5e0c67e8
JB
197 }
198 }
199
291b5ec8 200 private validateRequestPayload<T extends JsonType>(
b52c969d 201 chargingStation: ChargingStation,
45988780 202 commandName: RequestCommand | IncomingRequestCommand,
5edd8ba0 203 payload: T,
b52c969d 204 ): boolean {
5398cecf 205 if (chargingStation.stationInfo?.ocppStrictCompliance === false) {
b52c969d
JB
206 return true;
207 }
b3fc3ff5
JB
208 if (this.jsonSchemas.has(commandName as RequestCommand) === false) {
209 logger.warn(
5edd8ba0 210 `${chargingStation.logPrefix()} ${moduleName}.validateRequestPayload: No JSON schema found for command '${commandName}' PDU validation`,
b3fc3ff5 211 );
45988780
JB
212 return true;
213 }
0b0ca54f 214 const validate = this.getJsonRequestValidateFunction<T>(commandName as RequestCommand);
9bf0ef23 215 payload = cloneObject<T>(payload);
1799761a 216 OCPPServiceUtils.convertDateToISOString<T>(payload);
b52c969d
JB
217 if (validate(payload)) {
218 return true;
219 }
220 logger.error(
45988780 221 `${chargingStation.logPrefix()} ${moduleName}.validateRequestPayload: Command '${commandName}' request PDU is invalid: %j`,
5edd8ba0 222 validate.errors,
b52c969d 223 );
e909d2a7 224 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
b52c969d 225 throw new OCPPError(
9ff486f4 226 OCPPServiceUtils.ajvErrorsToErrorType(validate.errors),
b52c969d
JB
227 'Request PDU is invalid',
228 commandName,
4ed03b6e 229 JSON.stringify(validate.errors, undefined, 2),
b52c969d
JB
230 );
231 }
232
0b0ca54f
JB
233 private getJsonRequestValidateFunction<T extends JsonType>(commandName: RequestCommand) {
234 if (this.jsonValidateFunctions.has(commandName) === false) {
235 this.jsonValidateFunctions.set(
236 commandName,
8fc5fda4 237 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
0b0ca54f
JB
238 this.ajv.compile<T>(this.jsonSchemas.get(commandName)!).bind(this),
239 );
240 }
241 return this.jsonValidateFunctions.get(commandName)!;
242 }
243
291b5ec8 244 private validateIncomingRequestResponsePayload<T extends JsonType>(
b3fc3ff5
JB
245 chargingStation: ChargingStation,
246 commandName: RequestCommand | IncomingRequestCommand,
5edd8ba0 247 payload: T,
b3fc3ff5 248 ): boolean {
5398cecf 249 if (chargingStation.stationInfo?.ocppStrictCompliance === false) {
b3fc3ff5
JB
250 return true;
251 }
252 if (
253 this.ocppResponseService.jsonIncomingRequestResponseSchemas.has(
5edd8ba0 254 commandName as IncomingRequestCommand,
b3fc3ff5
JB
255 ) === false
256 ) {
257 logger.warn(
5edd8ba0 258 `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestResponsePayload: No JSON schema found for command '${commandName}' PDU validation`,
b3fc3ff5
JB
259 );
260 return true;
261 }
0b0ca54f 262 const validate = this.getJsonRequestResponseValidateFunction<T>(
ec0eebcc 263 commandName as IncomingRequestCommand,
0b0ca54f 264 );
9bf0ef23 265 payload = cloneObject<T>(payload);
b3fc3ff5
JB
266 OCPPServiceUtils.convertDateToISOString<T>(payload);
267 if (validate(payload)) {
268 return true;
269 }
270 logger.error(
02887891 271 `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestResponsePayload: Command '${commandName}' reponse PDU is invalid: %j`,
5edd8ba0 272 validate.errors,
b3fc3ff5
JB
273 );
274 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
275 throw new OCPPError(
9ff486f4 276 OCPPServiceUtils.ajvErrorsToErrorType(validate.errors),
b3fc3ff5
JB
277 'Response PDU is invalid',
278 commandName,
4ed03b6e 279 JSON.stringify(validate.errors, undefined, 2),
b3fc3ff5
JB
280 );
281 }
282
0b0ca54f
JB
283 private getJsonRequestResponseValidateFunction<T extends JsonType>(
284 commandName: IncomingRequestCommand,
285 ) {
286 if (
287 this.ocppResponseService.jsonIncomingRequestResponseValidateFunctions.has(commandName) ===
288 false
289 ) {
290 this.ocppResponseService.jsonIncomingRequestResponseValidateFunctions.set(
291 commandName,
8fc5fda4 292 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call
0b0ca54f 293 this.ajv
8fc5fda4 294 // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
0b0ca54f 295 .compile<T>(this.ocppResponseService.jsonIncomingRequestResponseSchemas.get(commandName)!)
8fc5fda4 296 // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
0b0ca54f
JB
297 .bind(this),
298 );
299 }
300 return this.ocppResponseService.jsonIncomingRequestResponseValidateFunctions.get(commandName)!;
301 }
302
e7aeea18 303 private async internalSendMessage(
08f130a0 304 chargingStation: ChargingStation,
e7aeea18 305 messageId: string,
5cc4b63b 306 messagePayload: JsonType | OCPPError,
e7aeea18 307 messageType: MessageType,
72092cfc 308 commandName: RequestCommand | IncomingRequestCommand,
7f3decca 309 params?: RequestParams,
e7aeea18 310 ): Promise<ResponseType> {
7b5dbe91 311 params = {
b9da1bc2 312 ...defaultRequestParams,
7b5dbe91
JB
313 ...params,
314 };
e7aeea18 315 if (
f7c2994d 316 (chargingStation.inUnknownState() === true &&
3a13fc92 317 commandName === RequestCommand.BOOT_NOTIFICATION) ||
5398cecf 318 (chargingStation.stationInfo?.ocppStrictCompliance === false &&
f7c2994d
JB
319 chargingStation.inUnknownState() === true) ||
320 chargingStation.inAcceptedState() === true ||
321 (chargingStation.inPendingState() === true &&
3a13fc92 322 (params.triggerMessage === true || messageType === MessageType.CALL_RESULT_MESSAGE))
e7aeea18 323 ) {
caad9d6b
JB
324 // eslint-disable-next-line @typescript-eslint/no-this-alias
325 const self = this;
326 // Send a message through wsConnection
5b2721db 327 return new Promise<ResponseType>((resolve, reject) => {
1b2acf4e
JB
328 /**
329 * Function that will receive the request's response
330 *
331 * @param payload -
332 * @param requestPayload -
333 */
334 const responseCallback = (payload: JsonType, requestPayload: JsonType): void => {
335 if (chargingStation.stationInfo?.enableStatistics === true) {
336 chargingStation.performanceStatistics?.addRequestStatistic(
337 commandName,
338 MessageType.CALL_RESULT_MESSAGE,
e8a92d57 339 );
1b2acf4e
JB
340 }
341 // Handle the request's response
342 self.ocppResponseService
343 .responseHandler(
344 chargingStation,
345 commandName as RequestCommand,
346 payload,
347 requestPayload,
348 )
349 .then(() => {
350 resolve(payload);
351 })
b7ee97c1 352 .catch(reject)
1b2acf4e
JB
353 .finally(() => {
354 chargingStation.requests.delete(messageId);
8baae8ee 355 chargingStation.emit(ChargingStationEvents.updated);
1b2acf4e
JB
356 });
357 };
e8a92d57 358
1b2acf4e
JB
359 /**
360 * Function that will receive the request's error response
361 *
9d7b5fa3 362 * @param ocppError -
1b2acf4e
JB
363 * @param requestStatistic -
364 */
9d7b5fa3 365 const errorCallback = (ocppError: OCPPError, requestStatistic = true): void => {
1b2acf4e
JB
366 if (requestStatistic === true && chargingStation.stationInfo?.enableStatistics === true) {
367 chargingStation.performanceStatistics?.addRequestStatistic(
368 commandName,
369 MessageType.CALL_ERROR_MESSAGE,
370 );
764d2c91 371 }
1b2acf4e
JB
372 logger.error(
373 `${chargingStation.logPrefix()} Error occurred at ${OCPPServiceUtils.getMessageTypeString(
374 messageType,
375 )} command ${commandName} with PDU %j:`,
e7aeea18 376 messagePayload,
9d7b5fa3 377 ocppError,
e7aeea18 378 );
1b2acf4e 379 chargingStation.requests.delete(messageId);
8baae8ee 380 chargingStation.emit(ChargingStationEvents.updated);
9d7b5fa3
JB
381 reject(ocppError);
382 };
383
3c80de96
JB
384 const handleSendError = (ocppError: OCPPError): void => {
385 if (params?.skipBufferingOnError === false) {
386 // Buffer
387 chargingStation.bufferMessage(messageToSend);
388 if (messageType === MessageType.CALL_MESSAGE) {
389 this.cacheRequestPromise(
390 chargingStation,
391 messageId,
392 messagePayload as JsonType,
393 commandName,
394 responseCallback,
395 errorCallback,
396 );
397 }
9aa1a33f
JB
398 } else if (
399 params?.skipBufferingOnError === true &&
400 messageType === MessageType.CALL_MESSAGE
401 ) {
2b94ad12
JB
402 // Remove request from the cache
403 chargingStation.requests.delete(messageId);
d42379d8 404 }
2b94ad12 405 return reject(ocppError);
d42379d8
JB
406 };
407
1b2acf4e
JB
408 if (chargingStation.stationInfo?.enableStatistics === true) {
409 chargingStation.performanceStatistics?.addRequestStatistic(commandName, messageType);
410 }
411 const messageToSend = this.buildMessageToSend(
412 chargingStation,
413 messageId,
414 messagePayload,
415 messageType,
416 commandName,
1b2acf4e 417 );
1b2acf4e 418 // Check if wsConnection opened
1a32c36b 419 if (chargingStation.isWebSocketConnectionOpened() === true) {
1b2acf4e 420 const beginId = PerformanceStatistics.beginMeasure(commandName);
1a32c36b 421 const sendTimeout = setTimeout(() => {
2b94ad12 422 return handleSendError(
1a32c36b
JB
423 new OCPPError(
424 ErrorType.GENERIC_ERROR,
2b94ad12
JB
425 `Timeout ${formatDurationMilliSeconds(
426 OCPPConstants.OCPP_WEBSOCKET_TIMEOUT,
427 )} reached for ${
428 params?.skipBufferingOnError === false ? '' : 'non '
42b8cf5c 429 }buffered message id '${messageId}' with content '${messageToSend}'`,
1a32c36b 430 commandName,
7375968c 431 (messagePayload as OCPPError).details,
1a32c36b 432 ),
1a32c36b
JB
433 );
434 }, OCPPConstants.OCPP_WEBSOCKET_TIMEOUT);
435 chargingStation.wsConnection?.send(messageToSend, (error?: Error) => {
d42379d8 436 PerformanceStatistics.endMeasure(commandName, beginId);
82fa1110 437 clearTimeout(sendTimeout);
d42379d8
JB
438 if (isNullOrUndefined(error)) {
439 logger.debug(
440 `${chargingStation.logPrefix()} >> Command '${commandName}' sent ${OCPPServiceUtils.getMessageTypeString(
441 messageType,
442 )} payload: ${messageToSend}`,
443 );
444 if (messageType === MessageType.CALL_MESSAGE) {
445 this.cacheRequestPromise(
446 chargingStation,
447 messageId,
448 messagePayload as JsonType,
449 commandName,
450 responseCallback,
451 errorCallback,
452 );
69dae411
JB
453 } else {
454 // Resolve response
d42379d8
JB
455 return resolve(messagePayload);
456 }
457 } else if (error) {
3c80de96
JB
458 return handleSendError(
459 new OCPPError(
460 ErrorType.GENERIC_ERROR,
461 `WebSocket errored for ${
462 params?.skipBufferingOnError === false ? '' : 'non '
463 }buffered message id '${messageId}' with content '${messageToSend}'`,
464 commandName,
465 { name: error.name, message: error.message, stack: error.stack },
466 ),
1a32c36b 467 );
1a32c36b 468 }
1a32c36b 469 });
82fa1110 470 } else {
3c80de96
JB
471 return handleSendError(
472 new OCPPError(
473 ErrorType.GENERIC_ERROR,
474 `WebSocket closed for ${
475 params?.skipBufferingOnError === false ? '' : 'non '
476 }buffered message id '${messageId}' with content '${messageToSend}'`,
477 commandName,
e3fd8f6d 478 (messagePayload as OCPPError).details,
3c80de96 479 ),
9d7b5fa3 480 );
1b2acf4e 481 }
1b2acf4e 482 });
caad9d6b 483 }
e7aeea18
JB
484 throw new OCPPError(
485 ErrorType.SECURITY_ERROR,
05e2446f 486 `Cannot send command ${commandName} PDU when the charging station is in ${chargingStation?.bootNotificationResponse?.status} state on the central server`,
5edd8ba0 487 commandName,
e7aeea18 488 );
c0560973
JB
489 }
490
e7aeea18 491 private buildMessageToSend(
08f130a0 492 chargingStation: ChargingStation,
e7aeea18 493 messageId: string,
5cc4b63b 494 messagePayload: JsonType | OCPPError,
e7aeea18 495 messageType: MessageType,
72092cfc 496 commandName: RequestCommand | IncomingRequestCommand,
e7aeea18 497 ): string {
e7accadb
JB
498 let messageToSend: string;
499 // Type of message
500 switch (messageType) {
501 // Request
502 case MessageType.CALL_MESSAGE:
503 // Build request
291b5ec8 504 this.validateRequestPayload(chargingStation, commandName, messagePayload as JsonType);
b3ec7bc1
JB
505 messageToSend = JSON.stringify([
506 messageType,
507 messageId,
508 commandName,
509 messagePayload,
510 ] as OutgoingRequest);
e7accadb
JB
511 break;
512 // Response
513 case MessageType.CALL_RESULT_MESSAGE:
514 // Build response
02887891
JB
515 this.validateIncomingRequestResponsePayload(
516 chargingStation,
517 commandName,
291b5ec8 518 messagePayload as JsonType,
02887891 519 );
b3ec7bc1 520 messageToSend = JSON.stringify([messageType, messageId, messagePayload] as Response);
e7accadb
JB
521 break;
522 // Error Message
523 case MessageType.CALL_ERROR_MESSAGE:
524 // Build Error Message
e7aeea18
JB
525 messageToSend = JSON.stringify([
526 messageType,
527 messageId,
7375968c
JB
528 (messagePayload as OCPPError).code,
529 (messagePayload as OCPPError).message,
530 (messagePayload as OCPPError).details ?? {
531 command: (messagePayload as OCPPError).command ?? commandName,
532 },
b3ec7bc1 533 ] as ErrorResponse);
e7accadb
JB
534 break;
535 }
536 return messageToSend;
537 }
538
82fa1110
JB
539 private cacheRequestPromise(
540 chargingStation: ChargingStation,
82fa1110
JB
541 messageId: string,
542 messagePayload: JsonType,
543 commandName: RequestCommand | IncomingRequestCommand,
54a8fbc7
JB
544 responseCallback: ResponseCallback,
545 errorCallback: ErrorCallback,
82fa1110
JB
546 ): void {
547 chargingStation.requests.set(messageId, [
548 responseCallback,
549 errorCallback,
550 commandName,
551 messagePayload,
552 ]);
553 }
554
ef6fa3fb 555 // eslint-disable-next-line @typescript-eslint/no-unused-vars
e0b0ee21 556 public abstract requestHandler<ReqType extends JsonType, ResType extends JsonType>(
08f130a0 557 chargingStation: ChargingStation,
94a464f9 558 commandName: RequestCommand,
e1d9a0f4 559 // FIXME: should be ReqType
5cc4b63b 560 commandParams?: JsonType,
5edd8ba0 561 params?: RequestParams,
e0b0ee21 562 ): Promise<ResType>;
c0560973 563}