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 OCPPError from
'../../../exception/OCPPError';
10 import type { JsonObject
, JsonType
} from
'../../../types/JsonType';
12 type OCPP20BootNotificationRequest
,
14 } from
'../../../types/ocpp/2.0/Requests';
15 import { ErrorType
} from
'../../../types/ocpp/ErrorType';
16 import { OCPPVersion
} from
'../../../types/ocpp/OCPPVersion';
17 import type { RequestParams
} from
'../../../types/ocpp/Requests';
18 import logger from
'../../../utils/Logger';
19 import Utils from
'../../../utils/Utils';
20 import type ChargingStation from
'../../ChargingStation';
21 import OCPPRequestService from
'../OCPPRequestService';
22 import type OCPPResponseService from
'../OCPPResponseService';
23 import { OCPP20ServiceUtils
} from
'./OCPP20ServiceUtils';
25 const moduleName
= 'OCPP20RequestService';
27 export default class OCPP20RequestService
extends OCPPRequestService
{
28 private jsonSchemas
: Map
<OCPP20RequestCommand
, JSONSchemaType
<JsonObject
>>;
30 public constructor(ocppResponseService
: OCPPResponseService
) {
31 if (new.target
?.name
=== moduleName
) {
32 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
34 super(OCPPVersion
.VERSION_20
, ocppResponseService
);
35 this.jsonSchemas
= new Map
<OCPP20RequestCommand
, JSONSchemaType
<JsonObject
>>([
37 OCPP20RequestCommand
.BOOT_NOTIFICATION
,
41 path
.dirname(fileURLToPath(import.meta
.url
)),
42 '../../../assets/json-schemas/ocpp/2.0/BootNotificationRequest.json'
46 ) as JSONSchemaType
<OCPP20BootNotificationRequest
>,
49 this.buildRequestPayload
.bind(this);
52 public async requestHandler
<RequestType
extends JsonType
, ResponseType
extends JsonType
>(
53 chargingStation
: ChargingStation
,
54 commandName
: OCPP20RequestCommand
,
55 commandParams
?: JsonType
,
56 params
?: RequestParams
57 ): Promise
<ResponseType
> {
58 if (OCPP20ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true) {
59 const requestPayload
= this.buildRequestPayload
<RequestType
>(
64 return (await this.sendMessage(
70 )) as unknown
as ResponseType
;
72 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
74 ErrorType
.NOT_SUPPORTED
,
75 `Unsupported OCPP command '${commandName}'`,
81 protected getRequestPayloadValidationSchema(
82 chargingStation
: ChargingStation
,
83 commandName
: OCPP20RequestCommand
84 ): JSONSchemaType
<JsonObject
> | false {
85 if (this.jsonSchemas
.has(commandName
) === true) {
86 return this.jsonSchemas
.get(commandName
);
89 `${chargingStation.logPrefix()} ${moduleName}.getPayloadValidationSchema: No JSON schema found for command ${commandName} PDU validation`
94 private buildRequestPayload
<Request
extends JsonType
>(
95 chargingStation
: ChargingStation
,
96 commandName
: OCPP20RequestCommand
,
97 commandParams
?: JsonType
99 commandParams
= commandParams
as JsonObject
;
100 switch (commandName
) {
101 case OCPP20RequestCommand
.BOOT_NOTIFICATION
:
102 commandParams
.chargingStation
= commandParams
.chargingStation
as JsonObject
;
103 commandParams
.chargingStation
.modem
= commandParams
.chargingStation
.modem
as JsonObject
;
105 reason
: commandParams
?.reason
,
107 model
: commandParams
?.chargingStation
?.model
,
108 vendorName
: commandParams
?.chargingStation
?.vendorName
,
109 ...(!Utils
.isUndefined(commandParams
?.chargingStation
?.firmwareVersion
) && {
110 firmwareVersion
: commandParams
.chargingStation
?.firmwareVersion
,
112 ...(!Utils
.isUndefined(commandParams
?.chargingStation
?.serialNumber
) && {
113 serialNumber
: commandParams
.chargingStation
?.serialNumber
,
115 ...(!Utils
.isUndefined(commandParams
?.chargingStation
?.modem
) && {
117 ...(!Utils
.isUndefined(commandParams
?.chargingStation
?.modem
?.iccid
) && {
118 iccid
: commandParams
.chargingStation
.modem
.iccid
,
120 ...(!Utils
.isUndefined(commandParams
?.chargingStation
?.modem
?.imsi
) && {
121 imsi
: commandParams
.chargingStation
.modem
.imsi
,
126 } as unknown
as Request
;
128 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
130 ErrorType
.NOT_SUPPORTED
,
131 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
132 `Unsupported OCPP command '${commandName}'`,