1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import type { JSONSchemaType
} from
'ajv';
5 import { OCPP20ServiceUtils
} from
'./OCPP20ServiceUtils';
6 import OCPPError from
'../../../exception/OCPPError';
7 import type { JsonObject
, JsonType
} from
'../../../types/JsonType';
9 type OCPP20BootNotificationRequest
,
10 type OCPP20HeartbeatRequest
,
12 type OCPP20StatusNotificationRequest
,
13 } from
'../../../types/ocpp/2.0/Requests';
14 import { ErrorType
} from
'../../../types/ocpp/ErrorType';
15 import { OCPPVersion
} from
'../../../types/ocpp/OCPPVersion';
16 import type { RequestParams
} from
'../../../types/ocpp/Requests';
17 import Utils from
'../../../utils/Utils';
18 import type ChargingStation from
'../../ChargingStation';
19 import OCPPConstants from
'../OCPPConstants';
20 import OCPPRequestService from
'../OCPPRequestService';
21 import type OCPPResponseService from
'../OCPPResponseService';
23 const moduleName
= 'OCPP20RequestService';
25 export default class OCPP20RequestService
extends OCPPRequestService
{
26 protected jsonSchemas
: Map
<OCPP20RequestCommand
, JSONSchemaType
<JsonObject
>>;
28 public constructor(ocppResponseService
: OCPPResponseService
) {
29 if (new.target
?.name
=== moduleName
) {
30 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
32 super(OCPPVersion
.VERSION_20
, ocppResponseService
);
33 this.jsonSchemas
= new Map
<OCPP20RequestCommand
, JSONSchemaType
<JsonObject
>>([
35 OCPP20RequestCommand
.BOOT_NOTIFICATION
,
36 OCPP20ServiceUtils
.parseJsonSchemaFile
<OCPP20BootNotificationRequest
>(
37 '../../../assets/json-schemas/ocpp/2.0/BootNotificationRequest.json'
41 OCPP20RequestCommand
.HEARTBEAT
,
42 OCPP20ServiceUtils
.parseJsonSchemaFile
<OCPP20HeartbeatRequest
>(
43 '../../../assets/json-schemas/ocpp/2.0/HeartbeatRequest.json'
47 OCPP20RequestCommand
.STATUS_NOTIFICATION
,
48 OCPP20ServiceUtils
.parseJsonSchemaFile
<OCPP20StatusNotificationRequest
>(
49 '../../../assets/json-schemas/ocpp/2.0/StatusNotificationRequest.json'
53 this.buildRequestPayload
.bind(this);
56 public async requestHandler
<RequestType
extends JsonType
, ResponseType
extends JsonType
>(
57 chargingStation
: ChargingStation
,
58 commandName
: OCPP20RequestCommand
,
59 commandParams
?: JsonType
,
60 params
?: RequestParams
61 ): Promise
<ResponseType
> {
62 if (OCPP20ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true) {
63 return (await this.sendMessage(
66 this.buildRequestPayload
<RequestType
>(chargingStation
, commandName
, commandParams
),
69 )) as unknown
as ResponseType
;
71 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
73 ErrorType
.NOT_SUPPORTED
,
74 `Unsupported OCPP command '${commandName}'`,
80 private buildRequestPayload
<Request
extends JsonType
>(
81 chargingStation
: ChargingStation
,
82 commandName
: OCPP20RequestCommand
,
83 commandParams
?: JsonType
85 commandParams
= commandParams
as JsonObject
;
86 switch (commandName
) {
87 case OCPP20RequestCommand
.BOOT_NOTIFICATION
:
88 return commandParams
as unknown
as Request
;
89 case OCPP20RequestCommand
.HEARTBEAT
:
90 return OCPPConstants
.OCPP_RESPONSE_EMPTY
as unknown
as Request
;
91 case OCPP20RequestCommand
.STATUS_NOTIFICATION
:
93 timestamp
: new Date(),
95 } as unknown
as Request
;
97 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
99 ErrorType
.NOT_SUPPORTED
,
100 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
101 `Unsupported OCPP command '${commandName}'`,