1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import type { JSONSchemaType
} from
'ajv'
5 import { OCPP20ServiceUtils
} from
'./OCPP20ServiceUtils.js'
6 import type { ChargingStation
} from
'../../../charging-station/index.js'
7 import { OCPPError
} from
'../../../exception/index.js'
10 type IncomingRequestHandler
,
12 type OCPP20ClearCacheRequest
,
13 OCPP20IncomingRequestCommand
,
15 } from
'../../../types/index.js'
16 import { logger
} from
'../../../utils/index.js'
17 import { OCPPIncomingRequestService
} from
'../OCPPIncomingRequestService.js'
19 const moduleName
= 'OCPP20IncomingRequestService'
21 export class OCPP20IncomingRequestService
extends OCPPIncomingRequestService
{
22 protected jsonSchemas
: Map
<OCPP20IncomingRequestCommand
, JSONSchemaType
<JsonType
>>
23 private readonly incomingRequestHandlers
: Map
<
24 OCPP20IncomingRequestCommand
,
25 IncomingRequestHandler
28 public constructor () {
29 // if (new.target?.name === moduleName) {
30 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`)
32 super(OCPPVersion
.VERSION_20
)
33 this.incomingRequestHandlers
= new Map
<OCPP20IncomingRequestCommand
, IncomingRequestHandler
>([
34 [OCPP20IncomingRequestCommand
.CLEAR_CACHE
, this.handleRequestClearCache
.bind(this)]
36 this.jsonSchemas
= new Map
<OCPP20IncomingRequestCommand
, JSONSchemaType
<JsonType
>>([
38 OCPP20IncomingRequestCommand
.CLEAR_CACHE
,
39 OCPP20ServiceUtils
.parseJsonSchemaFile
<OCPP20ClearCacheRequest
>(
40 'assets/json-schemas/ocpp/2.0/ClearCacheRequest.json',
46 this.validatePayload
= this.validatePayload
.bind(this) as (
47 chargingStation
: ChargingStation
,
48 commandName
: OCPP20IncomingRequestCommand
,
49 commandPayload
: JsonType
53 public async incomingRequestHandler
<ReqType
extends JsonType
, ResType
extends JsonType
>(
54 chargingStation
: ChargingStation
,
56 commandName
: OCPP20IncomingRequestCommand
,
57 commandPayload
: ReqType
61 chargingStation
.stationInfo
?.ocppStrictCompliance
=== true &&
62 chargingStation
.inPendingState() &&
63 (commandName
=== OCPP20IncomingRequestCommand
.REQUEST_START_TRANSACTION
||
64 commandName
=== OCPP20IncomingRequestCommand
.REQUEST_STOP_TRANSACTION
)
67 ErrorType
.SECURITY_ERROR
,
68 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
72 )} while the charging station is in pending state on the central server`,
78 chargingStation
.isRegistered() ||
79 (chargingStation
.stationInfo
?.ocppStrictCompliance
=== false &&
80 chargingStation
.inUnknownState())
83 this.incomingRequestHandlers
.has(commandName
) &&
84 OCPP20ServiceUtils
.isIncomingRequestCommandSupported(chargingStation
, commandName
)
87 this.validatePayload(chargingStation
, commandName
, commandPayload
)
88 // Call the method to build the response
89 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
90 response
= (await this.incomingRequestHandlers
.get(commandName
)!(
97 `${chargingStation.logPrefix()} ${moduleName}.incomingRequestHandler: Handle incoming request error:`,
105 ErrorType
.NOT_IMPLEMENTED
,
106 `${commandName} is not implemented to handle request PDU ${JSON.stringify(
117 ErrorType
.SECURITY_ERROR
,
118 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
122 )} while the charging station is not registered on the central server.`,
127 // Send the built response
128 await chargingStation
.ocppRequestService
.sendResponse(
136 private validatePayload (
137 chargingStation
: ChargingStation
,
138 commandName
: OCPP20IncomingRequestCommand
,
139 commandPayload
: JsonType
141 if (this.jsonSchemas
.has(commandName
)) {
142 return this.validateIncomingRequestPayload(
145 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
146 this.jsonSchemas
.get(commandName
)!,
151 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`