chore(deps-dev): apply updates
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 2.0 / OCPP20IncomingRequestService.ts
CommitLineData
a19b897d 1// Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
953d6b02 2
24d15716 3import type { ValidateFunction } from 'ajv'
953d6b02 4
66a7748d 5import type { ChargingStation } from '../../../charging-station/index.js'
0749233f 6
66a7748d 7import { OCPPError } from '../../../exception/index.js'
d270cc87 8import {
268a74bb
JB
9 ErrorType,
10 type IncomingRequestHandler,
268a74bb 11 type JsonType,
81533a20 12 type OCPP20ClearCacheRequest,
d270cc87 13 OCPP20IncomingRequestCommand,
d1f5bfd8 14 OCPPVersion,
66a7748d 15} from '../../../types/index.js'
bcf95df1 16import { isAsyncFunction, logger } from '../../../utils/index.js'
66a7748d 17import { OCPPIncomingRequestService } from '../OCPPIncomingRequestService.js'
4c3f6c20 18import { OCPP20ServiceUtils } from './OCPP20ServiceUtils.js'
953d6b02 19
66a7748d 20const moduleName = 'OCPP20IncomingRequestService'
953d6b02 21
268a74bb 22export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
d5490a13 23 protected payloadValidateFunctions: Map<OCPP20IncomingRequestCommand, ValidateFunction<JsonType>>
24d15716 24
66a7748d 25 private readonly incomingRequestHandlers: Map<
d1f5bfd8
JB
26 OCPP20IncomingRequestCommand,
27 IncomingRequestHandler
66a7748d 28 >
953d6b02 29
66a7748d 30 public constructor () {
5199f9fd
JB
31 // if (new.target.name === moduleName) {
32 // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
b768993d 33 // }
1feac591 34 super(OCPPVersion.VERSION_201)
d270cc87 35 this.incomingRequestHandlers = new Map<OCPP20IncomingRequestCommand, IncomingRequestHandler>([
d1f5bfd8 36 [OCPP20IncomingRequestCommand.CLEAR_CACHE, this.handleRequestClearCache.bind(this)],
66a7748d 37 ])
d5490a13 38 this.payloadValidateFunctions = new Map<
d1f5bfd8
JB
39 OCPP20IncomingRequestCommand,
40 ValidateFunction<JsonType>
24d15716 41 >([
d270cc87
JB
42 [
43 OCPP20IncomingRequestCommand.CLEAR_CACHE,
d712a9a3
JB
44 this.ajv.compile(
45 OCPP20ServiceUtils.parseJsonSchemaFile<OCPP20ClearCacheRequest>(
46 'assets/json-schemas/ocpp/2.0/ClearCacheRequest.json',
47 moduleName,
48 'constructor'
49 )
50 ),
d1f5bfd8 51 ],
66a7748d 52 ])
ba9a56a6 53 this.validatePayload = this.validatePayload.bind(this)
953d6b02
JB
54 }
55
0749233f
JB
56 private validatePayload (
57 chargingStation: ChargingStation,
58 commandName: OCPP20IncomingRequestCommand,
59 commandPayload: JsonType
60 ): boolean {
61 if (this.payloadValidateFunctions.has(commandName)) {
62 return this.validateIncomingRequestPayload(chargingStation, commandName, commandPayload)
63 }
64 logger.warn(
65 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema validation function found for command '${commandName}' PDU validation`
66 )
67 return false
68 }
69
01841aad 70 // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
9429aa42 71 public async incomingRequestHandler<ReqType extends JsonType, ResType extends JsonType>(
953d6b02
JB
72 chargingStation: ChargingStation,
73 messageId: string,
74 commandName: OCPP20IncomingRequestCommand,
66a7748d 75 commandPayload: ReqType
953d6b02 76 ): Promise<void> {
66a7748d 77 let response: ResType
953d6b02 78 if (
5398cecf 79 chargingStation.stationInfo?.ocppStrictCompliance === true &&
66a7748d 80 chargingStation.inPendingState() &&
81533a20
JB
81 (commandName === OCPP20IncomingRequestCommand.REQUEST_START_TRANSACTION ||
82 commandName === OCPP20IncomingRequestCommand.REQUEST_STOP_TRANSACTION)
953d6b02
JB
83 ) {
84 throw new OCPPError(
85 ErrorType.SECURITY_ERROR,
86 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
87 commandPayload,
4ed03b6e 88 undefined,
66a7748d 89 2
953d6b02
JB
90 )} while the charging station is in pending state on the central server`,
91 commandName,
66a7748d
JB
92 commandPayload
93 )
953d6b02
JB
94 }
95 if (
66a7748d 96 chargingStation.isRegistered() ||
5398cecf 97 (chargingStation.stationInfo?.ocppStrictCompliance === false &&
66a7748d 98 chargingStation.inUnknownState())
953d6b02
JB
99 ) {
100 if (
66a7748d
JB
101 this.incomingRequestHandlers.has(commandName) &&
102 OCPP20ServiceUtils.isIncomingRequestCommandSupported(chargingStation, commandName)
953d6b02
JB
103 ) {
104 try {
66a7748d 105 this.validatePayload(chargingStation, commandName, commandPayload)
953d6b02 106 // Call the method to build the response
66a7748d 107 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
bcf95df1
JB
108 const incomingRequestHandler = this.incomingRequestHandlers.get(commandName)!
109 if (isAsyncFunction(incomingRequestHandler)) {
110 response = (await incomingRequestHandler(chargingStation, commandPayload)) as ResType
111 } else {
112 response = incomingRequestHandler(chargingStation, commandPayload) as ResType
113 }
953d6b02
JB
114 } catch (error) {
115 // Log
116 logger.error(
117 `${chargingStation.logPrefix()} ${moduleName}.incomingRequestHandler: Handle incoming request error:`,
66a7748d
JB
118 error
119 )
120 throw error
953d6b02
JB
121 }
122 } else {
123 // Throw exception
124 throw new OCPPError(
125 ErrorType.NOT_IMPLEMENTED,
3024d5b2 126 `${commandName} is not implemented to handle request PDU ${JSON.stringify(
953d6b02 127 commandPayload,
4ed03b6e 128 undefined,
66a7748d 129 2
953d6b02
JB
130 )}`,
131 commandName,
66a7748d
JB
132 commandPayload
133 )
953d6b02
JB
134 }
135 } else {
136 throw new OCPPError(
137 ErrorType.SECURITY_ERROR,
138 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
139 commandPayload,
4ed03b6e 140 undefined,
66a7748d 141 2
412cece8 142 )} while the charging station is not registered on the central server`,
953d6b02 143 commandName,
66a7748d
JB
144 commandPayload
145 )
953d6b02
JB
146 }
147 // Send the built response
148 await chargingStation.ocppRequestService.sendResponse(
149 chargingStation,
150 messageId,
151 response,
66a7748d
JB
152 commandName
153 )
868c6830 154 // Emit command name event to allow delayed handling
1b7eb386 155 this.emit(commandName, chargingStation, commandPayload, response)
953d6b02 156 }
953d6b02 157}