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 type OCPP16CancelReservationResponse
,
29 OCPP16ChargePointStatus
,
30 type OCPP16DataTransferResponse
,
31 type OCPP16DiagnosticsStatusNotificationResponse
,
32 type OCPP16FirmwareStatusNotificationResponse
,
33 type OCPP16GetCompositeScheduleResponse
,
34 type OCPP16HeartbeatResponse
,
35 OCPP16IncomingRequestCommand
,
36 type OCPP16MeterValuesRequest
,
37 type OCPP16MeterValuesResponse
,
39 type OCPP16ReserveNowResponse
,
40 OCPP16StandardParametersKey
,
41 type OCPP16StartTransactionRequest
,
42 type OCPP16StartTransactionResponse
,
43 type OCPP16StatusNotificationResponse
,
44 type OCPP16StopTransactionRequest
,
45 type OCPP16StopTransactionResponse
,
46 type OCPP16TriggerMessageResponse
,
47 type OCPP16UpdateFirmwareResponse
,
49 RegistrationStatusEnumType
,
51 type SetChargingProfileResponse
,
52 type UnlockConnectorResponse
,
53 } from
'../../../types';
54 import { Constants
, Utils
, buildUpdatedMessage
, logger
} from
'../../../utils';
55 import { OCPPResponseService
} from
'../OCPPResponseService';
57 const moduleName
= 'OCPP16ResponseService';
59 export class OCPP16ResponseService
extends OCPPResponseService
{
60 public jsonIncomingRequestResponseSchemas
: Map
<
61 OCPP16IncomingRequestCommand
,
62 JSONSchemaType
<JsonObject
>
65 private responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>;
66 private jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
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
>([
74 [OCPP16RequestCommand
.BOOT_NOTIFICATION
, this.handleResponseBootNotification
.bind(this)],
75 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this)],
76 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this)],
77 [OCPP16RequestCommand
.START_TRANSACTION
, this.handleResponseStartTransaction
.bind(this)],
78 [OCPP16RequestCommand
.STOP_TRANSACTION
, this.handleResponseStopTransaction
.bind(this)],
79 [OCPP16RequestCommand
.STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
80 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this)],
81 [OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
82 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this)],
83 [OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
85 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
87 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
88 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
89 'assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
95 OCPP16RequestCommand
.HEARTBEAT
,
96 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
97 'assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
103 OCPP16RequestCommand
.AUTHORIZE
,
104 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
105 'assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
111 OCPP16RequestCommand
.START_TRANSACTION
,
112 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
113 'assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
119 OCPP16RequestCommand
.STOP_TRANSACTION
,
120 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
121 'assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
127 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
128 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
129 'assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
135 OCPP16RequestCommand
.METER_VALUES
,
136 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
137 'assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
143 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
144 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
145 'assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
151 OCPP16RequestCommand
.DATA_TRANSFER
,
152 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
153 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
159 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
160 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
161 'assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
167 OCPP16RequestCommand
.RESERVE_NOW
,
168 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ReserveNowResponse
>(
169 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json',
175 OCPP16RequestCommand
.CANCEL_RESERVATION
,
176 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16CancelReservationResponse
>(
177 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json',
183 this.jsonIncomingRequestResponseSchemas
= new Map([
185 OCPP16IncomingRequestCommand
.RESET
,
186 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
187 'assets/json-schemas/ocpp/1.6/ResetResponse.json',
193 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
194 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
195 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
201 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
202 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
203 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
209 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
210 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
211 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
217 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
218 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
219 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
225 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
226 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
227 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
233 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
234 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
235 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
241 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
242 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
243 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
249 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
250 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
251 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
257 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
258 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
259 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
265 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
266 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
267 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
273 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
274 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
275 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
281 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
282 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
283 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
289 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
290 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
291 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
297 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
298 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
299 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
305 this.validatePayload
= this.validatePayload
.bind(this) as (
306 chargingStation
: ChargingStation
,
307 commandName
: OCPP16RequestCommand
,
312 public async responseHandler(
313 chargingStation
: ChargingStation
,
314 commandName
: OCPP16RequestCommand
,
316 requestPayload
: JsonType
319 chargingStation
.isRegistered() === true ||
320 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
323 this.responseHandlers
.has(commandName
) === true &&
324 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
327 this.validatePayload(chargingStation
, commandName
, payload
);
328 await this.responseHandlers
.get(commandName
)(chargingStation
, payload
, requestPayload
);
331 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
339 ErrorType
.NOT_IMPLEMENTED
,
340 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
351 ErrorType
.SECURITY_ERROR
,
352 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
356 )} while the charging station is not registered on the central server.`,
363 private validatePayload(
364 chargingStation
: ChargingStation
,
365 commandName
: OCPP16RequestCommand
,
368 if (this.jsonSchemas
.has(commandName
) === true) {
369 return this.validateResponsePayload(
372 this.jsonSchemas
.get(commandName
),
377 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
382 private handleResponseBootNotification(
383 chargingStation
: ChargingStation
,
384 payload
: OCPP16BootNotificationResponse
386 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
387 ChargingStationConfigurationUtils
.addConfigurationKey(
389 OCPP16StandardParametersKey
.HeartbeatInterval
,
390 payload
.interval
.toString(),
392 { overwrite
: true, save
: true }
394 ChargingStationConfigurationUtils
.addConfigurationKey(
396 OCPP16StandardParametersKey
.HeartBeatInterval
,
397 payload
.interval
.toString(),
399 { overwrite
: true, save
: true }
401 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
);
403 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
404 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
406 }' state on the central server`;
407 payload
.status === RegistrationStatusEnumType
.REJECTED
408 ? logger
.warn(logMsg
)
409 : logger
.info(logMsg
);
412 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
418 private handleResponseAuthorize(
419 chargingStation
: ChargingStation
,
420 payload
: OCPP16AuthorizeResponse
,
421 requestPayload
: OCPP16AuthorizeRequest
423 let authorizeConnectorId
: number;
424 if (chargingStation
.hasEvses
) {
425 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
427 for (const [connectorId
, connectorStatus
] of evseStatus
.connectors
) {
428 if (connectorStatus
?.authorizeIdTag
=== requestPayload
.idTag
) {
429 authorizeConnectorId
= connectorId
;
436 for (const connectorId
of chargingStation
.connectors
.keys()) {
439 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
441 authorizeConnectorId
= connectorId
;
446 const authorizeConnectorIdDefined
= !Utils
.isNullOrUndefined(authorizeConnectorId
);
447 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
448 authorizeConnectorIdDefined
&&
449 (chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= true);
451 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${
452 authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}
` : ''
456 if (authorizeConnectorIdDefined
) {
457 chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= false;
458 delete chargingStation
.getConnectorStatus(authorizeConnectorId
)?.authorizeIdTag
;
461 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
462 payload.idTagInfo.status
463 }'${authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}` : ''}`
468 private async handleResponseStartTransaction(
469 chargingStation: ChargingStation,
470 payload: OCPP16StartTransactionResponse,
471 requestPayload: OCPP16StartTransactionRequest
473 const transactionConnectorId = requestPayload.connectorId;
475 transactionConnectorId === 0 ||
476 chargingStation.hasConnector(transactionConnectorId) === false
479 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector id ${transactionConnectorId.toString()}
`
484 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
486 chargingStation.getAuthorizeRemoteTxRequests() === true &&
487 chargingStation.getLocalAuthListEnabled() === true &&
488 chargingStation.hasIdTags() &&
489 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false
492 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{
493 chargingStation
.getConnectorStatus(transactionConnectorId
)?.localAuthorizeIdTag
494 } on connector id ${transactionConnectorId.toString()}
`
496 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
500 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
502 chargingStation.getAuthorizeRemoteTxRequests() === true &&
503 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
504 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false &&
505 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized === false
508 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{
509 chargingStation
.getConnectorStatus(transactionConnectorId
)?.authorizeIdTag
510 } on connector id ${transactionConnectorId.toString()}
`
512 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
516 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized &&
517 chargingStation.getConnectorStatus(transactionConnectorId)?.authorizeIdTag !==
521 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
523 } different from the authorize request one $
{
524 chargingStation
.getConnectorStatus(transactionConnectorId
)?.authorizeIdTag
525 } on connector id ${transactionConnectorId.toString()}
`
527 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
531 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized &&
532 chargingStation.getConnectorStatus(transactionConnectorId)?.localAuthorizeIdTag !==
536 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
538 } different from the local authorized one $
{
539 chargingStation
.getConnectorStatus(transactionConnectorId
)?.localAuthorizeIdTag
540 } on connector id ${transactionConnectorId.toString()}
`
542 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
545 if (chargingStation.getConnectorStatus(transactionConnectorId)?.transactionStarted === true) {
547 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${transactionConnectorId.toString()}
:`,
548 chargingStation.getConnectorStatus(transactionConnectorId)
552 if (chargingStation.hasEvses) {
553 for (const [evseId, evseStatus] of chargingStation.evses) {
554 if (evseStatus.connectors.size > 1) {
555 for (const [connectorId, connectorStatus] of evseStatus.connectors) {
557 transactionConnectorId !== connectorId &&
558 connectorStatus?.transactionStarted === true
561 `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId.toString()}
:`,
564 await this.resetConnectorOnStartTransactionError(
566 transactionConnectorId
575 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
576 OCPP16ChargePointStatus.Available &&
577 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
578 OCPP16ChargePointStatus.Preparing
581 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with status $
{
582 chargingStation
.getConnectorStatus(transactionConnectorId
)?.status
587 if (!Number.isInteger(payload.transactionId)) {
589 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with a non integer transaction id $
{
590 payload
.transactionId
591 }, converting to integer
`
593 payload.transactionId = Utils.convertToInt(payload.transactionId);
596 if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
597 chargingStation.getConnectorStatus(transactionConnectorId).transactionStarted = true;
598 chargingStation.getConnectorStatus(transactionConnectorId).transactionId =
599 payload.transactionId;
600 chargingStation.getConnectorStatus(transactionConnectorId).transactionIdTag =
601 requestPayload.idTag;
602 chargingStation.getConnectorStatus(
603 transactionConnectorId
604 ).transactionEnergyActiveImportRegisterValue = 0;
605 chargingStation.getConnectorStatus(transactionConnectorId).transactionBeginMeterValue =
606 OCPP16ServiceUtils.buildTransactionBeginMeterValue(
608 transactionConnectorId,
609 requestPayload.meterStart
611 chargingStation.getBeginEndMeterValues() &&
612 (await chargingStation.ocppRequestService.requestHandler<
613 OCPP16MeterValuesRequest,
614 OCPP16MeterValuesResponse
615 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
616 connectorId: transactionConnectorId,
617 transactionId: payload.transactionId,
619 chargingStation.getConnectorStatus(transactionConnectorId).transactionBeginMeterValue,
622 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
624 transactionConnectorId,
625 OCPP16ChargePointStatus.Charging
628 `${chargingStation.logPrefix()} Transaction
with id ${payload.transactionId.toString()} STARTED on $
{
629 chargingStation
.stationInfo
.chargingStationId
630 }#${transactionConnectorId.toString()}
for idTag
'${requestPayload.idTag}'`
632 if (chargingStation.stationInfo.powerSharedByConnectors) {
633 ++chargingStation.powerDivider;
635 const configuredMeterValueSampleInterval =
636 ChargingStationConfigurationUtils.getConfigurationKey(
638 OCPP16StandardParametersKey.MeterValueSampleInterval
640 chargingStation.startMeterValues(
641 transactionConnectorId,
642 configuredMeterValueSampleInterval
643 ? Utils.convertToInt(configuredMeterValueSampleInterval.value) * 1000
644 : Constants.DEFAULT_METER_VALUES_INTERVAL
648 `${chargingStation.logPrefix()} Starting transaction
with id ${payload.transactionId.toString()} REJECTED
with status '${
649 payload.idTagInfo?.status
650 }', idTag
'${requestPayload.idTag}'`
652 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
656 private async resetConnectorOnStartTransactionError(
657 chargingStation: ChargingStation,
660 ChargingStationUtils.resetConnectorStatus(chargingStation.getConnectorStatus(connectorId));
661 chargingStation.stopMeterValues(connectorId);
662 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
664 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
666 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
669 OCPP16ChargePointStatus.Available
674 private async handleResponseStopTransaction(
675 chargingStation: ChargingStation,
676 payload: OCPP16StopTransactionResponse,
677 requestPayload: OCPP16StopTransactionRequest
679 const transactionConnectorId = chargingStation.getConnectorIdByTransactionId(
680 requestPayload.transactionId
682 if (Utils.isNullOrUndefined(transactionConnectorId)) {
684 `${chargingStation.logPrefix()} Trying to stop a non existing transaction
with id ${requestPayload.transactionId.toString()}
`
688 chargingStation.getBeginEndMeterValues() === true &&
689 chargingStation.getOcppStrictCompliance() === false &&
690 chargingStation.getOutOfOrderEndMeterValues() === true &&
691 (await chargingStation.ocppRequestService.requestHandler<
692 OCPP16MeterValuesRequest,
693 OCPP16MeterValuesResponse
694 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
695 connectorId: transactionConnectorId,
696 transactionId: requestPayload.transactionId,
698 OCPP16ServiceUtils.buildTransactionEndMeterValue(
700 transactionConnectorId,
701 requestPayload.meterStop
706 chargingStation.isChargingStationAvailable() === false ||
707 chargingStation.isConnectorAvailable(transactionConnectorId) === false
709 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
711 transactionConnectorId,
712 OCPP16ChargePointStatus.Unavailable
715 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
717 transactionConnectorId,
718 OCPP16ChargePointStatus.Available
721 if (chargingStation.stationInfo.powerSharedByConnectors) {
722 chargingStation.powerDivider--;
724 ChargingStationUtils.resetConnectorStatus(
725 chargingStation.getConnectorStatus(transactionConnectorId)
727 chargingStation.stopMeterValues(transactionConnectorId);
728 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
729 const logMsg = `${chargingStation.logPrefix()} Transaction
with id ${requestPayload.transactionId.toString()} STOPPED on $
{
730 chargingStation
.stationInfo
.chargingStationId
731 }#${transactionConnectorId?.toString()}
with status '${
732 payload.idTagInfo?.status ?? 'undefined'
735 Utils.isNullOrUndefined(payload.idTagInfo) ||
736 payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED