1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import { parentPort
} from
'node:worker_threads';
5 import type { JSONSchemaType
} from
'ajv';
7 import { OCPP16ServiceUtils
} from
'./OCPP16ServiceUtils';
10 ChargingStationConfigurationUtils
,
12 } from
'../../../charging-station';
13 import { OCPPError
} from
'../../../exception';
15 type ChangeAvailabilityResponse
,
16 type ChangeConfigurationResponse
,
17 type ClearChargingProfileResponse
,
20 type GetConfigurationResponse
,
21 type GetDiagnosticsResponse
,
24 OCPP16AuthorizationStatus
,
25 type OCPP16AuthorizeRequest
,
26 type OCPP16AuthorizeResponse
,
27 type OCPP16BootNotificationResponse
,
28 OCPP16ChargePointStatus
,
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
,
50 type SetChargingProfileResponse
,
51 type UnlockConnectorResponse
,
52 } from
'../../../types';
53 import { Constants
, Utils
, buildUpdatedMessage
, logger
} from
'../../../utils';
54 import { OCPPResponseService
} from
'../OCPPResponseService';
56 const moduleName
= 'OCPP16ResponseService';
58 export class OCPP16ResponseService
extends OCPPResponseService
{
59 public jsonIncomingRequestResponseSchemas
: Map
<
60 OCPP16IncomingRequestCommand
,
61 JSONSchemaType
<JsonObject
>
64 private responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>;
65 private jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
67 public constructor() {
68 // if (new.target?.name === moduleName) {
69 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
71 super(OCPPVersion
.VERSION_16
);
72 this.responseHandlers
= new Map
<OCPP16RequestCommand
, ResponseHandler
>([
73 [OCPP16RequestCommand
.BOOT_NOTIFICATION
, this.handleResponseBootNotification
.bind(this)],
74 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this)],
75 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this)],
76 [OCPP16RequestCommand
.START_TRANSACTION
, this.handleResponseStartTransaction
.bind(this)],
77 [OCPP16RequestCommand
.STOP_TRANSACTION
, this.handleResponseStopTransaction
.bind(this)],
78 [OCPP16RequestCommand
.STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
79 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this)],
80 [OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
81 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this)],
82 [OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
84 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
86 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
87 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
88 'assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
94 OCPP16RequestCommand
.HEARTBEAT
,
95 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
96 'assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
102 OCPP16RequestCommand
.AUTHORIZE
,
103 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
104 'assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
110 OCPP16RequestCommand
.START_TRANSACTION
,
111 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
112 'assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
118 OCPP16RequestCommand
.STOP_TRANSACTION
,
119 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
120 'assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
126 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
127 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
128 'assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
134 OCPP16RequestCommand
.METER_VALUES
,
135 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
136 'assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
142 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
143 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
144 'assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
150 OCPP16RequestCommand
.DATA_TRANSFER
,
151 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
152 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
158 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
159 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
160 'assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
166 this.jsonIncomingRequestResponseSchemas
= new Map([
168 OCPP16IncomingRequestCommand
.RESET
,
169 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
170 'assets/json-schemas/ocpp/1.6/ResetResponse.json',
176 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
177 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
178 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
184 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
185 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
186 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
192 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
193 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
194 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
200 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
201 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
202 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
208 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
209 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
210 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
216 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
217 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
218 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
224 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
225 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
226 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
232 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
233 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
234 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
240 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
241 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
242 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
248 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
249 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
250 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
256 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
257 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
258 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
264 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
265 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
266 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
272 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
273 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
274 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
280 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
281 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
282 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
288 OCPP16IncomingRequestCommand
.RESERVE_NOW
,
289 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ReserveNowResponse
>(
290 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json',
296 OCPP16IncomingRequestCommand
.CANCEL_RESERVATION
,
297 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
298 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json',
304 this.validatePayload
= this.validatePayload
.bind(this) as (
305 chargingStation
: ChargingStation
,
306 commandName
: OCPP16RequestCommand
,
311 public async responseHandler(
312 chargingStation
: ChargingStation
,
313 commandName
: OCPP16RequestCommand
,
315 requestPayload
: JsonType
318 chargingStation
.isRegistered() === true ||
319 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
322 this.responseHandlers
.has(commandName
) === true &&
323 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
326 this.validatePayload(chargingStation
, commandName
, payload
);
327 await this.responseHandlers
.get(commandName
)(chargingStation
, payload
, requestPayload
);
330 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
338 ErrorType
.NOT_IMPLEMENTED
,
339 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
350 ErrorType
.SECURITY_ERROR
,
351 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
355 )} while the charging station is not registered on the central server.`,
362 private validatePayload(
363 chargingStation
: ChargingStation
,
364 commandName
: OCPP16RequestCommand
,
367 if (this.jsonSchemas
.has(commandName
) === true) {
368 return this.validateResponsePayload(
371 this.jsonSchemas
.get(commandName
),
376 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
381 private handleResponseBootNotification(
382 chargingStation
: ChargingStation
,
383 payload
: OCPP16BootNotificationResponse
385 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
386 ChargingStationConfigurationUtils
.addConfigurationKey(
388 OCPP16StandardParametersKey
.HeartbeatInterval
,
389 payload
.interval
.toString(),
391 { overwrite
: true, save
: true }
393 ChargingStationConfigurationUtils
.addConfigurationKey(
395 OCPP16StandardParametersKey
.HeartBeatInterval
,
396 payload
.interval
.toString(),
398 { overwrite
: true, save
: true }
400 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
);
402 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
403 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
405 }' state on the central server`;
406 payload
.status === RegistrationStatusEnumType
.REJECTED
407 ? logger
.warn(logMsg
)
408 : logger
.info(logMsg
);
411 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
417 private handleResponseAuthorize(
418 chargingStation
: ChargingStation
,
419 payload
: OCPP16AuthorizeResponse
,
420 requestPayload
: OCPP16AuthorizeRequest
422 let authorizeConnectorId
: number;
423 if (chargingStation
.hasEvses
) {
424 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
426 for (const [connectorId
, connectorStatus
] of evseStatus
.connectors
) {
427 if (connectorStatus
?.authorizeIdTag
=== requestPayload
.idTag
) {
428 authorizeConnectorId
= connectorId
;
435 for (const connectorId
of chargingStation
.connectors
.keys()) {
438 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
440 authorizeConnectorId
= connectorId
;
445 const authorizeConnectorIdDefined
= !Utils
.isNullOrUndefined(authorizeConnectorId
);
446 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
447 authorizeConnectorIdDefined
&&
448 (chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= true);
450 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${
451 authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}
` : ''
455 if (authorizeConnectorIdDefined
) {
456 chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= false;
457 delete chargingStation
.getConnectorStatus(authorizeConnectorId
)?.authorizeIdTag
;
460 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
461 payload.idTagInfo.status
462 }'${authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}` : ''}`
467 private async handleResponseStartTransaction(
468 chargingStation: ChargingStation,
469 payload: OCPP16StartTransactionResponse,
470 requestPayload: OCPP16StartTransactionRequest
472 const transactionConnectorId = requestPayload.connectorId;
474 transactionConnectorId === 0 ||
475 chargingStation.hasConnector(transactionConnectorId) === false
478 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector id ${transactionConnectorId.toString()}
`
483 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
485 chargingStation.getAuthorizeRemoteTxRequests() === true &&
486 chargingStation.getLocalAuthListEnabled() === true &&
487 chargingStation.hasIdTags() &&
488 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false
491 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{
492 chargingStation
.getConnectorStatus(transactionConnectorId
)?.localAuthorizeIdTag
493 } on connector id ${transactionConnectorId.toString()}
`
495 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
499 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
501 chargingStation.getAuthorizeRemoteTxRequests() === true &&
502 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
503 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false &&
504 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized === false
507 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{
508 chargingStation
.getConnectorStatus(transactionConnectorId
)?.authorizeIdTag
509 } on connector id ${transactionConnectorId.toString()}
`
511 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
515 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized &&
516 chargingStation.getConnectorStatus(transactionConnectorId)?.authorizeIdTag !==
520 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
522 } different from the authorize request one $
{
523 chargingStation
.getConnectorStatus(transactionConnectorId
)?.authorizeIdTag
524 } on connector id ${transactionConnectorId.toString()}
`
526 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
530 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized &&
531 chargingStation.getConnectorStatus(transactionConnectorId)?.localAuthorizeIdTag !==
535 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
537 } different from the local authorized one $
{
538 chargingStation
.getConnectorStatus(transactionConnectorId
)?.localAuthorizeIdTag
539 } on connector id ${transactionConnectorId.toString()}
`
541 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
544 if (chargingStation.getConnectorStatus(transactionConnectorId)?.transactionStarted === true) {
546 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${transactionConnectorId.toString()}
:`,
547 chargingStation.getConnectorStatus(transactionConnectorId)
551 if (chargingStation.hasEvses) {
552 for (const [evseId, evseStatus] of chargingStation.evses) {
553 if (evseStatus.connectors.size > 1) {
554 for (const [connectorId, connectorStatus] of evseStatus.connectors) {
556 transactionConnectorId !== connectorId &&
557 connectorStatus?.transactionStarted === true
560 `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId.toString()}
:`,
563 await this.resetConnectorOnStartTransactionError(
565 transactionConnectorId
574 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
575 OCPP16ChargePointStatus.Available &&
576 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
577 OCPP16ChargePointStatus.Preparing
580 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with status $
{
581 chargingStation
.getConnectorStatus(transactionConnectorId
)?.status
586 if (!Number.isInteger(payload.transactionId)) {
588 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with a non integer transaction id $
{
589 payload
.transactionId
590 }, converting to integer
`
592 payload.transactionId = Utils.convertToInt(payload.transactionId);
595 if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
596 chargingStation.getConnectorStatus(transactionConnectorId).transactionStarted = true;
597 chargingStation.getConnectorStatus(transactionConnectorId).transactionId =
598 payload.transactionId;
599 chargingStation.getConnectorStatus(transactionConnectorId).transactionIdTag =
600 requestPayload.idTag;
601 chargingStation.getConnectorStatus(
602 transactionConnectorId
603 ).transactionEnergyActiveImportRegisterValue = 0;
604 chargingStation.getConnectorStatus(transactionConnectorId).transactionBeginMeterValue =
605 OCPP16ServiceUtils.buildTransactionBeginMeterValue(
607 transactionConnectorId,
608 requestPayload.meterStart
610 chargingStation.getBeginEndMeterValues() &&
611 (await chargingStation.ocppRequestService.requestHandler<
612 OCPP16MeterValuesRequest,
613 OCPP16MeterValuesResponse
614 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
615 connectorId: transactionConnectorId,
616 transactionId: payload.transactionId,
618 chargingStation.getConnectorStatus(transactionConnectorId).transactionBeginMeterValue,
621 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
623 transactionConnectorId,
624 OCPP16ChargePointStatus.Charging
627 `${chargingStation.logPrefix()} Transaction
with id ${payload.transactionId.toString()} STARTED on $
{
628 chargingStation
.stationInfo
.chargingStationId
629 }#${transactionConnectorId.toString()}
for idTag
'${requestPayload.idTag}'`
631 if (chargingStation.stationInfo.powerSharedByConnectors) {
632 ++chargingStation.powerDivider;
634 const configuredMeterValueSampleInterval =
635 ChargingStationConfigurationUtils.getConfigurationKey(
637 OCPP16StandardParametersKey.MeterValueSampleInterval
639 chargingStation.startMeterValues(
640 transactionConnectorId,
641 configuredMeterValueSampleInterval
642 ? Utils.convertToInt(configuredMeterValueSampleInterval.value) * 1000
643 : Constants.DEFAULT_METER_VALUES_INTERVAL
647 `${chargingStation.logPrefix()} Starting transaction
with id ${payload.transactionId.toString()} REJECTED
with status '${
648 payload.idTagInfo?.status
649 }', idTag
'${requestPayload.idTag}'`
651 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
655 private async resetConnectorOnStartTransactionError(
656 chargingStation: ChargingStation,
659 ChargingStationUtils.resetConnectorStatus(chargingStation.getConnectorStatus(connectorId));
660 chargingStation.stopMeterValues(connectorId);
661 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
663 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
665 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
668 OCPP16ChargePointStatus.Available
673 private async handleResponseStopTransaction(
674 chargingStation: ChargingStation,
675 payload: OCPP16StopTransactionResponse,
676 requestPayload: OCPP16StopTransactionRequest
678 const transactionConnectorId = chargingStation.getConnectorIdByTransactionId(
679 requestPayload.transactionId
681 if (Utils.isNullOrUndefined(transactionConnectorId)) {
683 `${chargingStation.logPrefix()} Trying to stop a non existing transaction
with id ${requestPayload.transactionId.toString()}
`
687 chargingStation.getBeginEndMeterValues() === true &&
688 chargingStation.getOcppStrictCompliance() === false &&
689 chargingStation.getOutOfOrderEndMeterValues() === true &&
690 (await chargingStation.ocppRequestService.requestHandler<
691 OCPP16MeterValuesRequest,
692 OCPP16MeterValuesResponse
693 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
694 connectorId: transactionConnectorId,
695 transactionId: requestPayload.transactionId,
697 OCPP16ServiceUtils.buildTransactionEndMeterValue(
699 transactionConnectorId,
700 requestPayload.meterStop
705 chargingStation.isChargingStationAvailable() === false ||
706 chargingStation.isConnectorAvailable(transactionConnectorId) === false
708 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
710 transactionConnectorId,
711 OCPP16ChargePointStatus.Unavailable
714 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
716 transactionConnectorId,
717 OCPP16ChargePointStatus.Available
720 if (chargingStation.stationInfo.powerSharedByConnectors) {
721 chargingStation.powerDivider--;
723 ChargingStationUtils.resetConnectorStatus(
724 chargingStation.getConnectorStatus(transactionConnectorId)
726 chargingStation.stopMeterValues(transactionConnectorId);
727 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
728 const logMsg = `${chargingStation.logPrefix()} Transaction
with id ${requestPayload.transactionId.toString()} STOPPED on $
{
729 chargingStation
.stationInfo
.chargingStationId
730 }#${transactionConnectorId?.toString()}
with status '${
731 payload.idTagInfo?.status ?? 'undefined'
734 Utils.isNullOrUndefined(payload.idTagInfo) ||
735 payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED