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';
59 } from
'../../../utils';
60 import { OCPPResponseService
} from
'../OCPPResponseService';
62 const moduleName
= 'OCPP16ResponseService';
64 export class OCPP16ResponseService
extends OCPPResponseService
{
65 public jsonIncomingRequestResponseSchemas
: Map
<
66 OCPP16IncomingRequestCommand
,
67 JSONSchemaType
<JsonObject
>
70 private responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>;
71 private jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
73 public constructor() {
74 // if (new.target?.name === moduleName) {
75 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
77 super(OCPPVersion
.VERSION_16
);
78 this.responseHandlers
= new Map
<OCPP16RequestCommand
, ResponseHandler
>([
80 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
81 this.handleResponseBootNotification
.bind(this) as ResponseHandler
,
83 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
84 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this) as ResponseHandler
],
86 OCPP16RequestCommand
.START_TRANSACTION
,
87 this.handleResponseStartTransaction
.bind(this) as ResponseHandler
,
90 OCPP16RequestCommand
.STOP_TRANSACTION
,
91 this.handleResponseStopTransaction
.bind(this) as ResponseHandler
,
94 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
95 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
97 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
99 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
100 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
102 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
104 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
105 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
108 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
110 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
111 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
112 'assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
118 OCPP16RequestCommand
.HEARTBEAT
,
119 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
120 'assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
126 OCPP16RequestCommand
.AUTHORIZE
,
127 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
128 'assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
134 OCPP16RequestCommand
.START_TRANSACTION
,
135 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
136 'assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
142 OCPP16RequestCommand
.STOP_TRANSACTION
,
143 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
144 'assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
150 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
151 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
152 'assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
158 OCPP16RequestCommand
.METER_VALUES
,
159 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
160 'assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
166 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
167 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
168 'assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
174 OCPP16RequestCommand
.DATA_TRANSFER
,
175 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
176 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
182 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
183 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
184 'assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
190 this.jsonIncomingRequestResponseSchemas
= new Map([
192 OCPP16IncomingRequestCommand
.RESET
,
193 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
194 'assets/json-schemas/ocpp/1.6/ResetResponse.json',
200 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
201 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
202 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
208 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
209 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
210 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
216 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
217 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
218 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
224 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
225 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
226 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
232 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
233 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
234 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
240 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
241 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
242 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
248 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
249 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
250 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
256 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
257 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
258 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
264 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
265 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
266 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
272 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
273 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
274 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
280 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
281 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
282 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
288 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
289 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
290 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
296 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
297 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
298 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
304 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
305 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
306 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
312 OCPP16IncomingRequestCommand
.RESERVE_NOW
,
313 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ReserveNowResponse
>(
314 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json',
320 OCPP16IncomingRequestCommand
.CANCEL_RESERVATION
,
321 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
322 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json',
328 this.validatePayload
= this.validatePayload
.bind(this) as (
329 chargingStation
: ChargingStation
,
330 commandName
: OCPP16RequestCommand
,
335 public async responseHandler
<ReqType
extends JsonType
, ResType
extends JsonType
>(
336 chargingStation
: ChargingStation
,
337 commandName
: OCPP16RequestCommand
,
339 requestPayload
: ReqType
,
342 chargingStation
.isRegistered() === true ||
343 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
346 this.responseHandlers
.has(commandName
) === true &&
347 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
350 this.validatePayload(chargingStation
, commandName
, payload
);
351 await this.responseHandlers
.get(commandName
)!(chargingStation
, payload
, requestPayload
);
354 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
362 ErrorType
.NOT_IMPLEMENTED
,
363 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
374 ErrorType
.SECURITY_ERROR
,
375 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
379 )} while the charging station is not registered on the central server.`,
386 private validatePayload(
387 chargingStation
: ChargingStation
,
388 commandName
: OCPP16RequestCommand
,
391 if (this.jsonSchemas
.has(commandName
) === true) {
392 return this.validateResponsePayload(
395 this.jsonSchemas
.get(commandName
)!,
400 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`,
405 private handleResponseBootNotification(
406 chargingStation
: ChargingStation
,
407 payload
: OCPP16BootNotificationResponse
,
409 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
410 ChargingStationConfigurationUtils
.addConfigurationKey(
412 OCPP16StandardParametersKey
.HeartbeatInterval
,
413 payload
.interval
.toString(),
415 { overwrite
: true, save
: true },
417 ChargingStationConfigurationUtils
.addConfigurationKey(
419 OCPP16StandardParametersKey
.HeartBeatInterval
,
420 payload
.interval
.toString(),
422 { overwrite
: true, save
: true },
424 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
);
426 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
427 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
429 }' state on the central server`;
430 payload
.status === RegistrationStatusEnumType
.REJECTED
431 ? logger
.warn(logMsg
)
432 : logger
.info(logMsg
);
435 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
441 private handleResponseAuthorize(
442 chargingStation
: ChargingStation
,
443 payload
: OCPP16AuthorizeResponse
,
444 requestPayload
: OCPP16AuthorizeRequest
,
446 let authorizeConnectorId
: number | undefined;
447 if (chargingStation
.hasEvses
) {
448 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
450 for (const [connectorId
, connectorStatus
] of evseStatus
.connectors
) {
451 if (connectorStatus
?.authorizeIdTag
=== requestPayload
.idTag
) {
452 authorizeConnectorId
= connectorId
;
459 for (const connectorId
of chargingStation
.connectors
.keys()) {
462 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
464 authorizeConnectorId
= connectorId
;
469 const authorizeConnectorIdDefined
= !isNullOrUndefined(authorizeConnectorId
);
470 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
471 authorizeConnectorIdDefined
&&
472 (chargingStation
.getConnectorStatus(authorizeConnectorId
!)!.idTagAuthorized
= true);
474 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${
475 authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}
` : ''
479 if (authorizeConnectorIdDefined
) {
480 chargingStation
.getConnectorStatus(authorizeConnectorId
!)!.idTagAuthorized
= false;
481 delete chargingStation
.getConnectorStatus(authorizeConnectorId
!)?.authorizeIdTag
;
484 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
485 payload.idTagInfo.status
486 }'${authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}` : ''}`,
491 private async handleResponseStartTransaction(
492 chargingStation: ChargingStation,
493 payload: OCPP16StartTransactionResponse,
494 requestPayload: OCPP16StartTransactionRequest,
496 const transactionConnectorId = requestPayload.connectorId;
498 transactionConnectorId === 0 ||
499 chargingStation.hasConnector(transactionConnectorId) === false
502 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector id ${transactionConnectorId.toString()}
`,
507 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
509 chargingStation.getAuthorizeRemoteTxRequests() === true &&
510 chargingStation.getLocalAuthListEnabled() === true &&
511 chargingStation.hasIdTags() &&
512 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false
515 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{chargingStation
.getConnectorStatus(
516 transactionConnectorId
,
517 )?.localAuthorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
519 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
523 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
525 chargingStation.getAuthorizeRemoteTxRequests() === true &&
526 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
527 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false &&
528 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized === false
531 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{chargingStation
.getConnectorStatus(
532 transactionConnectorId
,
533 )?.authorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
535 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
539 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized &&
540 chargingStation.getConnectorStatus(transactionConnectorId)?.authorizeIdTag !==
544 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
546 } different from the authorize request one $
{chargingStation
.getConnectorStatus(
547 transactionConnectorId
,
548 )?.authorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
550 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
554 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized &&
555 chargingStation.getConnectorStatus(transactionConnectorId)?.localAuthorizeIdTag !==
559 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
561 } different from the local authorized one $
{chargingStation
.getConnectorStatus(
562 transactionConnectorId
,
563 )?.localAuthorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
565 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
568 if (chargingStation.getConnectorStatus(transactionConnectorId)?.transactionStarted === true) {
570 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${transactionConnectorId.toString()}
:`,
571 chargingStation.getConnectorStatus(transactionConnectorId),
575 if (chargingStation.hasEvses) {
576 for (const [evseId, evseStatus] of chargingStation.evses) {
577 if (evseStatus.connectors.size > 1) {
578 for (const [connectorId, connectorStatus] of evseStatus.connectors) {
580 transactionConnectorId !== connectorId &&
581 connectorStatus?.transactionStarted === true
584 `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId.toString()}
:`,
587 await this.resetConnectorOnStartTransactionError(
589 transactionConnectorId,
598 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
599 OCPP16ChargePointStatus.Available &&
600 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
601 OCPP16ChargePointStatus.Preparing
604 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with status $
{chargingStation
.getConnectorStatus(
605 transactionConnectorId
,
610 if (!Number.isInteger(payload.transactionId)) {
612 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with a non integer transaction id $
{
613 payload
.transactionId
614 }, converting to integer
`,
616 payload.transactionId = convertToInt(payload.transactionId);
619 if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
620 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionStarted = true;
621 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionId =
622 payload.transactionId;
623 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionIdTag =
624 requestPayload.idTag;
625 chargingStation.getConnectorStatus(
626 transactionConnectorId,
627 )!.transactionEnergyActiveImportRegisterValue = 0;
628 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionBeginMeterValue =
629 OCPP16ServiceUtils.buildTransactionBeginMeterValue(
631 transactionConnectorId,
632 requestPayload.meterStart,
634 chargingStation.getBeginEndMeterValues() &&
635 (await chargingStation.ocppRequestService.requestHandler<
636 OCPP16MeterValuesRequest,
637 OCPP16MeterValuesResponse
638 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
639 connectorId: transactionConnectorId,
640 transactionId: payload.transactionId,
642 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionBeginMeterValue,
644 } as OCPP16MeterValuesRequest));
645 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
647 transactionConnectorId,
648 OCPP16ChargePointStatus.Charging,
651 `${chargingStation.logPrefix()} Transaction
with id ${payload.transactionId.toString()} STARTED on $
{
652 chargingStation
.stationInfo
.chargingStationId
653 }#${transactionConnectorId.toString()}
for idTag
'${requestPayload.idTag}'`,
655 if (chargingStation.stationInfo.powerSharedByConnectors) {
656 ++chargingStation.powerDivider;
658 const configuredMeterValueSampleInterval =
659 ChargingStationConfigurationUtils.getConfigurationKey(
661 OCPP16StandardParametersKey.MeterValueSampleInterval,
663 chargingStation.startMeterValues(
664 transactionConnectorId,
665 configuredMeterValueSampleInterval
666 ? convertToInt(configuredMeterValueSampleInterval.value) * 1000
667 : Constants.DEFAULT_METER_VALUES_INTERVAL,
671 `${chargingStation.logPrefix()} Starting transaction
with id ${payload.transactionId.toString()} REJECTED
with status '${payload
672 .idTagInfo?.status}', idTag
'${requestPayload.idTag}'`,
674 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
678 private async resetConnectorOnStartTransactionError(
679 chargingStation: ChargingStation,
682 resetConnectorStatus(chargingStation.getConnectorStatus(connectorId)!);
683 chargingStation.stopMeterValues(connectorId);
684 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
686 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
688 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
691 OCPP16ChargePointStatus.Available,
696 private async handleResponseStopTransaction(
697 chargingStation: ChargingStation,
698 payload: OCPP16StopTransactionResponse,
699 requestPayload: OCPP16StopTransactionRequest,
701 const transactionConnectorId = chargingStation.getConnectorIdByTransactionId(
702 requestPayload.transactionId,
704 if (isNullOrUndefined(transactionConnectorId)) {
706 `${chargingStation.logPrefix()} Trying to stop a non existing transaction
with id ${requestPayload.transactionId.toString()}
`,
710 chargingStation.getBeginEndMeterValues() === true &&
711 chargingStation.getOcppStrictCompliance() === false &&
712 chargingStation.getOutOfOrderEndMeterValues() === true &&
713 (await chargingStation.ocppRequestService.requestHandler<
714 OCPP16MeterValuesRequest,
715 OCPP16MeterValuesResponse
716 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
717 connectorId: transactionConnectorId,
718 transactionId: requestPayload.transactionId,
720 OCPP16ServiceUtils.buildTransactionEndMeterValue(
722 transactionConnectorId!,
723 requestPayload.meterStop,
728 chargingStation.isChargingStationAvailable() === false ||
729 chargingStation.isConnectorAvailable(transactionConnectorId!) === false
731 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
733 transactionConnectorId!,
734 OCPP16ChargePointStatus.Unavailable,
737 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
739 transactionConnectorId!,
740 OCPP16ChargePointStatus.Available,
743 if (chargingStation.stationInfo.powerSharedByConnectors) {
744 chargingStation.powerDivider--;
746 resetConnectorStatus(chargingStation.getConnectorStatus(transactionConnectorId!)!);
747 chargingStation.stopMeterValues(transactionConnectorId!);
748 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
749 const logMsg = `${chargingStation.logPrefix()} Transaction
with id ${requestPayload.transactionId.toString()} STOPPED on $
{
750 chargingStation
.stationInfo
.chargingStationId
751 }#${transactionConnectorId?.toString()}
with status '${
752 payload.idTagInfo?.status ?? 'undefined'
755 isNullOrUndefined(payload.idTagInfo) ||
756 payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED