Commit | Line | Data |
---|---|---|
edd13439 | 1 | // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved. |
c8eeb62b | 2 | |
6c1761d4 | 3 | import type { JSONSchemaType } from 'ajv'; |
b52c969d | 4 | |
2896e06d | 5 | import type { ChargingStation } from '../../../charging-station'; |
268a74bb | 6 | import { OCPPError } from '../../../exception'; |
b52c969d | 7 | import { |
268a74bb JB |
8 | ErrorType, |
9 | type JsonObject, | |
10 | type JsonType, | |
11 | type OCPP16AuthorizeRequest, | |
27782dbc JB |
12 | type OCPP16BootNotificationRequest, |
13 | type OCPP16DataTransferRequest, | |
c9a4f9ea | 14 | type OCPP16DiagnosticsStatusNotificationRequest, |
e9a4164c | 15 | type OCPP16FirmwareStatusNotificationRequest, |
27782dbc | 16 | type OCPP16HeartbeatRequest, |
268a74bb | 17 | type OCPP16MeterValuesRequest, |
b52c969d | 18 | OCPP16RequestCommand, |
268a74bb | 19 | type OCPP16StartTransactionRequest, |
27782dbc | 20 | type OCPP16StatusNotificationRequest, |
268a74bb JB |
21 | type OCPP16StopTransactionRequest, |
22 | OCPPVersion, | |
23 | type RequestParams, | |
24 | } from '../../../types'; | |
60a74391 | 25 | import { Constants, Utils } from '../../../utils'; |
2896e06d | 26 | import { |
d8b1fab1 | 27 | OCPP16Constants, |
2896e06d | 28 | OCPP16ServiceUtils, |
2896e06d JB |
29 | OCPPRequestService, |
30 | type OCPPResponseService, | |
31 | } from '../internal'; | |
c0560973 | 32 | |
909dcf2d JB |
33 | const moduleName = 'OCPP16RequestService'; |
34 | ||
268a74bb | 35 | export class OCPP16RequestService extends OCPPRequestService { |
b3fc3ff5 | 36 | protected jsonSchemas: Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>; |
b52c969d | 37 | |
08f130a0 | 38 | public constructor(ocppResponseService: OCPPResponseService) { |
b768993d JB |
39 | // if (new.target?.name === moduleName) { |
40 | // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`); | |
41 | // } | |
d270cc87 | 42 | super(OCPPVersion.VERSION_16, ocppResponseService); |
b52c969d JB |
43 | this.jsonSchemas = new Map<OCPP16RequestCommand, JSONSchemaType<JsonObject>>([ |
44 | [ | |
45 | OCPP16RequestCommand.AUTHORIZE, | |
130783a7 | 46 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16AuthorizeRequest>( |
1b271a54 JB |
47 | '../../../assets/json-schemas/ocpp/1.6/Authorize.json', |
48 | moduleName, | |
49 | 'constructor' | |
e9a4164c | 50 | ), |
b52c969d JB |
51 | ], |
52 | [ | |
53 | OCPP16RequestCommand.BOOT_NOTIFICATION, | |
130783a7 | 54 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16BootNotificationRequest>( |
1b271a54 JB |
55 | '../../../assets/json-schemas/ocpp/1.6/BootNotification.json', |
56 | moduleName, | |
57 | 'constructor' | |
e9a4164c | 58 | ), |
b52c969d JB |
59 | ], |
60 | [ | |
61 | OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, | |
130783a7 | 62 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16DiagnosticsStatusNotificationRequest>( |
1b271a54 JB |
63 | '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotification.json', |
64 | moduleName, | |
65 | 'constructor' | |
e9a4164c | 66 | ), |
b52c969d JB |
67 | ], |
68 | [ | |
69 | OCPP16RequestCommand.HEARTBEAT, | |
130783a7 | 70 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16HeartbeatRequest>( |
1b271a54 JB |
71 | '../../../assets/json-schemas/ocpp/1.6/Heartbeat.json', |
72 | moduleName, | |
73 | 'constructor' | |
e9a4164c | 74 | ), |
b52c969d JB |
75 | ], |
76 | [ | |
77 | OCPP16RequestCommand.METER_VALUES, | |
130783a7 | 78 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16MeterValuesRequest>( |
1b271a54 JB |
79 | '../../../assets/json-schemas/ocpp/1.6/MeterValues.json', |
80 | moduleName, | |
81 | 'constructor' | |
e9a4164c | 82 | ), |
b52c969d JB |
83 | ], |
84 | [ | |
85 | OCPP16RequestCommand.STATUS_NOTIFICATION, | |
130783a7 | 86 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16StatusNotificationRequest>( |
1b271a54 JB |
87 | '../../../assets/json-schemas/ocpp/1.6/StatusNotification.json', |
88 | moduleName, | |
89 | 'constructor' | |
e9a4164c | 90 | ), |
b52c969d JB |
91 | ], |
92 | [ | |
93 | OCPP16RequestCommand.START_TRANSACTION, | |
130783a7 | 94 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16StartTransactionRequest>( |
1b271a54 JB |
95 | '../../../assets/json-schemas/ocpp/1.6/StartTransaction.json', |
96 | moduleName, | |
97 | 'constructor' | |
e9a4164c | 98 | ), |
b52c969d JB |
99 | ], |
100 | [ | |
101 | OCPP16RequestCommand.STOP_TRANSACTION, | |
130783a7 | 102 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16StopTransactionRequest>( |
1b271a54 JB |
103 | '../../../assets/json-schemas/ocpp/1.6/StopTransaction.json', |
104 | moduleName, | |
105 | 'constructor' | |
e9a4164c | 106 | ), |
b52c969d | 107 | ], |
91a7d3ea JB |
108 | [ |
109 | OCPP16RequestCommand.DATA_TRANSFER, | |
130783a7 | 110 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16DataTransferRequest>( |
1b271a54 JB |
111 | '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json', |
112 | moduleName, | |
113 | 'constructor' | |
e9a4164c | 114 | ), |
91a7d3ea | 115 | ], |
c9a4f9ea JB |
116 | [ |
117 | OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, | |
130783a7 | 118 | OCPP16ServiceUtils.parseJsonSchemaFile<OCPP16FirmwareStatusNotificationRequest>( |
1b271a54 JB |
119 | '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotification.json', |
120 | moduleName, | |
121 | 'constructor' | |
e9a4164c | 122 | ), |
c9a4f9ea | 123 | ], |
b52c969d | 124 | ]); |
31f59c6d JB |
125 | this.buildRequestPayload = this.buildRequestPayload.bind(this) as <Request extends JsonType>( |
126 | chargingStation: ChargingStation, | |
127 | commandName: OCPP16RequestCommand, | |
128 | commandParams?: JsonType | |
129 | ) => Request; | |
9f2e3130 JB |
130 | } |
131 | ||
6c1761d4 | 132 | public async requestHandler<RequestType extends JsonType, ResponseType extends JsonType>( |
08f130a0 | 133 | chargingStation: ChargingStation, |
94a464f9 | 134 | commandName: OCPP16RequestCommand, |
5cc4b63b | 135 | commandParams?: JsonType, |
be9b0d50 | 136 | params?: RequestParams |
6c1761d4 | 137 | ): Promise<ResponseType> { |
62340a29 | 138 | // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc. |
ed6cfcff | 139 | if (OCPP16ServiceUtils.isRequestCommandSupported(chargingStation, commandName) === true) { |
f22266fd | 140 | return (await this.sendMessage( |
08f130a0 | 141 | chargingStation, |
94a464f9 | 142 | Utils.generateUUID(), |
18bf8274 | 143 | this.buildRequestPayload<RequestType>(chargingStation, commandName, commandParams), |
94a464f9 JB |
144 | commandName, |
145 | params | |
617cad0c | 146 | )) as ResponseType; |
94a464f9 | 147 | } |
e909d2a7 | 148 | // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError(). |
94a464f9 JB |
149 | throw new OCPPError( |
150 | ErrorType.NOT_SUPPORTED, | |
6c8f5d90 | 151 | `Unsupported OCPP command '${commandName}'`, |
94a464f9 | 152 | commandName, |
7369e417 | 153 | commandParams |
94a464f9 | 154 | ); |
c0560973 JB |
155 | } |
156 | ||
5cc4b63b | 157 | private buildRequestPayload<Request extends JsonType>( |
08f130a0 | 158 | chargingStation: ChargingStation, |
78085c42 | 159 | commandName: OCPP16RequestCommand, |
5cc4b63b | 160 | commandParams?: JsonType |
f22266fd | 161 | ): Request { |
68c993d5 | 162 | let connectorId: number; |
cf058664 | 163 | let energyActiveImportRegister: number; |
5cc4b63b | 164 | commandParams = commandParams as JsonObject; |
78085c42 | 165 | switch (commandName) { |
78085c42 | 166 | case OCPP16RequestCommand.BOOT_NOTIFICATION: |
78085c42 | 167 | case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION: |
22e0d48e | 168 | case OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION: |
78085c42 | 169 | case OCPP16RequestCommand.METER_VALUES: |
78085c42 | 170 | case OCPP16RequestCommand.STATUS_NOTIFICATION: |
36c462a4 JB |
171 | case OCPP16RequestCommand.DATA_TRANSFER: |
172 | return commandParams as unknown as Request; | |
173 | case OCPP16RequestCommand.AUTHORIZE: | |
78085c42 | 174 | return { |
36c462a4 JB |
175 | idTag: Constants.DEFAULT_IDTAG, |
176 | ...commandParams, | |
f22266fd | 177 | } as unknown as Request; |
36c462a4 | 178 | case OCPP16RequestCommand.HEARTBEAT: |
d8b1fab1 | 179 | return OCPP16Constants.OCPP_REQUEST_EMPTY as unknown as Request; |
78085c42 JB |
180 | case OCPP16RequestCommand.START_TRANSACTION: |
181 | return { | |
36c462a4 JB |
182 | idTag: Constants.DEFAULT_IDTAG, |
183 | meterStart: chargingStation.getEnergyActiveImportRegisterByConnectorId( | |
18bf8274 JB |
184 | commandParams?.connectorId as number, |
185 | true | |
36c462a4 JB |
186 | ), |
187 | timestamp: new Date(), | |
188 | ...commandParams, | |
f22266fd | 189 | } as unknown as Request; |
78085c42 | 190 | case OCPP16RequestCommand.STOP_TRANSACTION: |
f1e731bd | 191 | chargingStation.getTransactionDataMeterValues() && |
f1e731bd JB |
192 | (connectorId = chargingStation.getConnectorIdByTransactionId( |
193 | commandParams?.transactionId as number | |
194 | )); | |
36c462a4 JB |
195 | energyActiveImportRegister = chargingStation.getEnergyActiveImportRegisterByTransactionId( |
196 | commandParams?.transactionId as number, | |
197 | true | |
198 | ); | |
78085c42 | 199 | return { |
36c462a4 JB |
200 | idTag: chargingStation.getTransactionIdTag(commandParams?.transactionId as number), |
201 | meterStop: energyActiveImportRegister, | |
202 | timestamp: new Date(), | |
203 | ...(chargingStation.getTransactionDataMeterValues() && { | |
204 | transactionData: OCPP16ServiceUtils.buildTransactionDataMeterValues( | |
205 | chargingStation.getConnectorStatus(connectorId).transactionBeginMeterValue, | |
206 | OCPP16ServiceUtils.buildTransactionEndMeterValue( | |
207 | chargingStation, | |
208 | connectorId, | |
209 | energyActiveImportRegister | |
210 | ) | |
211 | ), | |
78085c42 | 212 | }), |
36c462a4 | 213 | ...commandParams, |
f22266fd | 214 | } as unknown as Request; |
78085c42 | 215 | default: |
e909d2a7 | 216 | // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError(). |
78085c42 JB |
217 | throw new OCPPError( |
218 | ErrorType.NOT_SUPPORTED, | |
219 | // eslint-disable-next-line @typescript-eslint/restrict-template-expressions | |
6c8f5d90 | 220 | `Unsupported OCPP command '${commandName}'`, |
78085c42 | 221 | commandName, |
7369e417 | 222 | commandParams |
78085c42 JB |
223 | ); |
224 | } | |
225 | } | |
c0560973 | 226 | } |