Commit | Line | Data |
---|---|---|
c0560973 | 1 | import { AuthorizeResponse, StartTransactionResponse, StopTransactionReason, StopTransactionResponse } from '../../types/ocpp/Transaction'; |
47e22477 | 2 | import { DiagnosticsStatus, IncomingRequestCommand, RequestCommand } from '../../types/ocpp/Requests'; |
c0560973 | 3 | |
efa43e52 | 4 | import { BootNotificationResponse } from '../../types/ocpp/Responses'; |
c0560973 JB |
5 | import { ChargePointErrorCode } from '../../types/ocpp/ChargePointErrorCode'; |
6 | import { ChargePointStatus } from '../../types/ocpp/ChargePointStatus'; | |
7 | import ChargingStation from '../ChargingStation'; | |
8 | import Constants from '../../utils/Constants'; | |
9 | import { ErrorType } from '../../types/ocpp/ErrorType'; | |
10 | import { MessageType } from '../../types/ocpp/MessageType'; | |
fd0c36fa | 11 | import { MeterValue } from '../../types/ocpp/MeterValues'; |
14763b46 | 12 | import OCPPError from './OCPPError'; |
c0560973 | 13 | import OCPPResponseService from './OCPPResponseService'; |
a6b3c6c3 | 14 | import PerformanceStatistics from '../../performance/PerformanceStatistics'; |
c0560973 JB |
15 | import logger from '../../utils/Logger'; |
16 | ||
17 | export default abstract class OCPPRequestService { | |
18 | public chargingStation: ChargingStation; | |
19 | protected ocppResponseService: OCPPResponseService; | |
20 | ||
21 | constructor(chargingStation: ChargingStation, ocppResponseService: OCPPResponseService) { | |
22 | this.chargingStation = chargingStation; | |
23 | this.ocppResponseService = ocppResponseService; | |
24 | } | |
25 | ||
a6b3c6c3 | 26 | public async sendMessage(messageId: string, commandParams: any, messageType: MessageType, commandName: RequestCommand | IncomingRequestCommand, |
9292e32a | 27 | skipBufferingOnError = false): Promise<unknown> { |
c0560973 JB |
28 | // eslint-disable-next-line @typescript-eslint/no-this-alias |
29 | const self = this; | |
c0560973 JB |
30 | // Send a message through wsConnection |
31 | return new Promise((resolve: (value?: any | PromiseLike<any>) => void, reject: (reason?: any) => void) => { | |
32 | let messageToSend: string; | |
33 | // Type of message | |
34 | switch (messageType) { | |
35 | // Request | |
36 | case MessageType.CALL_MESSAGE: | |
37 | // Build request | |
16b0d4e7 | 38 | this.chargingStation.requests.set(messageId, [responseCallback, rejectCallback, commandParams as Record<string, unknown>]); |
c0560973 JB |
39 | messageToSend = JSON.stringify([messageType, messageId, commandName, commandParams]); |
40 | break; | |
41 | // Response | |
42 | case MessageType.CALL_RESULT_MESSAGE: | |
43 | // Build response | |
44 | messageToSend = JSON.stringify([messageType, messageId, commandParams]); | |
45 | break; | |
46 | // Error Message | |
47 | case MessageType.CALL_ERROR_MESSAGE: | |
48 | // Build Error Message | |
5e5a3ab7 | 49 | messageToSend = JSON.stringify([messageType, messageId, commandParams?.code ?? ErrorType.GENERIC_ERROR, commandParams?.message ?? '', commandParams?.details ?? {}]); |
c0560973 JB |
50 | break; |
51 | } | |
a6b3c6c3 JB |
52 | if (this.chargingStation.getEnableStatistics()) { |
53 | this.chargingStation.performanceStatistics.addRequestStatistic(commandName, messageType); | |
54 | } | |
55 | // Check if wsConnection opened | |
56 | if (this.chargingStation.isWebSocketConnectionOpened()) { | |
c0560973 | 57 | // Yes: Send Message |
aef1b33a | 58 | const beginId = PerformanceStatistics.beginMeasure(commandName); |
c0560973 | 59 | this.chargingStation.wsConnection.send(messageToSend); |
aef1b33a | 60 | PerformanceStatistics.endMeasure(commandName, beginId); |
9292e32a | 61 | } else if (!skipBufferingOnError) { |
3ba2381e | 62 | // Buffer it |
77f00f84 | 63 | this.chargingStation.addToMessageQueue(messageToSend); |
c0560973 | 64 | // Reject it |
3582e6fe | 65 | return rejectCallback(new OCPPError(commandParams?.code ?? ErrorType.GENERIC_ERROR, commandParams?.message ?? `WebSocket closed for message id '${messageId}' with content '${messageToSend}', message buffered`, commandParams?.details ?? {})); |
c0560973 JB |
66 | } |
67 | // Response? | |
68 | if (messageType === MessageType.CALL_RESULT_MESSAGE) { | |
69 | // Yes: send Ok | |
70 | resolve(); | |
71 | } else if (messageType === MessageType.CALL_ERROR_MESSAGE) { | |
72 | // Send timeout | |
5e5a3ab7 | 73 | setTimeout(() => rejectCallback(new OCPPError(commandParams?.code ?? ErrorType.GENERIC_ERROR, commandParams?.message ?? `Timeout for message id '${messageId}' with content '${messageToSend}'`, commandParams?.details ?? {})), Constants.OCPP_ERROR_TIMEOUT); |
c0560973 JB |
74 | } |
75 | ||
3340259a JB |
76 | /** |
77 | * Function that will receive the request's response | |
78 | * | |
81797102 JB |
79 | * @param payload |
80 | * @param requestPayload | |
3340259a | 81 | */ |
c0560973 | 82 | async function responseCallback(payload: Record<string, unknown> | string, requestPayload: Record<string, unknown>): Promise<void> { |
52748e2c | 83 | if (self.chargingStation.getEnableStatistics()) { |
aef1b33a | 84 | self.chargingStation.performanceStatistics.addRequestStatistic(commandName, MessageType.CALL_RESULT_MESSAGE); |
c0560973 JB |
85 | } |
86 | // Send the response | |
87 | await self.ocppResponseService.handleResponse(commandName as RequestCommand, payload, requestPayload); | |
88 | resolve(payload); | |
89 | } | |
90 | ||
3340259a JB |
91 | /** |
92 | * Function that will receive the request's rejection | |
93 | * | |
81797102 | 94 | * @param error |
3340259a | 95 | */ |
c0560973 | 96 | function rejectCallback(error: OCPPError): void { |
52748e2c | 97 | if (self.chargingStation.getEnableStatistics()) { |
aef1b33a | 98 | self.chargingStation.performanceStatistics.addRequestStatistic(commandName, MessageType.CALL_ERROR_MESSAGE); |
c0560973 | 99 | } |
52748e2c | 100 | logger.debug(`${self.chargingStation.logPrefix()} Error: %j occurred when calling command %s with parameters: %j`, error, commandName, commandParams); |
c0560973 JB |
101 | // Build Exception |
102 | // eslint-disable-next-line no-empty-function | |
16b0d4e7 | 103 | self.chargingStation.requests.set(messageId, [() => { }, () => { }, {}]); |
c0560973 JB |
104 | // Send error |
105 | reject(error); | |
106 | } | |
107 | }); | |
108 | } | |
109 | ||
c7f95d16 | 110 | protected handleRequestError(commandName: RequestCommand, error: Error): void { |
47e22477 | 111 | logger.error(this.chargingStation.logPrefix() + ' Request command ' + commandName + ' error: %j', error); |
c0560973 JB |
112 | throw error; |
113 | } | |
114 | ||
115 | public abstract sendHeartbeat(): Promise<void>; | |
116 | public abstract sendBootNotification(chargePointModel: string, chargePointVendor: string, chargeBoxSerialNumber?: string, firmwareVersion?: string, chargePointSerialNumber?: string, iccid?: string, imsi?: string, meterSerialNumber?: string, meterType?: string): Promise<BootNotificationResponse>; | |
117 | public abstract sendStatusNotification(connectorId: number, status: ChargePointStatus, errorCode?: ChargePointErrorCode): Promise<void>; | |
163547b1 | 118 | public abstract sendAuthorize(connectorId: number, idTag?: string): Promise<AuthorizeResponse>; |
c0560973 JB |
119 | public abstract sendStartTransaction(connectorId: number, idTag?: string): Promise<StartTransactionResponse>; |
120 | public abstract sendStopTransaction(transactionId: number, meterStop: number, idTag?: string, reason?: StopTransactionReason): Promise<StopTransactionResponse>; | |
aef1b33a | 121 | public abstract sendMeterValues(connectorId: number, transactionId: number, interval: number): Promise<void>; |
fd0c36fa JB |
122 | public abstract sendTransactionBeginMeterValues(connectorId: number, transactionId: number, beginMeterValue: MeterValue): Promise<void>; |
123 | public abstract sendTransactionEndMeterValues(connectorId: number, transactionId: number, endMeterValue: MeterValue): Promise<void>; | |
47e22477 | 124 | public abstract sendDiagnosticsStatusNotification(diagnosticsStatus: DiagnosticsStatus): Promise<void>; |
c0560973 | 125 | public abstract sendError(messageId: string, error: OCPPError, commandName: RequestCommand | IncomingRequestCommand): Promise<unknown>; |
c0560973 | 126 | } |