1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import type { JSONSchemaType
} from
'ajv';
5 import type { ChargingStation
} from
'../../../charging-station';
6 import { OCPPError
} from
'../../../exception';
11 type OCPP20BootNotificationRequest
,
12 type OCPP20HeartbeatRequest
,
14 type OCPP20StatusNotificationRequest
,
17 } from
'../../../types';
18 import { Utils
} from
'../../../utils';
23 type OCPPResponseService
,
26 const moduleName
= 'OCPP20RequestService';
28 export class OCPP20RequestService
extends OCPPRequestService
{
29 protected jsonSchemas
: Map
<OCPP20RequestCommand
, JSONSchemaType
<JsonObject
>>;
31 public constructor(ocppResponseService
: OCPPResponseService
) {
32 // if (new.target?.name === moduleName) {
33 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
35 super(OCPPVersion
.VERSION_20
, ocppResponseService
);
36 this.jsonSchemas
= new Map
<OCPP20RequestCommand
, JSONSchemaType
<JsonObject
>>([
38 OCPP20RequestCommand
.BOOT_NOTIFICATION
,
39 OCPP20ServiceUtils
.parseJsonSchemaFile
<OCPP20BootNotificationRequest
>(
40 '../../../assets/json-schemas/ocpp/2.0/BootNotificationRequest.json',
46 OCPP20RequestCommand
.HEARTBEAT
,
47 OCPP20ServiceUtils
.parseJsonSchemaFile
<OCPP20HeartbeatRequest
>(
48 '../../../assets/json-schemas/ocpp/2.0/HeartbeatRequest.json',
54 OCPP20RequestCommand
.STATUS_NOTIFICATION
,
55 OCPP20ServiceUtils
.parseJsonSchemaFile
<OCPP20StatusNotificationRequest
>(
56 '../../../assets/json-schemas/ocpp/2.0/StatusNotificationRequest.json',
62 this.buildRequestPayload
= this.buildRequestPayload
.bind(this) as <Request
extends JsonType
>(
63 chargingStation
: ChargingStation
,
64 commandName
: OCPP20RequestCommand
,
65 commandParams
?: JsonType
69 public async requestHandler
<RequestType
extends JsonType
, ResponseType
extends JsonType
>(
70 chargingStation
: ChargingStation
,
71 commandName
: OCPP20RequestCommand
,
72 commandParams
?: JsonType
,
73 params
?: RequestParams
74 ): Promise
<ResponseType
> {
75 // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc.
76 if (OCPP20ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true) {
77 return (await this.sendMessage(
80 this.buildRequestPayload
<RequestType
>(chargingStation
, commandName
, commandParams
),
85 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
87 ErrorType
.NOT_SUPPORTED
,
88 `Unsupported OCPP command '${commandName}'`,
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 return commandParams
as unknown
as Request
;
103 case OCPP20RequestCommand
.HEARTBEAT
:
104 return OCPP20Constants
.OCPP_RESPONSE_EMPTY
as unknown
as Request
;
105 case OCPP20RequestCommand
.STATUS_NOTIFICATION
:
107 timestamp
: new Date(),
109 } as unknown
as Request
;
111 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
113 ErrorType
.NOT_SUPPORTED
,
114 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
115 `Unsupported OCPP command '${commandName}'`,