1 // Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
3 import type { ValidateFunction
} from
'ajv'
4 import { secondsToMilliseconds
} from
'date-fns'
6 import { OCPP16ServiceUtils
} from
'./OCPP16ServiceUtils.js'
11 hasReservationExpired
,
13 } from
'../../../charging-station/index.js'
14 import { OCPPError
} from
'../../../exception/index.js'
16 type ChangeConfigurationResponse
,
19 type GetConfigurationResponse
,
20 type GetDiagnosticsResponse
,
22 OCPP16AuthorizationStatus
,
23 type OCPP16AuthorizeRequest
,
24 type OCPP16AuthorizeResponse
,
25 type OCPP16BootNotificationResponse
,
26 type OCPP16ChangeAvailabilityResponse
,
27 OCPP16ChargePointStatus
,
28 type OCPP16ClearChargingProfileResponse
,
29 type OCPP16DataTransferResponse
,
30 type OCPP16DiagnosticsStatusNotificationResponse
,
31 type OCPP16FirmwareStatusNotificationResponse
,
32 type OCPP16GetCompositeScheduleResponse
,
33 type OCPP16HeartbeatResponse
,
34 OCPP16IncomingRequestCommand
,
35 type OCPP16MeterValuesRequest
,
36 type OCPP16MeterValuesResponse
,
38 type OCPP16ReserveNowResponse
,
39 OCPP16StandardParametersKey
,
40 type OCPP16StartTransactionRequest
,
41 type OCPP16StartTransactionResponse
,
42 type OCPP16StatusNotificationResponse
,
43 type OCPP16StopTransactionRequest
,
44 type OCPP16StopTransactionResponse
,
45 type OCPP16TriggerMessageResponse
,
46 type OCPP16UpdateFirmwareResponse
,
48 RegistrationStatusEnumType
,
49 ReservationTerminationReason
,
51 type SetChargingProfileResponse
,
52 type UnlockConnectorResponse
53 } from
'../../../types/index.js'
54 import { Constants
, convertToInt
, logger
} from
'../../../utils/index.js'
55 import { OCPPResponseService
} from
'../OCPPResponseService.js'
57 const moduleName
= 'OCPP16ResponseService'
59 export class OCPP16ResponseService
extends OCPPResponseService
{
60 public jsonSchemasIncomingRequestResponseValidateFunction
: Map
<
61 OCPP16IncomingRequestCommand
,
62 ValidateFunction
<JsonType
>
65 protected jsonSchemasValidateFunction
: Map
<OCPP16RequestCommand
, ValidateFunction
<JsonType
>>
66 private readonly responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>
68 public constructor () {
69 // if (new.target.name === moduleName) {
70 // throw new TypeError(`Cannot construct ${new.target.name} instances directly`)
72 super(OCPPVersion
.VERSION_16
)
73 this.responseHandlers
= new Map
<OCPP16RequestCommand
, ResponseHandler
>([
75 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
76 this.handleResponseBootNotification
.bind(this) as ResponseHandler
78 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
],
79 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this) as ResponseHandler
],
81 OCPP16RequestCommand
.START_TRANSACTION
,
82 this.handleResponseStartTransaction
.bind(this) as ResponseHandler
85 OCPP16RequestCommand
.STOP_TRANSACTION
,
86 this.handleResponseStopTransaction
.bind(this) as ResponseHandler
89 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
90 this.emptyResponseHandler
.bind(this) as ResponseHandler
92 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
],
94 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
95 this.emptyResponseHandler
.bind(this) as ResponseHandler
97 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
],
98 [OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, this.emptyResponseHandler
]
100 this.jsonSchemasValidateFunction
= new Map
<OCPP16RequestCommand
, ValidateFunction
<JsonType
>>([
102 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
105 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
106 'assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
114 OCPP16RequestCommand
.HEARTBEAT
,
117 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
118 'assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
126 OCPP16RequestCommand
.AUTHORIZE
,
129 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
130 'assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
138 OCPP16RequestCommand
.START_TRANSACTION
,
141 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
142 'assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
150 OCPP16RequestCommand
.STOP_TRANSACTION
,
153 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
154 'assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
162 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
165 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
166 'assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
174 OCPP16RequestCommand
.METER_VALUES
,
177 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
178 'assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
186 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
189 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
190 'assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
198 OCPP16RequestCommand
.DATA_TRANSFER
,
201 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
202 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
210 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
213 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
214 'assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
222 this.jsonSchemasIncomingRequestResponseValidateFunction
= new Map
<
223 OCPP16IncomingRequestCommand
,
224 ValidateFunction
<JsonType
>
227 OCPP16IncomingRequestCommand
.RESET
,
230 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
231 'assets/json-schemas/ocpp/1.6/ResetResponse.json',
239 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
242 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
243 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
251 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
254 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ChangeAvailabilityResponse
>(
255 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
263 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
266 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
267 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
275 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
278 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
279 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
287 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
290 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
291 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
299 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
302 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
303 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
311 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
314 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
315 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
323 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
326 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ClearChargingProfileResponse
>(
327 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
335 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
338 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
339 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
347 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
350 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
351 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
359 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
362 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
363 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
371 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
374 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
375 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
383 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
386 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
387 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
395 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
398 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
399 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
407 OCPP16IncomingRequestCommand
.RESERVE_NOW
,
410 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ReserveNowResponse
>(
411 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json',
419 OCPP16IncomingRequestCommand
.CANCEL_RESERVATION
,
422 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
423 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json',
431 this.validatePayload
= this.validatePayload
.bind(this)
434 public async responseHandler
<ReqType
extends JsonType
, ResType
extends JsonType
>(
435 chargingStation
: ChargingStation
,
436 commandName
: OCPP16RequestCommand
,
438 requestPayload
: ReqType
440 if (chargingStation
.isRegistered() || commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
) {
442 this.responseHandlers
.has(commandName
) &&
443 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
)
446 this.validatePayload(chargingStation
, commandName
, payload
)
447 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
448 await this.responseHandlers
.get(commandName
)!(chargingStation
, payload
, requestPayload
)
451 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
459 ErrorType
.NOT_IMPLEMENTED
,
460 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
471 ErrorType
.SECURITY_ERROR
,
472 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
476 )} while the charging station is not registered on the central server.`,
483 private validatePayload (
484 chargingStation
: ChargingStation
,
485 commandName
: OCPP16RequestCommand
,
488 if (this.jsonSchemasValidateFunction
.has(commandName
)) {
489 return this.validateResponsePayload(chargingStation
, commandName
, payload
)
492 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema validation function found for command '${commandName}' PDU validation`
497 private handleResponseBootNotification (
498 chargingStation
: ChargingStation
,
499 payload
: OCPP16BootNotificationResponse
501 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
504 OCPP16StandardParametersKey
.HeartbeatInterval
,
505 payload
.interval
.toString(),
507 { overwrite
: true, save
: true }
511 OCPP16StandardParametersKey
.HeartBeatInterval
,
512 payload
.interval
.toString(),
514 { overwrite
: true, save
: true }
516 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
)
518 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
519 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
521 }' state on the central server`
522 payload
.status === RegistrationStatusEnumType
.REJECTED
523 ? logger
.warn(logMsg
)
524 : logger
.info(logMsg
)
527 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
533 private handleResponseAuthorize (
534 chargingStation
: ChargingStation
,
535 payload
: OCPP16AuthorizeResponse
,
536 requestPayload
: OCPP16AuthorizeRequest
538 let authorizeConnectorId
: number | undefined
539 if (chargingStation
.hasEvses
) {
540 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
542 for (const [connectorId
, connectorStatus
] of evseStatus
.connectors
) {
543 if (connectorStatus
.authorizeIdTag
=== requestPayload
.idTag
) {
544 authorizeConnectorId
= connectorId
551 for (const connectorId
of chargingStation
.connectors
.keys()) {
554 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
556 authorizeConnectorId
= connectorId
561 if (authorizeConnectorId
!= null) {
562 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
563 const authorizeConnectorStatus
= chargingStation
.getConnectorStatus(authorizeConnectorId
)!
564 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
565 authorizeConnectorStatus
.idTagAuthorized
= true
567 `${chargingStation.logPrefix()} idTag '${
569 }' accepted on connector id ${authorizeConnectorId}`
572 authorizeConnectorStatus
.idTagAuthorized
= false
573 delete authorizeConnectorStatus
.authorizeIdTag
575 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
576 payload.idTagInfo.status
582 `${chargingStation.logPrefix()} idTag '${
584 }' has no authorize request pending`
589 private async handleResponseStartTransaction (
590 chargingStation
: ChargingStation
,
591 payload
: OCPP16StartTransactionResponse
,
592 requestPayload
: OCPP16StartTransactionRequest
594 const { connectorId
} = requestPayload
595 if (connectorId
=== 0 || !chargingStation
.hasConnector(connectorId
)) {
597 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector id ${connectorId}`
601 const connectorStatus
= chargingStation
.getConnectorStatus(connectorId
)
603 connectorStatus
?.transactionRemoteStarted
=== true &&
604 chargingStation
.getAuthorizeRemoteTxRequests() &&
605 chargingStation
.getLocalAuthListEnabled() &&
606 chargingStation
.hasIdTags() &&
607 connectorStatus
.idTagLocalAuthorized
=== false
610 `${chargingStation.logPrefix()} Trying to start a transaction with a not local authorized idTag ${
611 connectorStatus.localAuthorizeIdTag
612 } on connector id ${connectorId}`
614 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
618 connectorStatus
?.transactionRemoteStarted
=== true &&
619 chargingStation
.getAuthorizeRemoteTxRequests() &&
620 chargingStation
.stationInfo
?.remoteAuthorization
=== true &&
621 connectorStatus
.idTagLocalAuthorized
=== false &&
622 connectorStatus
.idTagAuthorized
=== false
625 `${chargingStation.logPrefix()} Trying to start a transaction with a not authorized idTag ${
626 connectorStatus.authorizeIdTag
627 } on connector id ${connectorId}`
629 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
633 connectorStatus
?.idTagAuthorized
=== true &&
634 connectorStatus
.authorizeIdTag
!== requestPayload
.idTag
637 `${chargingStation.logPrefix()} Trying to start a transaction with an idTag ${
639 } different from the authorize request one ${
640 connectorStatus.authorizeIdTag
641 } on connector id ${connectorId}`
643 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
647 connectorStatus
?.idTagLocalAuthorized
=== true &&
648 connectorStatus
.localAuthorizeIdTag
!== requestPayload
.idTag
651 `${chargingStation.logPrefix()} Trying to start a transaction with an idTag ${
653 } different from the local authorized one ${
654 connectorStatus.localAuthorizeIdTag
655 } on connector id ${connectorId}`
657 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
660 if (connectorStatus
?.transactionStarted
=== true) {
662 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${connectorId} by idTag ${
663 connectorStatus.transactionIdTag
668 if (chargingStation
.hasEvses
) {
669 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
670 if (evseStatus
.connectors
.size
> 1) {
671 for (const [id
, status] of evseStatus
.connectors
) {
672 if (id
!== connectorId
&& status.transactionStarted
=== true) {
674 `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId} by connector id ${id} with idTag ${
675 status.transactionIdTag
678 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
686 connectorStatus
?.status !== OCPP16ChargePointStatus
.Available
&&
687 connectorStatus
?.status !== OCPP16ChargePointStatus
.Preparing
690 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${connectorId} with status ${connectorStatus?.status}`
694 if (!Number.isSafeInteger(payload
.transactionId
)) {
696 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${connectorId} with a non integer transaction id ${
697 payload.transactionId
698 }, converting to integer`
700 payload
.transactionId
= convertToInt(payload
.transactionId
)
703 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
704 connectorStatus
.transactionStarted
= true
705 connectorStatus
.transactionStart
= requestPayload
.timestamp
706 connectorStatus
.transactionId
= payload
.transactionId
707 connectorStatus
.transactionIdTag
= requestPayload
.idTag
708 connectorStatus
.transactionEnergyActiveImportRegisterValue
= 0
709 connectorStatus
.transactionBeginMeterValue
=
710 OCPP16ServiceUtils
.buildTransactionBeginMeterValue(
713 requestPayload
.meterStart
715 if (requestPayload
.reservationId
!= null) {
716 const reservation
= chargingStation
.getReservationBy(
718 requestPayload
.reservationId
720 if (reservation
!= null) {
721 if (reservation
.idTag
!== requestPayload
.idTag
) {
723 `${chargingStation.logPrefix()} Reserved transaction ${
724 payload.transactionId
725 } started with a different idTag ${requestPayload.idTag} than the reservation one ${
730 if (hasReservationExpired(reservation
)) {
732 `${chargingStation.logPrefix()} Reserved transaction ${
733 payload.transactionId
734 } started with expired reservation ${
735 requestPayload.reservationId
736 } (expiry date: ${reservation.expiryDate.toISOString()}))`
739 await chargingStation
.removeReservation(
741 ReservationTerminationReason
.TRANSACTION_STARTED
745 `${chargingStation.logPrefix()} Reserved transaction ${
746 payload.transactionId
747 } started with unknown reservation ${requestPayload.reservationId}`
751 chargingStation
.stationInfo
?.beginEndMeterValues
=== true &&
752 (await chargingStation
.ocppRequestService
.requestHandler
<
753 OCPP16MeterValuesRequest
,
754 OCPP16MeterValuesResponse
755 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
757 transactionId
: payload
.transactionId
,
758 meterValue
: [connectorStatus
.transactionBeginMeterValue
]
759 } satisfies OCPP16MeterValuesRequest
))
760 await OCPP16ServiceUtils
.sendAndSetConnectorStatus(
763 OCPP16ChargePointStatus
.Charging
766 `${chargingStation.logPrefix()} Transaction with id ${
767 payload.transactionId
768 } STARTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for idTag '${
772 if (chargingStation
.stationInfo
?.powerSharedByConnectors
=== true) {
773 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
774 ++chargingStation
.powerDivider
!
776 const configuredMeterValueSampleInterval
= getConfigurationKey(
778 OCPP16StandardParametersKey
.MeterValueSampleInterval
780 chargingStation
.startMeterValues(
782 configuredMeterValueSampleInterval
!= null
783 ? secondsToMilliseconds(convertToInt(configuredMeterValueSampleInterval
.value
))
784 : Constants
.DEFAULT_METER_VALUES_INTERVAL
788 `${chargingStation.logPrefix()} Starting transaction with id ${
789 payload.transactionId
791 chargingStation.stationInfo?.chargingStationId
792 }#${connectorId} with status '${payload.idTagInfo.status}', idTag '${
795 OCPP16ServiceUtils.hasReservation(chargingStation, connectorId, requestPayload.idTag)
796 ? `, reservationId
'${requestPayload.reservationId}'`
800 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
804 private async resetConnectorOnStartTransactionError (
805 chargingStation
: ChargingStation
,
808 const connectorStatus
= chargingStation
.getConnectorStatus(connectorId
)
809 resetConnectorStatus(connectorStatus
)
810 chargingStation
.stopMeterValues(connectorId
)
811 if (connectorStatus
?.status !== OCPP16ChargePointStatus
.Available
) {
812 await OCPP16ServiceUtils
.sendAndSetConnectorStatus(
815 OCPP16ChargePointStatus
.Available
820 private async handleResponseStopTransaction (
821 chargingStation
: ChargingStation
,
822 payload
: OCPP16StopTransactionResponse
,
823 requestPayload
: OCPP16StopTransactionRequest
825 const transactionConnectorId
= chargingStation
.getConnectorIdByTransactionId(
826 requestPayload
.transactionId
828 if (transactionConnectorId
== null) {
830 `${chargingStation.logPrefix()} Trying to stop a non existing transaction with id ${
831 requestPayload.transactionId
836 chargingStation
.stationInfo
?.beginEndMeterValues
=== true &&
837 chargingStation
.stationInfo
.ocppStrictCompliance
=== false &&
838 chargingStation
.stationInfo
.outOfOrderEndMeterValues
=== true &&
839 (await chargingStation
.ocppRequestService
.requestHandler
<
840 OCPP16MeterValuesRequest
,
841 OCPP16MeterValuesResponse
842 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
843 connectorId
: transactionConnectorId
,
844 transactionId
: requestPayload
.transactionId
,
846 OCPP16ServiceUtils
.buildTransactionEndMeterValue(
848 transactionConnectorId
,
849 requestPayload
.meterStop
854 !chargingStation
.isChargingStationAvailable() ||
855 !chargingStation
.isConnectorAvailable(transactionConnectorId
)
857 await OCPP16ServiceUtils
.sendAndSetConnectorStatus(
859 transactionConnectorId
,
860 OCPP16ChargePointStatus
.Unavailable
863 await OCPP16ServiceUtils
.sendAndSetConnectorStatus(
865 transactionConnectorId
,
866 OCPP16ChargePointStatus
.Available
869 if (chargingStation
.stationInfo
?.powerSharedByConnectors
=== true) {
870 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
871 chargingStation
.powerDivider
!--
873 resetConnectorStatus(chargingStation
.getConnectorStatus(transactionConnectorId
))
874 chargingStation
.stopMeterValues(transactionConnectorId
)
875 const logMsg
= `${chargingStation.logPrefix()} Transaction with id ${
876 requestPayload.transactionId
878 chargingStation.stationInfo?.chargingStationId
879 }#${transactionConnectorId} with status '${payload.idTagInfo?.status}'`
881 payload
.idTagInfo
== null ||
882 payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED