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 OCPP16AuthorizeRequest
,
12 type OCPP16BootNotificationRequest
,
13 type OCPP16DataTransferRequest
,
14 type OCPP16DiagnosticsStatusNotificationRequest
,
15 type OCPP16FirmwareStatusNotificationRequest
,
16 type OCPP16HeartbeatRequest
,
17 type OCPP16MeterValuesRequest
,
19 type OCPP16StartTransactionRequest
,
20 type OCPP16StatusNotificationRequest
,
21 type OCPP16StopTransactionRequest
,
24 } from
'../../../types';
25 import { Constants
} from
'../../../utils/Constants';
26 import { Utils
} from
'../../../utils/Utils';
31 type OCPPResponseService
,
34 const moduleName
= 'OCPP16RequestService';
36 export class OCPP16RequestService
extends OCPPRequestService
{
37 protected jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
39 public constructor(ocppResponseService
: OCPPResponseService
) {
40 if (new.target
?.name
=== moduleName
) {
41 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
43 super(OCPPVersion
.VERSION_16
, ocppResponseService
);
44 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
46 OCPP16RequestCommand
.AUTHORIZE
,
47 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeRequest
>(
48 '../../../assets/json-schemas/ocpp/1.6/Authorize.json',
54 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
55 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationRequest
>(
56 '../../../assets/json-schemas/ocpp/1.6/BootNotification.json',
62 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
63 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationRequest
>(
64 '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotification.json',
70 OCPP16RequestCommand
.HEARTBEAT
,
71 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatRequest
>(
72 '../../../assets/json-schemas/ocpp/1.6/Heartbeat.json',
78 OCPP16RequestCommand
.METER_VALUES
,
79 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesRequest
>(
80 '../../../assets/json-schemas/ocpp/1.6/MeterValues.json',
86 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
87 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationRequest
>(
88 '../../../assets/json-schemas/ocpp/1.6/StatusNotification.json',
94 OCPP16RequestCommand
.START_TRANSACTION
,
95 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionRequest
>(
96 '../../../assets/json-schemas/ocpp/1.6/StartTransaction.json',
102 OCPP16RequestCommand
.STOP_TRANSACTION
,
103 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionRequest
>(
104 '../../../assets/json-schemas/ocpp/1.6/StopTransaction.json',
110 OCPP16RequestCommand
.DATA_TRANSFER
,
111 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferRequest
>(
112 '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json',
118 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
119 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationRequest
>(
120 '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotification.json',
126 this.buildRequestPayload
.bind(this);
129 public async requestHandler
<RequestType
extends JsonType
, ResponseType
extends JsonType
>(
130 chargingStation
: ChargingStation
,
131 commandName
: OCPP16RequestCommand
,
132 commandParams
?: JsonType
,
133 params
?: RequestParams
134 ): Promise
<ResponseType
> {
135 if (OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true) {
136 return (await this.sendMessage(
138 Utils
.generateUUID(),
139 this.buildRequestPayload
<RequestType
>(chargingStation
, commandName
, commandParams
),
142 )) as unknown
as ResponseType
;
144 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
146 ErrorType
.NOT_SUPPORTED
,
147 `Unsupported OCPP command '${commandName}'`,
153 private buildRequestPayload
<Request
extends JsonType
>(
154 chargingStation
: ChargingStation
,
155 commandName
: OCPP16RequestCommand
,
156 commandParams
?: JsonType
158 let connectorId
: number;
159 let energyActiveImportRegister
: number;
160 commandParams
= commandParams
as JsonObject
;
161 switch (commandName
) {
162 case OCPP16RequestCommand
.BOOT_NOTIFICATION
:
163 case OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
:
164 case OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
:
165 case OCPP16RequestCommand
.METER_VALUES
:
166 case OCPP16RequestCommand
.STATUS_NOTIFICATION
:
167 case OCPP16RequestCommand
.DATA_TRANSFER
:
168 return commandParams
as unknown
as Request
;
169 case OCPP16RequestCommand
.AUTHORIZE
:
171 idTag
: Constants
.DEFAULT_IDTAG
,
173 } as unknown
as Request
;
174 case OCPP16RequestCommand
.HEARTBEAT
:
175 return OCPPConstants
.OCPP_REQUEST_EMPTY
as unknown
as Request
;
176 case OCPP16RequestCommand
.START_TRANSACTION
:
178 idTag
: Constants
.DEFAULT_IDTAG
,
179 meterStart
: chargingStation
.getEnergyActiveImportRegisterByConnectorId(
180 commandParams
?.connectorId
as number,
183 timestamp
: new Date(),
185 } as unknown
as Request
;
186 case OCPP16RequestCommand
.STOP_TRANSACTION
:
187 chargingStation
.getTransactionDataMeterValues() &&
188 (connectorId
= chargingStation
.getConnectorIdByTransactionId(
189 commandParams
?.transactionId
as number
191 energyActiveImportRegister
= chargingStation
.getEnergyActiveImportRegisterByTransactionId(
192 commandParams
?.transactionId
as number,
196 idTag
: chargingStation
.getTransactionIdTag(commandParams
?.transactionId
as number),
197 meterStop
: energyActiveImportRegister
,
198 timestamp
: new Date(),
199 ...(chargingStation
.getTransactionDataMeterValues() && {
200 transactionData
: OCPP16ServiceUtils
.buildTransactionDataMeterValues(
201 chargingStation
.getConnectorStatus(connectorId
).transactionBeginMeterValue
,
202 OCPP16ServiceUtils
.buildTransactionEndMeterValue(
205 energyActiveImportRegister
210 } as unknown
as Request
;
212 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
214 ErrorType
.NOT_SUPPORTED
,
215 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
216 `Unsupported OCPP command '${commandName}'`,