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
>([
79 [OCPP16RequestCommand
.BOOT_NOTIFICATION
, this.handleResponseBootNotification
.bind(this)],
80 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this)],
81 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this)],
82 [OCPP16RequestCommand
.START_TRANSACTION
, this.handleResponseStartTransaction
.bind(this)],
83 [OCPP16RequestCommand
.STOP_TRANSACTION
, this.handleResponseStopTransaction
.bind(this)],
84 [OCPP16RequestCommand
.STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
85 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this)],
86 [OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
87 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this)],
88 [OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
90 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
92 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
93 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
94 'assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
100 OCPP16RequestCommand
.HEARTBEAT
,
101 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
102 'assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
108 OCPP16RequestCommand
.AUTHORIZE
,
109 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
110 'assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
116 OCPP16RequestCommand
.START_TRANSACTION
,
117 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
118 'assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
124 OCPP16RequestCommand
.STOP_TRANSACTION
,
125 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
126 'assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
132 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
133 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
134 'assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
140 OCPP16RequestCommand
.METER_VALUES
,
141 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
142 'assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
148 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
149 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
150 'assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
156 OCPP16RequestCommand
.DATA_TRANSFER
,
157 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
158 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
164 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
165 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
166 'assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
172 this.jsonIncomingRequestResponseSchemas
= new Map([
174 OCPP16IncomingRequestCommand
.RESET
,
175 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
176 'assets/json-schemas/ocpp/1.6/ResetResponse.json',
182 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
183 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
184 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
190 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
191 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
192 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
198 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
199 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
200 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
206 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
207 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
208 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
214 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
215 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
216 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
222 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
223 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
224 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
230 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
231 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
232 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
238 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
239 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
240 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
246 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
247 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
248 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
254 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
255 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
256 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
262 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
263 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
264 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
270 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
271 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
272 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
278 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
279 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
280 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
286 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
287 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
288 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
294 OCPP16IncomingRequestCommand
.RESERVE_NOW
,
295 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ReserveNowResponse
>(
296 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json',
302 OCPP16IncomingRequestCommand
.CANCEL_RESERVATION
,
303 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
304 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json',
310 this.validatePayload
= this.validatePayload
.bind(this) as (
311 chargingStation
: ChargingStation
,
312 commandName
: OCPP16RequestCommand
,
317 public async responseHandler(
318 chargingStation
: ChargingStation
,
319 commandName
: OCPP16RequestCommand
,
321 requestPayload
: JsonType
324 chargingStation
.isRegistered() === true ||
325 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
328 this.responseHandlers
.has(commandName
) === true &&
329 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
332 this.validatePayload(chargingStation
, commandName
, payload
);
333 await this.responseHandlers
.get(commandName
)(chargingStation
, payload
, requestPayload
);
336 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
344 ErrorType
.NOT_IMPLEMENTED
,
345 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
356 ErrorType
.SECURITY_ERROR
,
357 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
361 )} while the charging station is not registered on the central server.`,
368 private validatePayload(
369 chargingStation
: ChargingStation
,
370 commandName
: OCPP16RequestCommand
,
373 if (this.jsonSchemas
.has(commandName
) === true) {
374 return this.validateResponsePayload(
377 this.jsonSchemas
.get(commandName
),
382 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
387 private handleResponseBootNotification(
388 chargingStation
: ChargingStation
,
389 payload
: OCPP16BootNotificationResponse
391 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
392 ChargingStationConfigurationUtils
.addConfigurationKey(
394 OCPP16StandardParametersKey
.HeartbeatInterval
,
395 payload
.interval
.toString(),
397 { overwrite
: true, save
: true }
399 ChargingStationConfigurationUtils
.addConfigurationKey(
401 OCPP16StandardParametersKey
.HeartBeatInterval
,
402 payload
.interval
.toString(),
404 { overwrite
: true, save
: true }
406 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
);
408 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
409 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
411 }' state on the central server`;
412 payload
.status === RegistrationStatusEnumType
.REJECTED
413 ? logger
.warn(logMsg
)
414 : logger
.info(logMsg
);
417 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
423 private handleResponseAuthorize(
424 chargingStation
: ChargingStation
,
425 payload
: OCPP16AuthorizeResponse
,
426 requestPayload
: OCPP16AuthorizeRequest
428 let authorizeConnectorId
: number;
429 if (chargingStation
.hasEvses
) {
430 for (const [evseId
, evseStatus
] of chargingStation
.evses
) {
432 for (const [connectorId
, connectorStatus
] of evseStatus
.connectors
) {
433 if (connectorStatus
?.authorizeIdTag
=== requestPayload
.idTag
) {
434 authorizeConnectorId
= connectorId
;
441 for (const connectorId
of chargingStation
.connectors
.keys()) {
444 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
446 authorizeConnectorId
= connectorId
;
451 const authorizeConnectorIdDefined
= !isNullOrUndefined(authorizeConnectorId
);
452 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
453 authorizeConnectorIdDefined
&&
454 (chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= true);
456 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' accepted${
457 authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}
` : ''
461 if (authorizeConnectorIdDefined
) {
462 chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= false;
463 delete chargingStation
.getConnectorStatus(authorizeConnectorId
)?.authorizeIdTag
;
466 `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
467 payload.idTagInfo.status
468 }'${authorizeConnectorIdDefined ? ` on connector id ${authorizeConnectorId}` : ''}`
473 private async handleResponseStartTransaction(
474 chargingStation: ChargingStation,
475 payload: OCPP16StartTransactionResponse,
476 requestPayload: OCPP16StartTransactionRequest
478 const transactionConnectorId = requestPayload.connectorId;
480 transactionConnectorId === 0 ||
481 chargingStation.hasConnector(transactionConnectorId) === false
484 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector id ${transactionConnectorId.toString()}
`
489 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
491 chargingStation.getAuthorizeRemoteTxRequests() === true &&
492 chargingStation.getLocalAuthListEnabled() === true &&
493 chargingStation.hasIdTags() &&
494 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false
497 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{
498 chargingStation
.getConnectorStatus(transactionConnectorId
)?.localAuthorizeIdTag
499 } on connector id ${transactionConnectorId.toString()}
`
501 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
505 chargingStation.getConnectorStatus(transactionConnectorId)?.transactionRemoteStarted ===
507 chargingStation.getAuthorizeRemoteTxRequests() === true &&
508 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
509 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized === false &&
510 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized === false
513 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{
514 chargingStation
.getConnectorStatus(transactionConnectorId
)?.authorizeIdTag
515 } on connector id ${transactionConnectorId.toString()}
`
517 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
521 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagAuthorized &&
522 chargingStation.getConnectorStatus(transactionConnectorId)?.authorizeIdTag !==
526 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
528 } different from the authorize request one $
{
529 chargingStation
.getConnectorStatus(transactionConnectorId
)?.authorizeIdTag
530 } on connector id ${transactionConnectorId.toString()}
`
532 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
536 chargingStation.getConnectorStatus(transactionConnectorId)?.idTagLocalAuthorized &&
537 chargingStation.getConnectorStatus(transactionConnectorId)?.localAuthorizeIdTag !==
541 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
543 } different from the local authorized one $
{
544 chargingStation
.getConnectorStatus(transactionConnectorId
)?.localAuthorizeIdTag
545 } on connector id ${transactionConnectorId.toString()}
`
547 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
550 if (chargingStation.getConnectorStatus(transactionConnectorId)?.transactionStarted === true) {
552 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${transactionConnectorId.toString()}
:`,
553 chargingStation.getConnectorStatus(transactionConnectorId)
557 if (chargingStation.hasEvses) {
558 for (const [evseId, evseStatus] of chargingStation.evses) {
559 if (evseStatus.connectors.size > 1) {
560 for (const [connectorId, connectorStatus] of evseStatus.connectors) {
562 transactionConnectorId !== connectorId &&
563 connectorStatus?.transactionStarted === true
566 `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId.toString()}
:`,
569 await this.resetConnectorOnStartTransactionError(
571 transactionConnectorId
580 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
581 OCPP16ChargePointStatus.Available &&
582 chargingStation.getConnectorStatus(transactionConnectorId)?.status !==
583 OCPP16ChargePointStatus.Preparing
586 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with status $
{
587 chargingStation
.getConnectorStatus(transactionConnectorId
)?.status
592 if (!Number.isInteger(payload.transactionId)) {
594 `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${transactionConnectorId.toString()}
with a non integer transaction id $
{
595 payload
.transactionId
596 }, converting to integer
`
598 payload.transactionId = convertToInt(payload.transactionId);
601 if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
602 chargingStation.getConnectorStatus(transactionConnectorId).transactionStarted = true;
603 chargingStation.getConnectorStatus(transactionConnectorId).transactionId =
604 payload.transactionId;
605 chargingStation.getConnectorStatus(transactionConnectorId).transactionIdTag =
606 requestPayload.idTag;
607 chargingStation.getConnectorStatus(
608 transactionConnectorId
609 ).transactionEnergyActiveImportRegisterValue = 0;
610 chargingStation.getConnectorStatus(transactionConnectorId).transactionBeginMeterValue =
611 OCPP16ServiceUtils.buildTransactionBeginMeterValue(
613 transactionConnectorId,
614 requestPayload.meterStart
616 chargingStation.getBeginEndMeterValues() &&
617 (await chargingStation.ocppRequestService.requestHandler<
618 OCPP16MeterValuesRequest,
619 OCPP16MeterValuesResponse
620 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
621 connectorId: transactionConnectorId,
622 transactionId: payload.transactionId,
624 chargingStation.getConnectorStatus(transactionConnectorId).transactionBeginMeterValue,
627 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
629 transactionConnectorId,
630 OCPP16ChargePointStatus.Charging
633 `${chargingStation.logPrefix()} Transaction
with id ${payload.transactionId.toString()} STARTED on $
{
634 chargingStation
.stationInfo
.chargingStationId
635 }#${transactionConnectorId.toString()}
for idTag
'${requestPayload.idTag}'`
637 if (chargingStation.stationInfo.powerSharedByConnectors) {
638 ++chargingStation.powerDivider;
640 const configuredMeterValueSampleInterval =
641 ChargingStationConfigurationUtils.getConfigurationKey(
643 OCPP16StandardParametersKey.MeterValueSampleInterval
645 chargingStation.startMeterValues(
646 transactionConnectorId,
647 configuredMeterValueSampleInterval
648 ? convertToInt(configuredMeterValueSampleInterval.value) * 1000
649 : Constants.DEFAULT_METER_VALUES_INTERVAL
653 `${chargingStation.logPrefix()} Starting transaction
with id ${payload.transactionId.toString()} REJECTED
with status '${
654 payload.idTagInfo?.status
655 }', idTag
'${requestPayload.idTag}'`
657 await this.resetConnectorOnStartTransactionError(chargingStation, transactionConnectorId);
661 private async resetConnectorOnStartTransactionError(
662 chargingStation: ChargingStation,
665 ChargingStationUtils.resetConnectorStatus(chargingStation.getConnectorStatus(connectorId));
666 chargingStation.stopMeterValues(connectorId);
667 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
669 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
671 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
674 OCPP16ChargePointStatus.Available
679 private async handleResponseStopTransaction(
680 chargingStation: ChargingStation,
681 payload: OCPP16StopTransactionResponse,
682 requestPayload: OCPP16StopTransactionRequest
684 const transactionConnectorId = chargingStation.getConnectorIdByTransactionId(
685 requestPayload.transactionId
687 if (isNullOrUndefined(transactionConnectorId)) {
689 `${chargingStation.logPrefix()} Trying to stop a non existing transaction
with id ${requestPayload.transactionId.toString()}
`
693 chargingStation.getBeginEndMeterValues() === true &&
694 chargingStation.getOcppStrictCompliance() === false &&
695 chargingStation.getOutOfOrderEndMeterValues() === true &&
696 (await chargingStation.ocppRequestService.requestHandler<
697 OCPP16MeterValuesRequest,
698 OCPP16MeterValuesResponse
699 >(chargingStation, OCPP16RequestCommand.METER_VALUES, {
700 connectorId: transactionConnectorId,
701 transactionId: requestPayload.transactionId,
703 OCPP16ServiceUtils.buildTransactionEndMeterValue(
705 transactionConnectorId,
706 requestPayload.meterStop
711 chargingStation.isChargingStationAvailable() === false ||
712 chargingStation.isConnectorAvailable(transactionConnectorId) === false
714 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
716 transactionConnectorId,
717 OCPP16ChargePointStatus.Unavailable
720 await OCPP16ServiceUtils.sendAndSetConnectorStatus(
722 transactionConnectorId,
723 OCPP16ChargePointStatus.Available
726 if (chargingStation.stationInfo.powerSharedByConnectors) {
727 chargingStation.powerDivider--;
729 ChargingStationUtils.resetConnectorStatus(
730 chargingStation.getConnectorStatus(transactionConnectorId)
732 chargingStation.stopMeterValues(transactionConnectorId);
733 parentPort?.postMessage(buildUpdatedMessage(chargingStation));
734 const logMsg = `${chargingStation.logPrefix()} Transaction
with id ${requestPayload.transactionId.toString()} STOPPED on $
{
735 chargingStation
.stationInfo
.chargingStationId
736 }#${transactionConnectorId?.toString()}
with status '${
737 payload.idTagInfo?.status ?? 'undefined'
740 isNullOrUndefined(payload.idTagInfo) ||
741 payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED