1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import { parentPort
} from
'node:worker_threads';
5 import type { JSONSchemaType
} from
'ajv';
6 import { secondsToMilliseconds
} from
'date-fns';
8 import { OCPP16ServiceUtils
} from
'./OCPP16ServiceUtils';
14 } from
'../../../charging-station';
15 import { OCPPError
} from
'../../../exception';
17 type ChangeAvailabilityResponse
,
18 type ChangeConfigurationResponse
,
19 type ClearChargingProfileResponse
,
22 type GetConfigurationResponse
,
23 type GetDiagnosticsResponse
,
26 OCPP16AuthorizationStatus
,
27 type OCPP16AuthorizeRequest
,
28 type OCPP16AuthorizeResponse
,
29 type OCPP16BootNotificationResponse
,
30 OCPP16ChargePointStatus
,
31 type OCPP16DataTransferResponse
,
32 type OCPP16DiagnosticsStatusNotificationResponse
,
33 type OCPP16FirmwareStatusNotificationResponse
,
34 type OCPP16GetCompositeScheduleResponse
,
35 type OCPP16HeartbeatResponse
,
36 OCPP16IncomingRequestCommand
,
37 type OCPP16MeterValuesRequest
,
38 type OCPP16MeterValuesResponse
,
40 type OCPP16ReserveNowResponse
,
41 OCPP16StandardParametersKey
,
42 type OCPP16StartTransactionRequest
,
43 type OCPP16StartTransactionResponse
,
44 type OCPP16StatusNotificationResponse
,
45 type OCPP16StopTransactionRequest
,
46 type OCPP16StopTransactionResponse
,
47 type OCPP16TriggerMessageResponse
,
48 type OCPP16UpdateFirmwareResponse
,
50 RegistrationStatusEnumType
,
52 type SetChargingProfileResponse
,
53 type UnlockConnectorResponse
,
54 } from
'../../../types';
61 } from
'../../../utils';
62 import { OCPPResponseService
} from
'../OCPPResponseService';
64 const moduleName
= 'OCPP16ResponseService';
66 export class OCPP16ResponseService
extends OCPPResponseService
{
67 public jsonIncomingRequestResponseSchemas
: Map
<
68 OCPP16IncomingRequestCommand
,
69 JSONSchemaType
<JsonObject
>
72 private responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>;
73 private jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
75 public constructor() {
76 // if (new.target?.name === moduleName) {
77 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
79 super(OCPPVersion
.VERSION_16
);
80 this.responseHandlers
= new Map
<OCPP16RequestCommand
, ResponseHandler
>([
82 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
83 this.handleResponseBootNotification
.bind(this) as ResponseHandler
,
85 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
86 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this) as ResponseHandler
],
88 OCPP16RequestCommand
.START_TRANSACTION
,
89 this.handleResponseStartTransaction
.bind(this) as ResponseHandler
,
92 OCPP16RequestCommand
.STOP_TRANSACTION
,
93 this.handleResponseStopTransaction
.bind(this) as ResponseHandler
,
96 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
97 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
99 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
101 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
102 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
104 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
106 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
107 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
110 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
112 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
113 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
114 'assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
120 OCPP16RequestCommand
.HEARTBEAT
,
121 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
122 'assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
128 OCPP16RequestCommand
.AUTHORIZE
,
129 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
130 'assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
136 OCPP16RequestCommand
.START_TRANSACTION
,
137 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
138 'assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
144 OCPP16RequestCommand
.STOP_TRANSACTION
,
145 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
146 'assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
152 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
153 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
154 'assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
160 OCPP16RequestCommand
.METER_VALUES
,
161 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
162 'assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
168 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
169 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
170 'assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
176 OCPP16RequestCommand
.DATA_TRANSFER
,
177 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
178 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
184 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
185 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
186 'assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
192 this.jsonIncomingRequestResponseSchemas
= new Map([
194 OCPP16IncomingRequestCommand
.RESET
,
195 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
196 'assets/json-schemas/ocpp/1.6/ResetResponse.json',
202 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
203 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
204 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
210 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
211 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
212 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
218 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
219 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
220 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
226 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
227 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
228 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
234 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
235 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
236 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
242 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
243 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
244 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
250 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
251 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
252 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
258 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
259 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
260 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
266 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
267 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
268 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
274 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
275 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
276 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
282 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
283 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
284 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
290 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
291 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
292 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
298 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
299 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
300 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
306 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
307 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
308 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
314 OCPP16IncomingRequestCommand
.RESERVE_NOW
,
315 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ReserveNowResponse
>(
316 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json',
322 OCPP16IncomingRequestCommand
.CANCEL_RESERVATION
,
323 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
324 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json',
330 this.validatePayload
= this.validatePayload
.bind(this) as (
331 chargingStation
: ChargingStation
,
332 commandName
: OCPP16RequestCommand
,
337 public async responseHandler
<ReqType
extends JsonType
, ResType
extends JsonType
>(
338 chargingStation
: ChargingStation
,
339 commandName
: OCPP16RequestCommand
,
341 requestPayload
: ReqType
,
344 chargingStation
.isRegistered() === true ||
345 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
348 this.responseHandlers
.has(commandName
) === true &&
349 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
352 this.validatePayload(chargingStation
, commandName
, payload
);
353 await this.responseHandlers
.get(commandName
)!(chargingStation
, payload
, requestPayload
);
356 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
364 ErrorType
.NOT_IMPLEMENTED
,
365 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
376 ErrorType
.SECURITY_ERROR
,
377 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
381 )} while the charging station is not registered on the central server.`,
388 private validatePayload(
389 chargingStation
: ChargingStation
,
390 commandName
: OCPP16RequestCommand
,
393 if (this.jsonSchemas
.has(commandName
) === true) {
394 return this.validateResponsePayload(
397 this.jsonSchemas
.get(commandName
)!,
402 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`,
407 private handleResponseBootNotification(
408 chargingStation
: ChargingStation
,
409 payload
: OCPP16BootNotificationResponse
,
411 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
414 OCPP16StandardParametersKey
.HeartbeatInterval
,
415 payload
.interval
.toString(),
417 { overwrite
: true, save
: true },
421 OCPP16StandardParametersKey
.HeartBeatInterval
,
422 payload
.interval
.toString(),
424 { overwrite
: true, save
: true },
426 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
);
428 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
429 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
431 }' state on the central server`;
432 payload
.status === RegistrationStatusEnumType
.REJECTED
433 ? logger
.warn(logMsg
)
434 : logger
.info(logMsg
);
437 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
443 private handleResponseAuthorize(
444 chargingStation
: ChargingStation
,
445 payload
: OCPP16AuthorizeResponse
,
446 requestPayload
: OCPP16AuthorizeRequest
,
448 let authorizeConnectorId
: number | undefined;
449 if (chargingStation
.hasEvses
) {
450 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
452 for (const [connectorId
, connectorStatus
] of evseStatus
.connectors
) {
453 if (connectorStatus
?.authorizeIdTag
=== requestPayload
.idTag
) {
454 authorizeConnectorId
= connectorId
;
461 for (const connectorId
of chargingStation
.connectors
.keys()) {
464 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
466 authorizeConnectorId
= connectorId
;
471 const authorizeConnectorIdDefined
= !isNullOrUndefined(authorizeConnectorId
);
472 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
473 authorizeConnectorIdDefined
&&
474 (chargingStation
.getConnectorStatus(authorizeConnectorId
!)!.idTagAuthorized
= true);
476 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${
477 authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}
` : ''
481 if (authorizeConnectorIdDefined
) {
482 chargingStation
.getConnectorStatus(authorizeConnectorId
!)!.idTagAuthorized
= false;
483 delete chargingStation
.getConnectorStatus(authorizeConnectorId
!)?.authorizeIdTag
;
486 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
487 payload.idTagInfo.status
488 }'${authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}` : ''}`,
493 private async handleResponseStartTransaction(
494 chargingStation: ChargingStation,
495 payload: OCPP16StartTransactionResponse,
496 requestPayload: OCPP16StartTransactionRequest,
498 const transactionConnectorId = requestPayload.connectorId;
500 transactionConnectorId === 0 ||
501 chargingStation.hasConnector(transactionConnectorId) === false
504 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector id ${transactionConnectorId.toString()}
`,
509 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
511 chargingStation.getAuthorizeRemoteTxRequests() === true &&
512 chargingStation.getLocalAuthListEnabled() === true &&
513 chargingStation.hasIdTags() &&
514 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false
517 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{chargingStation
.getConnectorStatus(
518 transactionConnectorId
,
519 )?.localAuthorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
521 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
525 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
527 chargingStation.getAuthorizeRemoteTxRequests() === true &&
528 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
529 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false &&
530 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized === false
533 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{chargingStation
.getConnectorStatus(
534 transactionConnectorId
,
535 )?.authorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
537 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
541 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized &&
542 chargingStation.getConnectorStatus(transactionConnectorId)?.authorizeIdTag !==
546 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
548 } different from the authorize request one $
{chargingStation
.getConnectorStatus(
549 transactionConnectorId
,
550 )?.authorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
552 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
556 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized &&
557 chargingStation.getConnectorStatus(transactionConnectorId)?.localAuthorizeIdTag !==
561 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
563 } different from the local authorized one $
{chargingStation
.getConnectorStatus(
564 transactionConnectorId
,
565 )?.localAuthorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
567 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
570 if (chargingStation.getConnectorStatus(transactionConnectorId)?.transactionStarted === true) {
572 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${transactionConnectorId.toString()}
:`,
573 chargingStation.getConnectorStatus(transactionConnectorId),
577 if (chargingStation.hasEvses) {
578 for (const [evseId, evseStatus] of chargingStation.evses) {
579 if (evseStatus.connectors.size > 1) {
580 for (const [connectorId, connectorStatus] of evseStatus.connectors) {
582 transactionConnectorId !== connectorId &&
583 connectorStatus?.transactionStarted === true
586 `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId.toString()}
:`,
589 await this.resetConnectorOnStartTransactionError(
591 transactionConnectorId,
600 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
601 OCPP16ChargePointStatus.Available &&
602 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
603 OCPP16ChargePointStatus.Preparing
606 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with status $
{chargingStation
.getConnectorStatus(
607 transactionConnectorId
,
612 if (!Number.isInteger(payload.transactionId)) {
614 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with a non integer transaction id $
{
615 payload
.transactionId
616 }, converting to integer
`,
618 payload.transactionId = convertToInt(payload.transactionId);
621 if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
622 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionStarted = true;
623 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionStart =
624 requestPayload.timestamp;
625 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionId =
626 payload.transactionId;
627 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionIdTag =
628 requestPayload.idTag;
629 chargingStation.getConnectorStatus(
630 transactionConnectorId,
631 )!.transactionEnergyActiveImportRegisterValue = 0;
632 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionBeginMeterValue =
633 OCPP16ServiceUtils.buildTransactionBeginMeterValue(
635 transactionConnectorId,
636 requestPayload.meterStart,
638 chargingStation.getBeginEndMeterValues() &&
639 (await chargingStation.ocppRequestService.requestHandler<
640 OCPP16MeterValuesRequest,
641 OCPP16MeterValuesResponse
642 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
643 connectorId: transactionConnectorId,
644 transactionId: payload.transactionId,
646 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionBeginMeterValue,
648 } as OCPP16MeterValuesRequest));
649 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
651 transactionConnectorId,
652 OCPP16ChargePointStatus.Charging,
655 `${chargingStation.logPrefix()} Transaction
with id ${payload.transactionId.toString()} STARTED on $
{
656 chargingStation
.stationInfo
.chargingStationId
657 }#${transactionConnectorId.toString()}
for idTag
'${requestPayload.idTag}'`,
659 if (chargingStation.stationInfo.powerSharedByConnectors) {
660 ++chargingStation.powerDivider;
662 const configuredMeterValueSampleInterval = getConfigurationKey(
664 OCPP16StandardParametersKey.MeterValueSampleInterval,
666 chargingStation.startMeterValues(
667 transactionConnectorId,
668 configuredMeterValueSampleInterval
669 ? secondsToMilliseconds(convertToInt(configuredMeterValueSampleInterval.value))
670 : Constants.DEFAULT_METER_VALUES_INTERVAL,
674 `${chargingStation.logPrefix()} Starting transaction
with id ${payload.transactionId.toString()} REJECTED
with status '${payload
675 .idTagInfo?.status}', idTag
'${requestPayload.idTag}'`,
677 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
681 private async resetConnectorOnStartTransactionError(
682 chargingStation: ChargingStation,
685 resetConnectorStatus(chargingStation.getConnectorStatus(connectorId)!);
686 chargingStation.stopMeterValues(connectorId);
687 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
689 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
691 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
694 OCPP16ChargePointStatus.Available,
699 private async handleResponseStopTransaction(
700 chargingStation: ChargingStation,
701 payload: OCPP16StopTransactionResponse,
702 requestPayload: OCPP16StopTransactionRequest,
704 const transactionConnectorId = chargingStation.getConnectorIdByTransactionId(
705 requestPayload.transactionId,
707 if (isNullOrUndefined(transactionConnectorId)) {
709 `${chargingStation.logPrefix()} Trying to stop a non existing transaction
with id ${requestPayload.transactionId.toString()}
`,
713 chargingStation.getBeginEndMeterValues() === true &&
714 chargingStation.getOcppStrictCompliance() === false &&
715 chargingStation.getOutOfOrderEndMeterValues() === true &&
716 (await chargingStation.ocppRequestService.requestHandler<
717 OCPP16MeterValuesRequest,
718 OCPP16MeterValuesResponse
719 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
720 connectorId: transactionConnectorId,
721 transactionId: requestPayload.transactionId,
723 OCPP16ServiceUtils.buildTransactionEndMeterValue(
725 transactionConnectorId!,
726 requestPayload.meterStop,
731 chargingStation.isChargingStationAvailable() === false ||
732 chargingStation.isConnectorAvailable(transactionConnectorId!) === false
734 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
736 transactionConnectorId!,
737 OCPP16ChargePointStatus.Unavailable,
740 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
742 transactionConnectorId!,
743 OCPP16ChargePointStatus.Available,
746 if (chargingStation.stationInfo.powerSharedByConnectors) {
747 chargingStation.powerDivider--;
749 resetConnectorStatus(chargingStation.getConnectorStatus(transactionConnectorId!)!);
750 chargingStation.stopMeterValues(transactionConnectorId!);
751 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
752 const logMsg = `${chargingStation.logPrefix()} Transaction
with id ${requestPayload.transactionId.toString()} STOPPED on $
{
753 chargingStation
.stationInfo
.chargingStationId
754 }#${transactionConnectorId?.toString()}
with status '${
755 payload.idTagInfo?.status ?? 'undefined'
758 isNullOrUndefined(payload.idTagInfo) ||
759 payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED