1 import Ajv
, { type JSONSchemaType
, type ValidateFunction
} from
'ajv';
2 import ajvFormats from
'ajv-formats';
4 import { OCPPConstants
} from
'./OCPPConstants.js';
5 import { OCPPServiceUtils
} from
'./OCPPServiceUtils.js';
6 import { type ChargingStation
, getIdTagsFile
} from
'../../charging-station/index.js';
7 import { OCPPError
} from
'../../exception/index.js';
11 IncomingRequestCommand
,
14 } from
'../../types/index.js';
15 import { logger
, setDefaultErrorParams
} from
'../../utils/index.js';
17 const moduleName
= 'OCPPIncomingRequestService';
19 export abstract class OCPPIncomingRequestService
{
20 private static instance
: OCPPIncomingRequestService
| null = null;
21 private readonly version
: OCPPVersion
;
22 private readonly ajv
: Ajv
;
23 private jsonValidateFunctions
: Map
<IncomingRequestCommand
, ValidateFunction
<JsonType
>>;
24 protected abstract jsonSchemas
: Map
<IncomingRequestCommand
, JSONSchemaType
<JsonType
>>;
26 protected constructor(version
: OCPPVersion
) {
27 this.version
= version
;
28 // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
30 keywords
: ['javaType'],
31 multipleOfPrecision
: 2,
34 this.jsonValidateFunctions
= new Map
<IncomingRequestCommand
, ValidateFunction
<JsonType
>>();
35 this.incomingRequestHandler
= this.incomingRequestHandler
.bind(this) as <
36 ReqType
extends JsonType
,
37 // eslint-disable-next-line @typescript-eslint/no-unused-vars
38 ResType
extends JsonType
,
40 chargingStation
: ChargingStation
,
42 commandName
: IncomingRequestCommand
,
43 commandPayload
: ReqType
,
45 this.validateIncomingRequestPayload
= this.validateIncomingRequestPayload
.bind(this) as <
48 chargingStation
: ChargingStation
,
49 commandName
: IncomingRequestCommand
,
50 schema
: JSONSchemaType
<T
>,
55 public static getInstance
<T
extends OCPPIncomingRequestService
>(this: new () => T
): T
{
56 if (OCPPIncomingRequestService
.instance
=== null) {
57 OCPPIncomingRequestService
.instance
= new this();
59 return OCPPIncomingRequestService
.instance
as T
;
62 protected handleIncomingRequestError
<T
extends JsonType
>(
63 chargingStation
: ChargingStation
,
64 commandName
: IncomingRequestCommand
,
66 params
: HandleErrorParams
<T
> = { throwError
: true, consoleOut
: false },
68 setDefaultErrorParams(params
);
70 `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
73 if (!params
?.throwError
&& params
?.errorResponse
) {
74 return params
?.errorResponse
;
76 if (params
?.throwError
&& !params
?.errorResponse
) {
79 if (params
?.throwError
&& params
?.errorResponse
) {
80 return params
?.errorResponse
;
84 protected validateIncomingRequestPayload
<T
extends JsonType
>(
85 chargingStation
: ChargingStation
,
86 commandName
: IncomingRequestCommand
,
87 schema
: JSONSchemaType
<T
>,
90 if (chargingStation
.stationInfo
?.ocppStrictCompliance
=== false) {
93 const validate
= this.getJsonIncomingRequestValidateFunction
<T
>(commandName
, schema
);
94 if (validate(payload
)) {
98 `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestPayload: Command '${commandName}' incoming request PDU is invalid: %j`,
102 OCPPServiceUtils
.ajvErrorsToErrorType(validate
.errors
),
103 'Incoming request PDU is invalid',
105 JSON
.stringify(validate
.errors
, undefined, 2),
109 protected handleRequestClearCache(chargingStation
: ChargingStation
): ClearCacheResponse
{
110 if (chargingStation
.idTagsCache
.deleteIdTags(getIdTagsFile(chargingStation
.stationInfo
)!)) {
111 return OCPPConstants
.OCPP_RESPONSE_ACCEPTED
;
113 return OCPPConstants
.OCPP_RESPONSE_REJECTED
;
116 private getJsonIncomingRequestValidateFunction
<T
extends JsonType
>(
117 commandName
: IncomingRequestCommand
,
118 schema
: JSONSchemaType
<T
>,
120 if (this.jsonValidateFunctions
.has(commandName
) === false) {
121 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
122 this.jsonValidateFunctions
.set(commandName
, this.ajv
.compile
<T
>(schema
).bind(this));
124 return this.jsonValidateFunctions
.get(commandName
)!;
127 // eslint-disable-next-line @typescript-eslint/no-unused-vars
128 public abstract incomingRequestHandler
<ReqType
extends JsonType
, ResType
extends JsonType
>(
129 chargingStation
: ChargingStation
,
131 commandName
: IncomingRequestCommand
,
132 commandPayload
: ReqType
,