1 // Partial Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
3 import type { JSONSchemaType
} 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 jsonIncomingRequestResponseSchemas
: Map
<
61 OCPP16IncomingRequestCommand
,
62 JSONSchemaType
<JsonType
>
65 private readonly responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>
66 private readonly jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonType
>>
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.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonType
>>([
102 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
103 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
104 'assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
110 OCPP16RequestCommand
.HEARTBEAT
,
111 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
112 'assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
118 OCPP16RequestCommand
.AUTHORIZE
,
119 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
120 'assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
126 OCPP16RequestCommand
.START_TRANSACTION
,
127 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
128 'assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
134 OCPP16RequestCommand
.STOP_TRANSACTION
,
135 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
136 'assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
142 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
143 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
144 'assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
150 OCPP16RequestCommand
.METER_VALUES
,
151 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
152 'assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
158 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
159 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
160 'assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
166 OCPP16RequestCommand
.DATA_TRANSFER
,
167 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
168 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
174 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
175 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
176 'assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
182 this.jsonIncomingRequestResponseSchemas
= new Map([
184 OCPP16IncomingRequestCommand
.RESET
,
185 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
186 'assets/json-schemas/ocpp/1.6/ResetResponse.json',
192 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
193 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
194 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
200 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
201 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ChangeAvailabilityResponse
>(
202 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
208 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
209 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
210 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
216 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
217 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
218 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
224 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
225 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
226 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
232 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
233 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
234 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
240 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
241 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
242 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
248 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
249 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ClearChargingProfileResponse
>(
250 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
256 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
257 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
258 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
264 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
265 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
266 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
272 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
273 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
274 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
280 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
281 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
282 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
288 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
289 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
290 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
296 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
297 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
298 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
304 OCPP16IncomingRequestCommand
.RESERVE_NOW
,
305 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ReserveNowResponse
>(
306 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json',
312 OCPP16IncomingRequestCommand
.CANCEL_RESERVATION
,
313 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
314 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json',
320 this.validatePayload
= this.validatePayload
.bind(this) as (
321 chargingStation
: ChargingStation
,
322 commandName
: OCPP16RequestCommand
,
327 public async responseHandler
<ReqType
extends JsonType
, ResType
extends JsonType
>(
328 chargingStation
: ChargingStation
,
329 commandName
: OCPP16RequestCommand
,
331 requestPayload
: ReqType
333 if (chargingStation
.isRegistered() || commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
) {
335 this.responseHandlers
.has(commandName
) &&
336 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
)
339 this.validatePayload(chargingStation
, commandName
, payload
)
340 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
341 await this.responseHandlers
.get(commandName
)!(chargingStation
, payload
, requestPayload
)
344 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
352 ErrorType
.NOT_IMPLEMENTED
,
353 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
364 ErrorType
.SECURITY_ERROR
,
365 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
369 )} while the charging station is not registered on the central server.`,
376 private validatePayload (
377 chargingStation
: ChargingStation
,
378 commandName
: OCPP16RequestCommand
,
381 if (this.jsonSchemas
.has(commandName
)) {
382 return this.validateResponsePayload(
385 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
386 this.jsonSchemas
.get(commandName
)!,
391 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
396 private handleResponseBootNotification (
397 chargingStation
: ChargingStation
,
398 payload
: OCPP16BootNotificationResponse
400 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
403 OCPP16StandardParametersKey
.HeartbeatInterval
,
404 payload
.interval
.toString(),
406 { overwrite
: true, save
: true }
410 OCPP16StandardParametersKey
.HeartBeatInterval
,
411 payload
.interval
.toString(),
413 { overwrite
: true, save
: true }
415 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
)
417 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
418 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
420 }' state on the central server`
421 payload
.status === RegistrationStatusEnumType
.REJECTED
422 ? logger
.warn(logMsg
)
423 : logger
.info(logMsg
)
426 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
432 private handleResponseAuthorize (
433 chargingStation
: ChargingStation
,
434 payload
: OCPP16AuthorizeResponse
,
435 requestPayload
: OCPP16AuthorizeRequest
437 let authorizeConnectorId
: number | undefined
438 if (chargingStation
.hasEvses
) {
439 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
441 for (const [connectorId
, connectorStatus
] of evseStatus
.connectors
) {
442 if (connectorStatus
.authorizeIdTag
=== requestPayload
.idTag
) {
443 authorizeConnectorId
= connectorId
450 for (const connectorId
of chargingStation
.connectors
.keys()) {
453 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
455 authorizeConnectorId
= connectorId
460 if (authorizeConnectorId
!= null) {
461 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
462 const authorizeConnectorStatus
= chargingStation
.getConnectorStatus(authorizeConnectorId
)!
463 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
464 authorizeConnectorStatus
.idTagAuthorized
= true
466 `${chargingStation.logPrefix()} idTag '${
468 }' accepted on connector id ${authorizeConnectorId}`
471 authorizeConnectorStatus
.idTagAuthorized
= false
472 delete authorizeConnectorStatus
.authorizeIdTag
474 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
475 payload.idTagInfo.status
481 `${chargingStation.logPrefix()} idTag '${
483 }' has no authorize request pending`
488 private async handleResponseStartTransaction (
489 chargingStation
: ChargingStation
,
490 payload
: OCPP16StartTransactionResponse
,
491 requestPayload
: OCPP16StartTransactionRequest
493 const { connectorId
} = requestPayload
494 if (connectorId
=== 0 || !chargingStation
.hasConnector(connectorId
)) {
496 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector id ${connectorId}`
500 const connectorStatus
= chargingStation
.getConnectorStatus(connectorId
)
502 connectorStatus
?.transactionRemoteStarted
=== true &&
503 chargingStation
.getAuthorizeRemoteTxRequests() &&
504 chargingStation
.getLocalAuthListEnabled() &&
505 chargingStation
.hasIdTags() &&
506 connectorStatus
.idTagLocalAuthorized
=== false
509 `${chargingStation.logPrefix()} Trying to start a transaction with a not local authorized idTag ${
510 connectorStatus.localAuthorizeIdTag
511 } on connector id ${connectorId}`
513 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
517 connectorStatus
?.transactionRemoteStarted
=== true &&
518 chargingStation
.getAuthorizeRemoteTxRequests() &&
519 chargingStation
.stationInfo
?.remoteAuthorization
=== true &&
520 connectorStatus
.idTagLocalAuthorized
=== false &&
521 connectorStatus
.idTagAuthorized
=== false
524 `${chargingStation.logPrefix()} Trying to start a transaction with a not authorized idTag ${
525 connectorStatus.authorizeIdTag
526 } on connector id ${connectorId}`
528 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
532 connectorStatus
?.idTagAuthorized
=== true &&
533 connectorStatus
.authorizeIdTag
!== requestPayload
.idTag
536 `${chargingStation.logPrefix()} Trying to start a transaction with an idTag ${
538 } different from the authorize request one ${
539 connectorStatus.authorizeIdTag
540 } on connector id ${connectorId}`
542 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
546 connectorStatus
?.idTagLocalAuthorized
=== true &&
547 connectorStatus
.localAuthorizeIdTag
!== requestPayload
.idTag
550 `${chargingStation.logPrefix()} Trying to start a transaction with an idTag ${
552 } different from the local authorized one ${
553 connectorStatus.localAuthorizeIdTag
554 } on connector id ${connectorId}`
556 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
559 if (connectorStatus
?.transactionStarted
=== true) {
561 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${connectorId} by idTag ${
562 connectorStatus.transactionIdTag
567 if (chargingStation
.hasEvses
) {
568 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
569 if (evseStatus
.connectors
.size
> 1) {
570 for (const [id
, status] of evseStatus
.connectors
) {
571 if (id
!== connectorId
&& status.transactionStarted
=== true) {
573 `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId} by connector id ${id} with idTag ${
574 status.transactionIdTag
577 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
585 connectorStatus
?.status !== OCPP16ChargePointStatus
.Available
&&
586 connectorStatus
?.status !== OCPP16ChargePointStatus
.Preparing
589 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${connectorId} with status ${connectorStatus?.status}`
593 if (!Number.isSafeInteger(payload
.transactionId
)) {
595 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${connectorId} with a non integer transaction id ${
596 payload.transactionId
597 }, converting to integer`
599 payload
.transactionId
= convertToInt(payload
.transactionId
)
602 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
603 connectorStatus
.transactionStarted
= true
604 connectorStatus
.transactionStart
= requestPayload
.timestamp
605 connectorStatus
.transactionId
= payload
.transactionId
606 connectorStatus
.transactionIdTag
= requestPayload
.idTag
607 connectorStatus
.transactionEnergyActiveImportRegisterValue
= 0
608 connectorStatus
.transactionBeginMeterValue
=
609 OCPP16ServiceUtils
.buildTransactionBeginMeterValue(
612 requestPayload
.meterStart
614 if (requestPayload
.reservationId
!= null) {
615 const reservation
= chargingStation
.getReservationBy(
617 requestPayload
.reservationId
619 if (reservation
!= null) {
620 if (reservation
.idTag
!== requestPayload
.idTag
) {
622 `${chargingStation.logPrefix()} Reserved transaction ${
623 payload.transactionId
624 } started with a different idTag ${requestPayload.idTag} than the reservation one ${
629 if (hasReservationExpired(reservation
)) {
631 `${chargingStation.logPrefix()} Reserved transaction ${
632 payload.transactionId
633 } started with expired reservation ${
634 requestPayload.reservationId
635 } (expiry date: ${reservation.expiryDate.toISOString()}))`
638 await chargingStation
.removeReservation(
640 ReservationTerminationReason
.TRANSACTION_STARTED
644 `${chargingStation.logPrefix()} Reserved transaction ${
645 payload.transactionId
646 } started with unknown reservation ${requestPayload.reservationId}`
650 chargingStation
.stationInfo
?.beginEndMeterValues
=== true &&
651 (await chargingStation
.ocppRequestService
.requestHandler
<
652 OCPP16MeterValuesRequest
,
653 OCPP16MeterValuesResponse
654 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
656 transactionId
: payload
.transactionId
,
657 meterValue
: [connectorStatus
.transactionBeginMeterValue
]
658 } satisfies OCPP16MeterValuesRequest
))
659 await OCPP16ServiceUtils
.sendAndSetConnectorStatus(
662 OCPP16ChargePointStatus
.Charging
665 `${chargingStation.logPrefix()} Transaction with id ${
666 payload.transactionId
667 } STARTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for idTag '${
671 if (chargingStation
.stationInfo
?.powerSharedByConnectors
=== true) {
672 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
673 ++chargingStation
.powerDivider
!
675 const configuredMeterValueSampleInterval
= getConfigurationKey(
677 OCPP16StandardParametersKey
.MeterValueSampleInterval
679 chargingStation
.startMeterValues(
681 configuredMeterValueSampleInterval
!= null
682 ? secondsToMilliseconds(convertToInt(configuredMeterValueSampleInterval
.value
))
683 : Constants
.DEFAULT_METER_VALUES_INTERVAL
687 `${chargingStation.logPrefix()} Starting transaction with id ${
688 payload.transactionId
690 chargingStation.stationInfo?.chargingStationId
691 }#${connectorId} with status '${payload.idTagInfo.status}', idTag '${
694 OCPP16ServiceUtils.hasReservation(chargingStation, connectorId, requestPayload.idTag)
695 ? `, reservationId
'${requestPayload.reservationId}'`
699 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
)
703 private async resetConnectorOnStartTransactionError (
704 chargingStation
: ChargingStation
,
707 const connectorStatus
= chargingStation
.getConnectorStatus(connectorId
)
708 resetConnectorStatus(connectorStatus
)
709 chargingStation
.stopMeterValues(connectorId
)
710 if (connectorStatus
?.status !== OCPP16ChargePointStatus
.Available
) {
711 await OCPP16ServiceUtils
.sendAndSetConnectorStatus(
714 OCPP16ChargePointStatus
.Available
719 private async handleResponseStopTransaction (
720 chargingStation
: ChargingStation
,
721 payload
: OCPP16StopTransactionResponse
,
722 requestPayload
: OCPP16StopTransactionRequest
724 const transactionConnectorId
= chargingStation
.getConnectorIdByTransactionId(
725 requestPayload
.transactionId
727 if (transactionConnectorId
== null) {
729 `${chargingStation.logPrefix()} Trying to stop a non existing transaction with id ${
730 requestPayload.transactionId
735 chargingStation
.stationInfo
?.beginEndMeterValues
=== true &&
736 chargingStation
.stationInfo
.ocppStrictCompliance
=== false &&
737 chargingStation
.stationInfo
.outOfOrderEndMeterValues
=== true &&
738 (await chargingStation
.ocppRequestService
.requestHandler
<
739 OCPP16MeterValuesRequest
,
740 OCPP16MeterValuesResponse
741 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
742 connectorId
: transactionConnectorId
,
743 transactionId
: requestPayload
.transactionId
,
745 OCPP16ServiceUtils
.buildTransactionEndMeterValue(
747 transactionConnectorId
,
748 requestPayload
.meterStop
753 !chargingStation
.isChargingStationAvailable() ||
754 !chargingStation
.isConnectorAvailable(transactionConnectorId
)
756 await OCPP16ServiceUtils
.sendAndSetConnectorStatus(
758 transactionConnectorId
,
759 OCPP16ChargePointStatus
.Unavailable
762 await OCPP16ServiceUtils
.sendAndSetConnectorStatus(
764 transactionConnectorId
,
765 OCPP16ChargePointStatus
.Available
768 if (chargingStation
.stationInfo
?.powerSharedByConnectors
=== true) {
769 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
770 chargingStation
.powerDivider
!--
772 resetConnectorStatus(chargingStation
.getConnectorStatus(transactionConnectorId
))
773 chargingStation
.stopMeterValues(transactionConnectorId
)
774 const logMsg
= `${chargingStation.logPrefix()} Transaction with id ${
775 requestPayload.transactionId
777 chargingStation.stationInfo?.chargingStationId
778 }#${transactionConnectorId} with status '${payload.idTagInfo?.status}'`
780 payload
.idTagInfo
== null ||
781 payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED