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