1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
4 import path from
'path';
5 import { fileURLToPath
} from
'url';
7 import type { JSONSchemaType
} from
'ajv';
9 import { OCPP20ServiceUtils
} from
'./OCPP20ServiceUtils';
10 import OCPPError from
'../../../exception/OCPPError';
11 import type { JsonObject
, JsonType
} from
'../../../types/JsonType';
13 type OCPP20ClearCacheRequest
,
14 OCPP20IncomingRequestCommand
,
15 } from
'../../../types/ocpp/2.0/Requests';
16 import { ErrorType
} from
'../../../types/ocpp/ErrorType';
17 import { OCPPVersion
} from
'../../../types/ocpp/OCPPVersion';
18 import type { IncomingRequestHandler
} from
'../../../types/ocpp/Requests';
19 import logger from
'../../../utils/Logger';
20 import type ChargingStation from
'../../ChargingStation';
21 import OCPPIncomingRequestService from
'../OCPPIncomingRequestService';
23 const moduleName
= 'OCPP20IncomingRequestService';
25 export default class OCPP20IncomingRequestService
extends OCPPIncomingRequestService
{
26 protected jsonSchemas
: Map
<OCPP20IncomingRequestCommand
, JSONSchemaType
<JsonObject
>>;
27 private incomingRequestHandlers
: Map
<OCPP20IncomingRequestCommand
, IncomingRequestHandler
>;
29 public constructor() {
30 if (new.target
?.name
=== moduleName
) {
31 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
33 super(OCPPVersion
.VERSION_20
);
34 this.incomingRequestHandlers
= new Map
<OCPP20IncomingRequestCommand
, IncomingRequestHandler
>([
35 [OCPP20IncomingRequestCommand
.CLEAR_CACHE
, this.handleRequestClearCache
.bind(this)],
37 this.jsonSchemas
= new Map
<OCPP20IncomingRequestCommand
, JSONSchemaType
<JsonObject
>>([
39 OCPP20IncomingRequestCommand
.CLEAR_CACHE
,
40 this.parseJsonSchemaFile
<OCPP20ClearCacheRequest
>(
41 '../../../assets/json-schemas/ocpp/2.0/ClearCacheRequest.json'
45 this.validatePayload
.bind(this);
48 public async incomingRequestHandler(
49 chargingStation
: ChargingStation
,
51 commandName
: OCPP20IncomingRequestCommand
,
52 commandPayload
: JsonType
54 let response
: JsonType
;
56 chargingStation
.getOcppStrictCompliance() === true &&
57 chargingStation
.isInPendingState() === true &&
58 (commandName
=== OCPP20IncomingRequestCommand
.REQUEST_START_TRANSACTION
||
59 commandName
=== OCPP20IncomingRequestCommand
.REQUEST_STOP_TRANSACTION
)
62 ErrorType
.SECURITY_ERROR
,
63 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
67 )} while the charging station is in pending state on the central server`,
73 chargingStation
.isRegistered() === true ||
74 (chargingStation
.getOcppStrictCompliance() === false &&
75 chargingStation
.isInUnknownState() === true)
78 this.incomingRequestHandlers
.has(commandName
) === true &&
79 OCPP20ServiceUtils
.isIncomingRequestCommandSupported(chargingStation
, commandName
) === true
82 this.validatePayload(chargingStation
, commandName
, commandPayload
);
83 // Call the method to build the response
84 response
= await this.incomingRequestHandlers
.get(commandName
)(
91 `${chargingStation.logPrefix()} ${moduleName}.incomingRequestHandler: Handle incoming request error:`,
99 ErrorType
.NOT_IMPLEMENTED
,
100 `${commandName} is not implemented to handle request PDU ${JSON.stringify(
111 ErrorType
.SECURITY_ERROR
,
112 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
116 )} while the charging station is not registered on the central server.`,
121 // Send the built response
122 await chargingStation
.ocppRequestService
.sendResponse(
130 private validatePayload(
131 chargingStation
: ChargingStation
,
132 commandName
: OCPP20IncomingRequestCommand
,
133 commandPayload
: JsonType
135 if (this.jsonSchemas
.has(commandName
) === true) {
136 return this.validateIncomingRequestPayload(
139 this.jsonSchemas
.get(commandName
),
144 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
149 private parseJsonSchemaFile
<T
extends JsonType
>(relativePath
: string): JSONSchemaType
<T
> {
152 path
.resolve(path
.dirname(fileURLToPath(import.meta
.url
)), relativePath
),
155 ) as JSONSchemaType
<T
>;