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';
13 } from
'../../../charging-station';
14 import { OCPPError
} from
'../../../exception';
16 type ChangeAvailabilityResponse
,
17 type ChangeConfigurationResponse
,
18 type ClearChargingProfileResponse
,
21 type GetConfigurationResponse
,
22 type GetDiagnosticsResponse
,
25 OCPP16AuthorizationStatus
,
26 type OCPP16AuthorizeRequest
,
27 type OCPP16AuthorizeResponse
,
28 type OCPP16BootNotificationResponse
,
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';
60 } from
'../../../utils';
61 import { OCPPResponseService
} from
'../OCPPResponseService';
63 const moduleName
= 'OCPP16ResponseService';
65 export class OCPP16ResponseService
extends OCPPResponseService
{
66 public jsonIncomingRequestResponseSchemas
: Map
<
67 OCPP16IncomingRequestCommand
,
68 JSONSchemaType
<JsonObject
>
71 private responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>;
72 private jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
74 public constructor() {
75 // if (new.target?.name === moduleName) {
76 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
78 super(OCPPVersion
.VERSION_16
);
79 this.responseHandlers
= new Map
<OCPP16RequestCommand
, ResponseHandler
>([
81 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
82 this.handleResponseBootNotification
.bind(this) as ResponseHandler
,
84 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
85 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this) as ResponseHandler
],
87 OCPP16RequestCommand
.START_TRANSACTION
,
88 this.handleResponseStartTransaction
.bind(this) as ResponseHandler
,
91 OCPP16RequestCommand
.STOP_TRANSACTION
,
92 this.handleResponseStopTransaction
.bind(this) as ResponseHandler
,
95 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
96 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
98 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
100 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
101 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
103 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this) as ResponseHandler
],
105 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
106 this.emptyResponseHandler
.bind(this) as ResponseHandler
,
109 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
111 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
112 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
113 'assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
119 OCPP16RequestCommand
.HEARTBEAT
,
120 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
121 'assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
127 OCPP16RequestCommand
.AUTHORIZE
,
128 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
129 'assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
135 OCPP16RequestCommand
.START_TRANSACTION
,
136 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
137 'assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
143 OCPP16RequestCommand
.STOP_TRANSACTION
,
144 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
145 'assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
151 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
152 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
153 'assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
159 OCPP16RequestCommand
.METER_VALUES
,
160 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
161 'assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
167 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
168 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
169 'assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
175 OCPP16RequestCommand
.DATA_TRANSFER
,
176 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
177 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
183 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
184 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
185 'assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
191 this.jsonIncomingRequestResponseSchemas
= new Map([
193 OCPP16IncomingRequestCommand
.RESET
,
194 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
195 'assets/json-schemas/ocpp/1.6/ResetResponse.json',
201 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
202 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
203 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
209 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
210 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
211 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
217 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
218 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
219 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
225 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
226 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
227 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
233 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
234 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
235 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
241 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
242 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
243 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
249 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
250 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
251 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
257 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
258 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
259 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
265 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
266 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
267 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
273 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
274 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
275 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
281 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
282 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
283 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
289 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
290 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
291 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
297 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
298 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
299 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
305 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
306 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
307 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
313 OCPP16IncomingRequestCommand
.RESERVE_NOW
,
314 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ReserveNowResponse
>(
315 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json',
321 OCPP16IncomingRequestCommand
.CANCEL_RESERVATION
,
322 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
323 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json',
329 this.validatePayload
= this.validatePayload
.bind(this) as (
330 chargingStation
: ChargingStation
,
331 commandName
: OCPP16RequestCommand
,
336 public async responseHandler
<ReqType
extends JsonType
, ResType
extends JsonType
>(
337 chargingStation
: ChargingStation
,
338 commandName
: OCPP16RequestCommand
,
340 requestPayload
: ReqType
,
343 chargingStation
.isRegistered() === true ||
344 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
347 this.responseHandlers
.has(commandName
) === true &&
348 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
351 this.validatePayload(chargingStation
, commandName
, payload
);
352 await this.responseHandlers
.get(commandName
)!(chargingStation
, payload
, requestPayload
);
355 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
363 ErrorType
.NOT_IMPLEMENTED
,
364 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
375 ErrorType
.SECURITY_ERROR
,
376 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
380 )} while the charging station is not registered on the central server.`,
387 private validatePayload(
388 chargingStation
: ChargingStation
,
389 commandName
: OCPP16RequestCommand
,
392 if (this.jsonSchemas
.has(commandName
) === true) {
393 return this.validateResponsePayload(
396 this.jsonSchemas
.get(commandName
)!,
401 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`,
406 private handleResponseBootNotification(
407 chargingStation
: ChargingStation
,
408 payload
: OCPP16BootNotificationResponse
,
410 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
413 OCPP16StandardParametersKey
.HeartbeatInterval
,
414 payload
.interval
.toString(),
416 { overwrite
: true, save
: true },
420 OCPP16StandardParametersKey
.HeartBeatInterval
,
421 payload
.interval
.toString(),
423 { overwrite
: true, save
: true },
425 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
);
427 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
428 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
430 }' state on the central server`;
431 payload
.status === RegistrationStatusEnumType
.REJECTED
432 ? logger
.warn(logMsg
)
433 : logger
.info(logMsg
);
436 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
442 private handleResponseAuthorize(
443 chargingStation
: ChargingStation
,
444 payload
: OCPP16AuthorizeResponse
,
445 requestPayload
: OCPP16AuthorizeRequest
,
447 let authorizeConnectorId
: number | undefined;
448 if (chargingStation
.hasEvses
) {
449 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
451 for (const [connectorId
, connectorStatus
] of evseStatus
.connectors
) {
452 if (connectorStatus
?.authorizeIdTag
=== requestPayload
.idTag
) {
453 authorizeConnectorId
= connectorId
;
460 for (const connectorId
of chargingStation
.connectors
.keys()) {
463 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
465 authorizeConnectorId
= connectorId
;
470 const authorizeConnectorIdDefined
= !isNullOrUndefined(authorizeConnectorId
);
471 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
472 authorizeConnectorIdDefined
&&
473 (chargingStation
.getConnectorStatus(authorizeConnectorId
!)!.idTagAuthorized
= true);
475 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${
476 authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}
` : ''
480 if (authorizeConnectorIdDefined
) {
481 chargingStation
.getConnectorStatus(authorizeConnectorId
!)!.idTagAuthorized
= false;
482 delete chargingStation
.getConnectorStatus(authorizeConnectorId
!)?.authorizeIdTag
;
485 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
486 payload.idTagInfo.status
487 }'${authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}` : ''}`,
492 private async handleResponseStartTransaction(
493 chargingStation: ChargingStation,
494 payload: OCPP16StartTransactionResponse,
495 requestPayload: OCPP16StartTransactionRequest,
497 const transactionConnectorId = requestPayload.connectorId;
499 transactionConnectorId === 0 ||
500 chargingStation.hasConnector(transactionConnectorId) === false
503 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector id ${transactionConnectorId.toString()}
`,
508 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
510 chargingStation.getAuthorizeRemoteTxRequests() === true &&
511 chargingStation.getLocalAuthListEnabled() === true &&
512 chargingStation.hasIdTags() &&
513 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false
516 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{chargingStation
.getConnectorStatus(
517 transactionConnectorId
,
518 )?.localAuthorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
520 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
524 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
526 chargingStation.getAuthorizeRemoteTxRequests() === true &&
527 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
528 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false &&
529 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized === false
532 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{chargingStation
.getConnectorStatus(
533 transactionConnectorId
,
534 )?.authorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
536 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
540 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized &&
541 chargingStation.getConnectorStatus(transactionConnectorId)?.authorizeIdTag !==
545 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
547 } different from the authorize request one $
{chargingStation
.getConnectorStatus(
548 transactionConnectorId
,
549 )?.authorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
551 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
555 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized &&
556 chargingStation.getConnectorStatus(transactionConnectorId)?.localAuthorizeIdTag !==
560 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
562 } different from the local authorized one $
{chargingStation
.getConnectorStatus(
563 transactionConnectorId
,
564 )?.localAuthorizeIdTag
} on connector id ${transactionConnectorId.toString()}
`,
566 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
569 if (chargingStation.getConnectorStatus(transactionConnectorId)?.transactionStarted === true) {
571 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${transactionConnectorId.toString()}
:`,
572 chargingStation.getConnectorStatus(transactionConnectorId),
576 if (chargingStation.hasEvses) {
577 for (const [evseId, evseStatus] of chargingStation.evses) {
578 if (evseStatus.connectors.size > 1) {
579 for (const [connectorId, connectorStatus] of evseStatus.connectors) {
581 transactionConnectorId !== connectorId &&
582 connectorStatus?.transactionStarted === true
585 `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId.toString()}
:`,
588 await this.resetConnectorOnStartTransactionError(
590 transactionConnectorId,
599 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
600 OCPP16ChargePointStatus.Available &&
601 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
602 OCPP16ChargePointStatus.Preparing
605 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with status $
{chargingStation
.getConnectorStatus(
606 transactionConnectorId
,
611 if (!Number.isInteger(payload.transactionId)) {
613 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with a non integer transaction id $
{
614 payload
.transactionId
615 }, converting to integer
`,
617 payload.transactionId = convertToInt(payload.transactionId);
620 if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
621 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionStarted = true;
622 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionStart =
623 requestPayload.timestamp;
624 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionId =
625 payload.transactionId;
626 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionIdTag =
627 requestPayload.idTag;
628 chargingStation.getConnectorStatus(
629 transactionConnectorId,
630 )!.transactionEnergyActiveImportRegisterValue = 0;
631 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionBeginMeterValue =
632 OCPP16ServiceUtils.buildTransactionBeginMeterValue(
634 transactionConnectorId,
635 requestPayload.meterStart,
637 chargingStation.getBeginEndMeterValues() &&
638 (await chargingStation.ocppRequestService.requestHandler<
639 OCPP16MeterValuesRequest,
640 OCPP16MeterValuesResponse
641 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
642 connectorId: transactionConnectorId,
643 transactionId: payload.transactionId,
645 chargingStation.getConnectorStatus(transactionConnectorId)!.transactionBeginMeterValue,
647 } as OCPP16MeterValuesRequest));
648 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
650 transactionConnectorId,
651 OCPP16ChargePointStatus.Charging,
654 `${chargingStation.logPrefix()} Transaction
with id ${payload.transactionId.toString()} STARTED on $
{
655 chargingStation
.stationInfo
.chargingStationId
656 }#${transactionConnectorId.toString()}
for idTag
'${requestPayload.idTag}'`,
658 if (chargingStation.stationInfo.powerSharedByConnectors) {
659 ++chargingStation.powerDivider;
661 const configuredMeterValueSampleInterval = getConfigurationKey(
663 OCPP16StandardParametersKey.MeterValueSampleInterval,
665 chargingStation.startMeterValues(
666 transactionConnectorId,
667 configuredMeterValueSampleInterval
668 ? convertToInt(configuredMeterValueSampleInterval.value) * 1000
669 : Constants.DEFAULT_METER_VALUES_INTERVAL,
673 `${chargingStation.logPrefix()} Starting transaction
with id ${payload.transactionId.toString()} REJECTED
with status '${payload
674 .idTagInfo?.status}', idTag
'${requestPayload.idTag}'`,
676 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
680 private async resetConnectorOnStartTransactionError(
681 chargingStation: ChargingStation,
684 resetConnectorStatus(chargingStation.getConnectorStatus(connectorId)!);
685 chargingStation.stopMeterValues(connectorId);
686 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
688 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
690 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
693 OCPP16ChargePointStatus.Available,
698 private async handleResponseStopTransaction(
699 chargingStation: ChargingStation,
700 payload: OCPP16StopTransactionResponse,
701 requestPayload: OCPP16StopTransactionRequest,
703 const transactionConnectorId = chargingStation.getConnectorIdByTransactionId(
704 requestPayload.transactionId,
706 if (isNullOrUndefined(transactionConnectorId)) {
708 `${chargingStation.logPrefix()} Trying to stop a non existing transaction
with id ${requestPayload.transactionId.toString()}
`,
712 chargingStation.getBeginEndMeterValues() === true &&
713 chargingStation.getOcppStrictCompliance() === false &&
714 chargingStation.getOutOfOrderEndMeterValues() === true &&
715 (await chargingStation.ocppRequestService.requestHandler<
716 OCPP16MeterValuesRequest,
717 OCPP16MeterValuesResponse
718 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
719 connectorId: transactionConnectorId,
720 transactionId: requestPayload.transactionId,
722 OCPP16ServiceUtils.buildTransactionEndMeterValue(
724 transactionConnectorId!,
725 requestPayload.meterStop,
730 chargingStation.isChargingStationAvailable() === false ||
731 chargingStation.isConnectorAvailable(transactionConnectorId!) === false
733 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
735 transactionConnectorId!,
736 OCPP16ChargePointStatus.Unavailable,
739 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
741 transactionConnectorId!,
742 OCPP16ChargePointStatus.Available,
745 if (chargingStation.stationInfo.powerSharedByConnectors) {
746 chargingStation.powerDivider--;
748 resetConnectorStatus(chargingStation.getConnectorStatus(transactionConnectorId!)!);
749 chargingStation.stopMeterValues(transactionConnectorId!);
750 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
751 const logMsg = `${chargingStation.logPrefix()} Transaction
with id ${requestPayload.transactionId.toString()} STOPPED on $
{
752 chargingStation
.stationInfo
.chargingStationId
753 }#${transactionConnectorId?.toString()}
with status '${
754 payload.idTagInfo?.status ?? 'undefined'
757 isNullOrUndefined(payload.idTagInfo) ||
758 payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED