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 { OCPP16ChargePointErrorCode
} from
'../../../types/ocpp/1.6/ChargePointErrorCode';
9 import { OCPP16ChargePointStatus
} from
'../../../types/ocpp/1.6/ChargePointStatus';
10 import { OCPP16StandardParametersKey
} from
'../../../types/ocpp/1.6/Configuration';
12 OCPP16MeterValuesRequest
,
13 OCPP16MeterValuesResponse
,
14 } from
'../../../types/ocpp/1.6/MeterValues';
16 type OCPP16BootNotificationRequest
,
17 OCPP16IncomingRequestCommand
,
19 type OCPP16StatusNotificationRequest
,
20 } from
'../../../types/ocpp/1.6/Requests';
22 ChangeAvailabilityResponse
,
23 ChangeConfigurationResponse
,
24 ClearChargingProfileResponse
,
25 GetConfigurationResponse
,
26 GetDiagnosticsResponse
,
27 OCPP16BootNotificationResponse
,
28 OCPP16DataTransferResponse
,
29 OCPP16DiagnosticsStatusNotificationResponse
,
30 OCPP16FirmwareStatusNotificationResponse
,
31 OCPP16HeartbeatResponse
,
32 OCPP16StatusNotificationResponse
,
33 OCPP16TriggerMessageResponse
,
34 OCPP16UpdateFirmwareResponse
,
35 SetChargingProfileResponse
,
36 UnlockConnectorResponse
,
37 } from
'../../../types/ocpp/1.6/Responses';
39 OCPP16AuthorizationStatus
,
40 type OCPP16AuthorizeRequest
,
41 type OCPP16AuthorizeResponse
,
42 type OCPP16StartTransactionRequest
,
43 type OCPP16StartTransactionResponse
,
44 type OCPP16StopTransactionRequest
,
45 type OCPP16StopTransactionResponse
,
46 } from
'../../../types/ocpp/1.6/Transaction';
47 import { ErrorType
} from
'../../../types/ocpp/ErrorType';
48 import { OCPPVersion
} from
'../../../types/ocpp/OCPPVersion';
51 RegistrationStatusEnumType
,
53 } from
'../../../types/ocpp/Responses';
54 import Constants from
'../../../utils/Constants';
55 import logger from
'../../../utils/Logger';
56 import Utils from
'../../../utils/Utils';
57 import type ChargingStation from
'../../ChargingStation';
58 import { ChargingStationConfigurationUtils
} from
'../../ChargingStationConfigurationUtils';
59 import OCPPResponseService from
'../OCPPResponseService';
61 const moduleName
= 'OCPP16ResponseService';
63 export default class OCPP16ResponseService
extends OCPPResponseService
{
64 public jsonIncomingRequestResponseSchemas
: Map
<
65 OCPP16IncomingRequestCommand
,
66 JSONSchemaType
<JsonObject
>
69 private responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>;
70 private jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
72 public constructor() {
73 if (new.target
?.name
=== moduleName
) {
74 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
76 super(OCPPVersion
.VERSION_16
);
77 this.responseHandlers
= new Map
<OCPP16RequestCommand
, ResponseHandler
>([
78 [OCPP16RequestCommand
.BOOT_NOTIFICATION
, this.handleResponseBootNotification
.bind(this)],
79 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this)],
80 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this)],
81 [OCPP16RequestCommand
.START_TRANSACTION
, this.handleResponseStartTransaction
.bind(this)],
82 [OCPP16RequestCommand
.STOP_TRANSACTION
, this.handleResponseStopTransaction
.bind(this)],
83 [OCPP16RequestCommand
.STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
84 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this)],
85 [OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
86 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this)],
87 [OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
89 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
91 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
92 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
93 '../../../assets/json-schemas/ocpp/1.6/BootNotificationResponse.json'
97 OCPP16RequestCommand
.HEARTBEAT
,
98 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
99 '../../../assets/json-schemas/ocpp/1.6/HeartbeatResponse.json'
103 OCPP16RequestCommand
.AUTHORIZE
,
104 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
105 '../../../assets/json-schemas/ocpp/1.6/AuthorizeResponse.json'
109 OCPP16RequestCommand
.START_TRANSACTION
,
110 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
111 '../../../assets/json-schemas/ocpp/1.6/StartTransactionResponse.json'
115 OCPP16RequestCommand
.STOP_TRANSACTION
,
116 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
117 '../../../assets/json-schemas/ocpp/1.6/StopTransactionResponse.json'
121 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
122 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
123 '../../../assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json'
127 OCPP16RequestCommand
.METER_VALUES
,
128 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
129 '../../../assets/json-schemas/ocpp/1.6/MeterValuesResponse.json'
133 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
134 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
135 '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json'
139 OCPP16RequestCommand
.DATA_TRANSFER
,
140 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
141 '../../../assets/json-schemas/ocpp/1.6/DataTransferResponse.json'
145 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
146 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
147 '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json'
151 this.jsonIncomingRequestResponseSchemas
= new Map([
153 OCPP16IncomingRequestCommand
.RESET
,
154 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
155 '../../../assets/json-schemas/ocpp/1.6/ResetResponse.json'
159 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
160 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
161 '../../../assets/json-schemas/ocpp/1.6/ClearCacheResponse.json'
165 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
166 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
167 '../../../assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json'
171 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
172 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
173 '../../../assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json'
177 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
178 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
179 '../../../assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json'
183 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
184 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
185 '../../../assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json'
189 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
190 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
191 '../../../assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json'
195 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
196 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
197 '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json'
201 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
202 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
203 '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json'
207 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
208 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
209 '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json'
213 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
214 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
215 '../../../assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json'
219 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
220 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
221 '../../../assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json'
225 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
226 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
227 '../../../assets/json-schemas/ocpp/1.6/DataTransferResponse.json'
231 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
232 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
233 '../../../assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json'
237 this.validatePayload
.bind(this);
240 public async responseHandler(
241 chargingStation
: ChargingStation
,
242 commandName
: OCPP16RequestCommand
,
244 requestPayload
: JsonType
247 chargingStation
.isRegistered() === true ||
248 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
251 this.responseHandlers
.has(commandName
) === true &&
252 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
255 this.validatePayload(chargingStation
, commandName
, payload
);
256 await this.responseHandlers
.get(commandName
)(chargingStation
, payload
, requestPayload
);
259 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
267 ErrorType
.NOT_IMPLEMENTED
,
268 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
279 ErrorType
.SECURITY_ERROR
,
280 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
284 )} while the charging station is not registered on the central server.`,
291 private validatePayload(
292 chargingStation
: ChargingStation
,
293 commandName
: OCPP16RequestCommand
,
296 if (this.jsonSchemas
.has(commandName
) === true) {
297 return this.validateResponsePayload(
300 this.jsonSchemas
.get(commandName
),
305 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
310 private handleResponseBootNotification(
311 chargingStation
: ChargingStation
,
312 payload
: OCPP16BootNotificationResponse
314 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
315 ChargingStationConfigurationUtils
.addConfigurationKey(
317 OCPP16StandardParametersKey
.HeartbeatInterval
,
318 payload
.interval
.toString(),
320 { overwrite
: true, save
: true }
322 ChargingStationConfigurationUtils
.addConfigurationKey(
324 OCPP16StandardParametersKey
.HeartBeatInterval
,
325 payload
.interval
.toString(),
327 { overwrite
: true, save
: true }
329 chargingStation
.heartbeatSetInterval
330 ? chargingStation
.restartHeartbeat()
331 : chargingStation
.startHeartbeat();
333 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
334 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
336 }' state on the central server`;
337 payload
.status === RegistrationStatusEnumType
.REJECTED
338 ? logger
.warn(logMsg
)
339 : logger
.info(logMsg
);
342 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
348 private handleResponseAuthorize(
349 chargingStation
: ChargingStation
,
350 payload
: OCPP16AuthorizeResponse
,
351 requestPayload
: OCPP16AuthorizeRequest
353 let authorizeConnectorId
: number;
354 for (const connectorId
of chargingStation
.connectors
.keys()) {
357 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
359 authorizeConnectorId
= connectorId
;
363 const authorizeConnectorIdDefined
= authorizeConnectorId
!== undefined;
364 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
365 authorizeConnectorIdDefined
&&
366 (chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= true);
368 `${chargingStation.logPrefix()} IdTag '${requestPayload.idTag}' accepted${
369 authorizeConnectorIdDefined ? ` on connector ${authorizeConnectorId}
` : ''
373 if (authorizeConnectorIdDefined
) {
374 chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= false;
375 delete chargingStation
.getConnectorStatus(authorizeConnectorId
)?.authorizeIdTag
;
378 `${chargingStation.logPrefix()} IdTag '${requestPayload.idTag}' rejected with status '${
379 payload.idTagInfo.status
380 }'${authorizeConnectorIdDefined ? ` on connector ${authorizeConnectorId}` : ''}`
385 private async handleResponseStartTransaction(
386 chargingStation: ChargingStation,
387 payload: OCPP16StartTransactionResponse,
388 requestPayload: OCPP16StartTransactionRequest
390 const connectorId = requestPayload.connectorId;
392 let transactionConnectorId: number;
393 for (const id of chargingStation.connectors.keys()) {
394 if (id > 0 && id === connectorId) {
395 transactionConnectorId = id;
399 if (Utils.isNullOrUndefined(transactionConnectorId)) {
401 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector Id ${connectorId.toString()}
`
406 chargingStation.getConnectorStatus(connectorId)?.transactionRemoteStarted === true &&
407 chargingStation.getAuthorizeRemoteTxRequests() === true &&
408 chargingStation.getLocalAuthListEnabled() === true &&
409 chargingStation.hasAuthorizedTags() &&
410 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized === false
413 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{
414 chargingStation
.getConnectorStatus(connectorId
)?.localAuthorizeIdTag
415 } on connector Id ${connectorId.toString()}
`
417 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
421 chargingStation.getConnectorStatus(connectorId)?.transactionRemoteStarted === true &&
422 chargingStation.getAuthorizeRemoteTxRequests() === true &&
423 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
424 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized === false &&
425 chargingStation.getConnectorStatus(connectorId)?.idTagAuthorized === false
428 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{
429 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
430 } on connector Id ${connectorId.toString()}
`
432 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
436 chargingStation.getConnectorStatus(connectorId)?.idTagAuthorized &&
437 chargingStation.getConnectorStatus(connectorId)?.authorizeIdTag !== requestPayload.idTag
440 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
442 } different from the authorize request one $
{
443 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
444 } on connector Id ${connectorId.toString()}
`
446 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
450 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized &&
451 chargingStation.getConnectorStatus(connectorId)?.localAuthorizeIdTag !== requestPayload.idTag
454 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
456 } different from the local authorized one $
{
457 chargingStation
.getConnectorStatus(connectorId
)?.localAuthorizeIdTag
458 } on connector Id ${connectorId.toString()}
`
460 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
463 if (chargingStation.getConnectorStatus(connectorId)?.transactionStarted === true) {
465 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector ${connectorId.toString()}
: %j
`,
466 chargingStation.getConnectorStatus(connectorId)
471 chargingStation.getConnectorStatus(connectorId)?.status !==
472 OCPP16ChargePointStatus.AVAILABLE &&
473 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.PREPARING
476 `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()}
with status $
{
477 chargingStation
.getConnectorStatus(connectorId
)?.status
482 // if (!Number.isInteger(payload.transactionId)) {
484 // `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()}
with a non integer transaction Id $
{
485 // payload.transactionId
486 // }, converting to integer`
488 // payload.transactionId = Utils.convertToInt(payload.transactionId);
491 if (payload
.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
492 chargingStation
.getConnectorStatus(connectorId
).transactionStarted
= true;
493 chargingStation
.getConnectorStatus(connectorId
).transactionId
= payload
.transactionId
;
494 chargingStation
.getConnectorStatus(connectorId
).transactionIdTag
= requestPayload
.idTag
;
495 chargingStation
.getConnectorStatus(
497 ).transactionEnergyActiveImportRegisterValue
= 0;
498 chargingStation
.getConnectorStatus(connectorId
).transactionBeginMeterValue
=
499 OCPP16ServiceUtils
.buildTransactionBeginMeterValue(
502 requestPayload
.meterStart
504 chargingStation
.getBeginEndMeterValues() &&
505 (await chargingStation
.ocppRequestService
.requestHandler
<
506 OCPP16MeterValuesRequest
,
507 OCPP16MeterValuesResponse
508 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
510 transactionId
: payload
.transactionId
,
511 meterValue
: [chargingStation
.getConnectorStatus(connectorId
).transactionBeginMeterValue
],
513 await chargingStation
.ocppRequestService
.requestHandler
<
514 OCPP16StatusNotificationRequest
,
515 OCPP16StatusNotificationResponse
516 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
518 status: OCPP16ChargePointStatus
.CHARGING
,
519 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
521 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.CHARGING
;
523 `${chargingStation.logPrefix()} Transaction ${payload.transactionId.toString()} STARTED on ${
524 chargingStation.stationInfo.chargingStationId
525 }#${connectorId.toString()} for idTag '${requestPayload.idTag}'`
527 if (chargingStation
.stationInfo
.powerSharedByConnectors
) {
528 chargingStation
.powerDivider
++;
530 const configuredMeterValueSampleInterval
=
531 ChargingStationConfigurationUtils
.getConfigurationKey(
533 OCPP16StandardParametersKey
.MeterValueSampleInterval
535 chargingStation
.startMeterValues(
537 configuredMeterValueSampleInterval
538 ? Utils
.convertToInt(configuredMeterValueSampleInterval
.value
) * 1000
539 : Constants
.DEFAULT_METER_VALUES_INTERVAL
543 `${chargingStation.logPrefix()} Starting transaction id ${payload.transactionId.toString()} REJECTED with status '${
544 payload.idTagInfo?.status
545 }', idTag '${requestPayload.idTag}'`
547 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
);
551 private async resetConnectorOnStartTransactionError(
552 chargingStation
: ChargingStation
,
555 chargingStation
.resetConnectorStatus(connectorId
);
557 chargingStation
.getConnectorStatus(connectorId
)?.status !== OCPP16ChargePointStatus
.AVAILABLE
559 await chargingStation
.ocppRequestService
.requestHandler
<
560 OCPP16StatusNotificationRequest
,
561 OCPP16StatusNotificationResponse
562 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
564 status: OCPP16ChargePointStatus
.AVAILABLE
,
565 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
567 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.AVAILABLE
;
571 private async handleResponseStopTransaction(
572 chargingStation
: ChargingStation
,
573 payload
: OCPP16StopTransactionResponse
,
574 requestPayload
: OCPP16StopTransactionRequest
576 const transactionConnectorId
= chargingStation
.getConnectorIdByTransactionId(
577 requestPayload
.transactionId
579 if (Utils
.isNullOrUndefined(transactionConnectorId
)) {
581 `${chargingStation.logPrefix()} Trying to stop a non existing transaction ${requestPayload.transactionId.toString()}`
585 chargingStation
.getBeginEndMeterValues() === true &&
586 chargingStation
.getOcppStrictCompliance() === false &&
587 chargingStation
.getOutOfOrderEndMeterValues() === true &&
588 (await chargingStation
.ocppRequestService
.requestHandler
<
589 OCPP16MeterValuesRequest
,
590 OCPP16MeterValuesResponse
591 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
592 connectorId
: transactionConnectorId
,
593 transactionId
: requestPayload
.transactionId
,
595 OCPP16ServiceUtils
.buildTransactionEndMeterValue(
597 transactionConnectorId
,
598 requestPayload
.meterStop
603 chargingStation
.isChargingStationAvailable() === false ||
604 chargingStation
.isConnectorAvailable(transactionConnectorId
) === false
606 await chargingStation
.ocppRequestService
.requestHandler
<
607 OCPP16StatusNotificationRequest
,
608 OCPP16StatusNotificationResponse
609 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
610 connectorId
: transactionConnectorId
,
611 status: OCPP16ChargePointStatus
.UNAVAILABLE
,
612 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
614 chargingStation
.getConnectorStatus(transactionConnectorId
).status =
615 OCPP16ChargePointStatus
.UNAVAILABLE
;
617 await chargingStation
.ocppRequestService
.requestHandler
<
618 OCPP16BootNotificationRequest
,
619 OCPP16BootNotificationResponse
620 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
621 connectorId
: transactionConnectorId
,
622 status: OCPP16ChargePointStatus
.AVAILABLE
,
623 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
625 chargingStation
.getConnectorStatus(transactionConnectorId
).status =
626 OCPP16ChargePointStatus
.AVAILABLE
;
628 if (chargingStation
.stationInfo
.powerSharedByConnectors
) {
629 chargingStation
.powerDivider
--;
631 chargingStation
.resetConnectorStatus(transactionConnectorId
);
632 const logMsg
= `${chargingStation.logPrefix()} Transaction ${requestPayload.transactionId.toString()} STOPPED on ${
633 chargingStation.stationInfo.chargingStationId
634 }#${transactionConnectorId?.toString()} with status '${
635 payload.idTagInfo?.status ?? 'undefined'
638 Utils
.isNullOrUndefined(payload
.idTagInfo
) ||
639 payload
.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED