1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import type { JSONSchemaType
} from
'ajv';
5 import { OCPP16ServiceUtils
} from
'./OCPP16ServiceUtils';
6 import OCPPError from
'../../../exception/OCPPError';
7 import type { JsonObject
, JsonType
} from
'../../../types/JsonType';
8 import type { OCPP16MeterValuesRequest
} from
'../../../types/ocpp/1.6/MeterValues';
10 type OCPP16BootNotificationRequest
,
11 type OCPP16DataTransferRequest
,
12 type OCPP16DiagnosticsStatusNotificationRequest
,
13 type OCPP16FirmwareStatusNotificationRequest
,
14 type OCPP16HeartbeatRequest
,
16 type OCPP16StatusNotificationRequest
,
17 } from
'../../../types/ocpp/1.6/Requests';
19 OCPP16AuthorizeRequest
,
20 OCPP16StartTransactionRequest
,
21 OCPP16StopTransactionRequest
,
22 } from
'../../../types/ocpp/1.6/Transaction';
23 import { ErrorType
} from
'../../../types/ocpp/ErrorType';
24 import { OCPPVersion
} from
'../../../types/ocpp/OCPPVersion';
25 import type { RequestParams
} from
'../../../types/ocpp/Requests';
26 import Constants from
'../../../utils/Constants';
27 import Utils from
'../../../utils/Utils';
28 import type ChargingStation from
'../../ChargingStation';
29 import OCPPConstants from
'../OCPPConstants';
30 import OCPPRequestService from
'../OCPPRequestService';
31 import type OCPPResponseService from
'../OCPPResponseService';
33 const moduleName
= 'OCPP16RequestService';
35 export default class OCPP16RequestService
extends OCPPRequestService
{
36 protected jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
38 public constructor(ocppResponseService
: OCPPResponseService
) {
39 if (new.target
?.name
=== moduleName
) {
40 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
42 super(OCPPVersion
.VERSION_16
, ocppResponseService
);
43 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
45 OCPP16RequestCommand
.AUTHORIZE
,
46 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeRequest
>(
47 '../../../assets/json-schemas/ocpp/1.6/Authorize.json'
51 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
52 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationRequest
>(
53 '../../../assets/json-schemas/ocpp/1.6/BootNotification.json'
57 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
58 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationRequest
>(
59 '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotification.json'
63 OCPP16RequestCommand
.HEARTBEAT
,
64 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatRequest
>(
65 '../../../assets/json-schemas/ocpp/1.6/Heartbeat.json'
69 OCPP16RequestCommand
.METER_VALUES
,
70 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesRequest
>(
71 '../../../assets/json-schemas/ocpp/1.6/MeterValues.json'
75 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
76 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationRequest
>(
77 '../../../assets/json-schemas/ocpp/1.6/StatusNotification.json'
81 OCPP16RequestCommand
.START_TRANSACTION
,
82 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionRequest
>(
83 '../../../assets/json-schemas/ocpp/1.6/StartTransaction.json'
87 OCPP16RequestCommand
.STOP_TRANSACTION
,
88 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionRequest
>(
89 '../../../assets/json-schemas/ocpp/1.6/StopTransaction.json'
93 OCPP16RequestCommand
.DATA_TRANSFER
,
94 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferRequest
>(
95 '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json'
99 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
100 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationRequest
>(
101 '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotification.json'
105 this.buildRequestPayload
.bind(this);
108 public async requestHandler
<RequestType
extends JsonType
, ResponseType
extends JsonType
>(
109 chargingStation
: ChargingStation
,
110 commandName
: OCPP16RequestCommand
,
111 commandParams
?: JsonType
,
112 params
?: RequestParams
113 ): Promise
<ResponseType
> {
114 if (OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true) {
115 return (await this.sendMessage(
117 Utils
.generateUUID(),
118 this.buildRequestPayload
<RequestType
>(chargingStation
, commandName
, commandParams
),
121 )) as unknown
as ResponseType
;
123 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
125 ErrorType
.NOT_SUPPORTED
,
126 `Unsupported OCPP command '${commandName}'`,
132 private buildRequestPayload
<Request
extends JsonType
>(
133 chargingStation
: ChargingStation
,
134 commandName
: OCPP16RequestCommand
,
135 commandParams
?: JsonType
137 let connectorId
: number;
138 let energyActiveImportRegister
: number;
139 commandParams
= commandParams
as JsonObject
;
140 switch (commandName
) {
141 case OCPP16RequestCommand
.BOOT_NOTIFICATION
:
142 case OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
:
143 case OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
:
144 case OCPP16RequestCommand
.METER_VALUES
:
145 case OCPP16RequestCommand
.STATUS_NOTIFICATION
:
146 case OCPP16RequestCommand
.DATA_TRANSFER
:
147 return commandParams
as unknown
as Request
;
148 case OCPP16RequestCommand
.AUTHORIZE
:
150 idTag
: Constants
.DEFAULT_IDTAG
,
152 } as unknown
as Request
;
153 case OCPP16RequestCommand
.HEARTBEAT
:
154 return OCPPConstants
.OCPP_REQUEST_EMPTY
as unknown
as Request
;
155 case OCPP16RequestCommand
.START_TRANSACTION
:
157 idTag
: Constants
.DEFAULT_IDTAG
,
158 meterStart
: chargingStation
.getEnergyActiveImportRegisterByConnectorId(
159 commandParams
?.connectorId
as number,
162 timestamp
: new Date(),
164 } as unknown
as Request
;
165 case OCPP16RequestCommand
.STOP_TRANSACTION
:
166 chargingStation
.getTransactionDataMeterValues() &&
167 (connectorId
= chargingStation
.getConnectorIdByTransactionId(
168 commandParams
?.transactionId
as number
170 energyActiveImportRegister
= chargingStation
.getEnergyActiveImportRegisterByTransactionId(
171 commandParams
?.transactionId
as number,
175 idTag
: chargingStation
.getTransactionIdTag(commandParams
?.transactionId
as number),
176 meterStop
: energyActiveImportRegister
,
177 timestamp
: new Date(),
178 ...(chargingStation
.getTransactionDataMeterValues() && {
179 transactionData
: OCPP16ServiceUtils
.buildTransactionDataMeterValues(
180 chargingStation
.getConnectorStatus(connectorId
).transactionBeginMeterValue
,
181 OCPP16ServiceUtils
.buildTransactionEndMeterValue(
184 energyActiveImportRegister
189 } as unknown
as Request
;
191 // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
193 ErrorType
.NOT_SUPPORTED
,
194 // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
195 `Unsupported OCPP command '${commandName}'`,