1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import type { JSONSchemaType
} from
'ajv';
5 import { OCPP20ServiceUtils
} from
'./OCPP20ServiceUtils';
6 import type { ChargingStation
} from
'../../../charging-station';
7 import { OCPPError
} from
'../../../exception';
10 type IncomingRequestHandler
,
13 type OCPP20ClearCacheRequest
,
14 OCPP20IncomingRequestCommand
,
16 } from
'../../../types';
17 import { logger
} from
'../../../utils';
18 import { OCPPIncomingRequestService
} from
'../OCPPIncomingRequestService';
20 const moduleName
= 'OCPP20IncomingRequestService';
22 export class OCPP20IncomingRequestService
extends OCPPIncomingRequestService
{
23 protected jsonSchemas
: Map
<OCPP20IncomingRequestCommand
, JSONSchemaType
<JsonObject
>>;
24 private incomingRequestHandlers
: Map
<OCPP20IncomingRequestCommand
, IncomingRequestHandler
>;
26 public constructor() {
27 // if (new.target?.name === moduleName) {
28 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
30 super(OCPPVersion
.VERSION_20
);
31 this.incomingRequestHandlers
= new Map
<OCPP20IncomingRequestCommand
, IncomingRequestHandler
>([
32 [OCPP20IncomingRequestCommand
.CLEAR_CACHE
, this.handleRequestClearCache
.bind(this)],
34 this.jsonSchemas
= new Map
<OCPP20IncomingRequestCommand
, JSONSchemaType
<JsonObject
>>([
36 OCPP20IncomingRequestCommand
.CLEAR_CACHE
,
37 OCPP20ServiceUtils
.parseJsonSchemaFile
<OCPP20ClearCacheRequest
>(
38 'assets/json-schemas/ocpp/2.0/ClearCacheRequest.json',
44 this.validatePayload
= this.validatePayload
.bind(this) as (
45 chargingStation
: ChargingStation
,
46 commandName
: OCPP20IncomingRequestCommand
,
47 commandPayload
: JsonType
,
51 public async incomingRequestHandler
<ReqType
extends JsonType
, ResType
extends JsonType
>(
52 chargingStation
: ChargingStation
,
54 commandName
: OCPP20IncomingRequestCommand
,
55 commandPayload
: ReqType
,
57 let response
: ResType
;
59 chargingStation
.getOcppStrictCompliance() === true &&
60 chargingStation
.inPendingState() === true &&
61 (commandName
=== OCPP20IncomingRequestCommand
.REQUEST_START_TRANSACTION
||
62 commandName
=== OCPP20IncomingRequestCommand
.REQUEST_STOP_TRANSACTION
)
65 ErrorType
.SECURITY_ERROR
,
66 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
70 )} while the charging station is in pending state on the central server`,
76 chargingStation
.isRegistered() === true ||
77 (chargingStation
.getOcppStrictCompliance() === false &&
78 chargingStation
.inUnknownState() === true)
81 this.incomingRequestHandlers
.has(commandName
) === true &&
82 OCPP20ServiceUtils
.isIncomingRequestCommandSupported(chargingStation
, commandName
) === true
85 this.validatePayload(chargingStation
, commandName
, commandPayload
);
86 // Call the method to build the response
87 response
= (await this.incomingRequestHandlers
.get(commandName
)!(
94 `${chargingStation.logPrefix()} ${moduleName}.incomingRequestHandler: Handle incoming request error:`,
102 ErrorType
.NOT_IMPLEMENTED
,
103 `${commandName} is not implemented to handle request PDU ${JSON.stringify(
114 ErrorType
.SECURITY_ERROR
,
115 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
119 )} while the charging station is not registered on the central server.`,
124 // Send the built response
125 await chargingStation
.ocppRequestService
.sendResponse(
133 private validatePayload(
134 chargingStation
: ChargingStation
,
135 commandName
: OCPP20IncomingRequestCommand
,
136 commandPayload
: JsonType
,
138 if (this.jsonSchemas
.has(commandName
) === true) {
139 return this.validateIncomingRequestPayload(
142 this.jsonSchemas
.get(commandName
)!,
147 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`,