1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import type { JSONSchemaType
} from
'ajv';
5 import { type ChargingStation
, ChargingStationConfigurationUtils
} from
'../../../charging-station';
6 import { OCPPError
} from
'../../../exception';
8 type ChangeAvailabilityResponse
,
9 type ChangeConfigurationResponse
,
10 type ClearChargingProfileResponse
,
13 type GetConfigurationResponse
,
14 type GetDiagnosticsResponse
,
17 OCPP16AuthorizationStatus
,
18 type OCPP16AuthorizeRequest
,
19 type OCPP16AuthorizeResponse
,
20 type OCPP16BootNotificationRequest
,
21 type OCPP16BootNotificationResponse
,
22 OCPP16ChargePointErrorCode
,
23 OCPP16ChargePointStatus
,
24 type OCPP16DataTransferResponse
,
25 type OCPP16DiagnosticsStatusNotificationResponse
,
26 type OCPP16FirmwareStatusNotificationResponse
,
27 type OCPP16HeartbeatResponse
,
28 OCPP16IncomingRequestCommand
,
29 type OCPP16MeterValuesRequest
,
30 type OCPP16MeterValuesResponse
,
32 OCPP16StandardParametersKey
,
33 type OCPP16StartTransactionRequest
,
34 type OCPP16StartTransactionResponse
,
35 type OCPP16StatusNotificationRequest
,
36 type OCPP16StatusNotificationResponse
,
37 type OCPP16StopTransactionRequest
,
38 type OCPP16StopTransactionResponse
,
39 type OCPP16TriggerMessageResponse
,
40 type OCPP16UpdateFirmwareResponse
,
42 RegistrationStatusEnumType
,
44 type SetChargingProfileResponse
,
45 type UnlockConnectorResponse
,
46 } from
'../../../types';
47 import { Constants
} from
'../../../utils/Constants';
48 import { logger
} from
'../../../utils/Logger';
49 import { Utils
} from
'../../../utils/Utils';
50 import { OCPP16ServiceUtils
, OCPPResponseService
} from
'../internal';
52 const moduleName
= 'OCPP16ResponseService';
54 export class OCPP16ResponseService
extends OCPPResponseService
{
55 public jsonIncomingRequestResponseSchemas
: Map
<
56 OCPP16IncomingRequestCommand
,
57 JSONSchemaType
<JsonObject
>
60 private responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>;
61 private jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
63 public constructor() {
64 if (new.target
?.name
=== moduleName
) {
65 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
67 super(OCPPVersion
.VERSION_16
);
68 this.responseHandlers
= new Map
<OCPP16RequestCommand
, ResponseHandler
>([
69 [OCPP16RequestCommand
.BOOT_NOTIFICATION
, this.handleResponseBootNotification
.bind(this)],
70 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this)],
71 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this)],
72 [OCPP16RequestCommand
.START_TRANSACTION
, this.handleResponseStartTransaction
.bind(this)],
73 [OCPP16RequestCommand
.STOP_TRANSACTION
, this.handleResponseStopTransaction
.bind(this)],
74 [OCPP16RequestCommand
.STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
75 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this)],
76 [OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
77 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this)],
78 [OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
80 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
82 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
83 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
84 '../../../assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
90 OCPP16RequestCommand
.HEARTBEAT
,
91 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
92 '../../../assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
98 OCPP16RequestCommand
.AUTHORIZE
,
99 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
100 '../../../assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
106 OCPP16RequestCommand
.START_TRANSACTION
,
107 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
108 '../../../assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
114 OCPP16RequestCommand
.STOP_TRANSACTION
,
115 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
116 '../../../assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
122 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
123 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
124 '../../../assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
130 OCPP16RequestCommand
.METER_VALUES
,
131 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
132 '../../../assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
138 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
139 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
140 '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
146 OCPP16RequestCommand
.DATA_TRANSFER
,
147 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
148 '../../../assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
154 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
155 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
156 '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
162 this.jsonIncomingRequestResponseSchemas
= new Map([
164 OCPP16IncomingRequestCommand
.RESET
,
165 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
166 '../../../assets/json-schemas/ocpp/1.6/ResetResponse.json',
172 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
173 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
174 '../../../assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
180 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
181 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
182 '../../../assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
188 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
189 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
190 '../../../assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
196 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
197 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
198 '../../../assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
204 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
205 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
206 '../../../assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
212 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
213 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
214 '../../../assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
220 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
221 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
222 '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
228 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
229 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
230 '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
236 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
237 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
238 '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
244 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
245 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
246 '../../../assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
252 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
253 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
254 '../../../assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
260 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
261 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
262 '../../../assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
268 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
269 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
270 '../../../assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
276 this.validatePayload
.bind(this);
279 public async responseHandler(
280 chargingStation
: ChargingStation
,
281 commandName
: OCPP16RequestCommand
,
283 requestPayload
: JsonType
286 chargingStation
.isRegistered() === true ||
287 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
290 this.responseHandlers
.has(commandName
) === true &&
291 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
294 this.validatePayload(chargingStation
, commandName
, payload
);
295 await this.responseHandlers
.get(commandName
)(chargingStation
, payload
, requestPayload
);
298 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
306 ErrorType
.NOT_IMPLEMENTED
,
307 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
318 ErrorType
.SECURITY_ERROR
,
319 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
323 )} while the charging station is not registered on the central server.`,
330 private validatePayload(
331 chargingStation
: ChargingStation
,
332 commandName
: OCPP16RequestCommand
,
335 if (this.jsonSchemas
.has(commandName
) === true) {
336 return this.validateResponsePayload(
339 this.jsonSchemas
.get(commandName
),
344 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
349 private handleResponseBootNotification(
350 chargingStation
: ChargingStation
,
351 payload
: OCPP16BootNotificationResponse
353 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
354 ChargingStationConfigurationUtils
.addConfigurationKey(
356 OCPP16StandardParametersKey
.HeartbeatInterval
,
357 payload
.interval
.toString(),
359 { overwrite
: true, save
: true }
361 ChargingStationConfigurationUtils
.addConfigurationKey(
363 OCPP16StandardParametersKey
.HeartBeatInterval
,
364 payload
.interval
.toString(),
366 { overwrite
: true, save
: true }
368 chargingStation
.heartbeatSetInterval
369 ? chargingStation
.restartHeartbeat()
370 : chargingStation
.startHeartbeat();
372 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
373 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
375 }' state on the central server`;
376 payload
.status === RegistrationStatusEnumType
.REJECTED
377 ? logger
.warn(logMsg
)
378 : logger
.info(logMsg
);
381 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
387 private handleResponseAuthorize(
388 chargingStation
: ChargingStation
,
389 payload
: OCPP16AuthorizeResponse
,
390 requestPayload
: OCPP16AuthorizeRequest
392 let authorizeConnectorId
: number;
393 for (const connectorId
of chargingStation
.connectors
.keys()) {
396 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
398 authorizeConnectorId
= connectorId
;
402 const authorizeConnectorIdDefined
= authorizeConnectorId
!== undefined;
403 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
404 authorizeConnectorIdDefined
&&
405 (chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= true);
407 `${chargingStation.logPrefix()} IdTag '${requestPayload.idTag}' accepted${
408 authorizeConnectorIdDefined ? ` on connector ${authorizeConnectorId}
` : ''
412 if (authorizeConnectorIdDefined
) {
413 chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= false;
414 delete chargingStation
.getConnectorStatus(authorizeConnectorId
)?.authorizeIdTag
;
417 `${chargingStation.logPrefix()} IdTag '${requestPayload.idTag}' rejected with status '${
418 payload.idTagInfo.status
419 }'${authorizeConnectorIdDefined ? ` on connector ${authorizeConnectorId}` : ''}`
424 private async handleResponseStartTransaction(
425 chargingStation: ChargingStation,
426 payload: OCPP16StartTransactionResponse,
427 requestPayload: OCPP16StartTransactionRequest
429 const connectorId = requestPayload.connectorId;
431 let transactionConnectorId: number;
432 for (const id of chargingStation.connectors.keys()) {
433 if (id > 0 && id === connectorId) {
434 transactionConnectorId = id;
438 if (Utils.isNullOrUndefined(transactionConnectorId)) {
440 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector Id ${connectorId.toString()}
`
445 chargingStation.getConnectorStatus(connectorId)?.transactionRemoteStarted === true &&
446 chargingStation.getAuthorizeRemoteTxRequests() === true &&
447 chargingStation.getLocalAuthListEnabled() === true &&
448 chargingStation.hasAuthorizedTags() &&
449 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized === false
452 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{
453 chargingStation
.getConnectorStatus(connectorId
)?.localAuthorizeIdTag
454 } on connector Id ${connectorId.toString()}
`
456 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
460 chargingStation.getConnectorStatus(connectorId)?.transactionRemoteStarted === true &&
461 chargingStation.getAuthorizeRemoteTxRequests() === true &&
462 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
463 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized === false &&
464 chargingStation.getConnectorStatus(connectorId)?.idTagAuthorized === false
467 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{
468 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
469 } on connector Id ${connectorId.toString()}
`
471 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
475 chargingStation.getConnectorStatus(connectorId)?.idTagAuthorized &&
476 chargingStation.getConnectorStatus(connectorId)?.authorizeIdTag !== requestPayload.idTag
479 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
481 } different from the authorize request one $
{
482 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
483 } on connector Id ${connectorId.toString()}
`
485 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
489 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized &&
490 chargingStation.getConnectorStatus(connectorId)?.localAuthorizeIdTag !== requestPayload.idTag
493 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
495 } different from the local authorized one $
{
496 chargingStation
.getConnectorStatus(connectorId
)?.localAuthorizeIdTag
497 } on connector Id ${connectorId.toString()}
`
499 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
502 if (chargingStation.getConnectorStatus(connectorId)?.transactionStarted === true) {
504 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector ${connectorId.toString()}
: %j
`,
505 chargingStation.getConnectorStatus(connectorId)
510 chargingStation.getConnectorStatus(connectorId)?.status !==
511 OCPP16ChargePointStatus.AVAILABLE &&
512 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.PREPARING
515 `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()}
with status $
{
516 chargingStation
.getConnectorStatus(connectorId
)?.status
521 // if (!Number.isInteger(payload.transactionId)) {
523 // `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()}
with a non integer transaction Id $
{
524 // payload.transactionId
525 // }, converting to integer`
527 // payload.transactionId = Utils.convertToInt(payload.transactionId);
530 if (payload
.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
531 chargingStation
.getConnectorStatus(connectorId
).transactionStarted
= true;
532 chargingStation
.getConnectorStatus(connectorId
).transactionId
= payload
.transactionId
;
533 chargingStation
.getConnectorStatus(connectorId
).transactionIdTag
= requestPayload
.idTag
;
534 chargingStation
.getConnectorStatus(
536 ).transactionEnergyActiveImportRegisterValue
= 0;
537 chargingStation
.getConnectorStatus(connectorId
).transactionBeginMeterValue
=
538 OCPP16ServiceUtils
.buildTransactionBeginMeterValue(
541 requestPayload
.meterStart
543 chargingStation
.getBeginEndMeterValues() &&
544 (await chargingStation
.ocppRequestService
.requestHandler
<
545 OCPP16MeterValuesRequest
,
546 OCPP16MeterValuesResponse
547 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
549 transactionId
: payload
.transactionId
,
550 meterValue
: [chargingStation
.getConnectorStatus(connectorId
).transactionBeginMeterValue
],
552 await chargingStation
.ocppRequestService
.requestHandler
<
553 OCPP16StatusNotificationRequest
,
554 OCPP16StatusNotificationResponse
555 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
557 status: OCPP16ChargePointStatus
.CHARGING
,
558 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
560 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.CHARGING
;
562 `${chargingStation.logPrefix()} Transaction ${payload.transactionId.toString()} STARTED on ${
563 chargingStation.stationInfo.chargingStationId
564 }#${connectorId.toString()} for idTag '${requestPayload.idTag}'`
566 if (chargingStation
.stationInfo
.powerSharedByConnectors
) {
567 chargingStation
.powerDivider
++;
569 const configuredMeterValueSampleInterval
=
570 ChargingStationConfigurationUtils
.getConfigurationKey(
572 OCPP16StandardParametersKey
.MeterValueSampleInterval
574 chargingStation
.startMeterValues(
576 configuredMeterValueSampleInterval
577 ? Utils
.convertToInt(configuredMeterValueSampleInterval
.value
) * 1000
578 : Constants
.DEFAULT_METER_VALUES_INTERVAL
582 `${chargingStation.logPrefix()} Starting transaction id ${payload.transactionId.toString()} REJECTED with status '${
583 payload.idTagInfo?.status
584 }', idTag '${requestPayload.idTag}'`
586 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
);
590 private async resetConnectorOnStartTransactionError(
591 chargingStation
: ChargingStation
,
594 chargingStation
.resetConnectorStatus(connectorId
);
596 chargingStation
.getConnectorStatus(connectorId
)?.status !== OCPP16ChargePointStatus
.AVAILABLE
598 await chargingStation
.ocppRequestService
.requestHandler
<
599 OCPP16StatusNotificationRequest
,
600 OCPP16StatusNotificationResponse
601 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
603 status: OCPP16ChargePointStatus
.AVAILABLE
,
604 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
606 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.AVAILABLE
;
610 private async handleResponseStopTransaction(
611 chargingStation
: ChargingStation
,
612 payload
: OCPP16StopTransactionResponse
,
613 requestPayload
: OCPP16StopTransactionRequest
615 const transactionConnectorId
= chargingStation
.getConnectorIdByTransactionId(
616 requestPayload
.transactionId
618 if (Utils
.isNullOrUndefined(transactionConnectorId
)) {
620 `${chargingStation.logPrefix()} Trying to stop a non existing transaction ${requestPayload.transactionId.toString()}`
624 chargingStation
.getBeginEndMeterValues() === true &&
625 chargingStation
.getOcppStrictCompliance() === false &&
626 chargingStation
.getOutOfOrderEndMeterValues() === true &&
627 (await chargingStation
.ocppRequestService
.requestHandler
<
628 OCPP16MeterValuesRequest
,
629 OCPP16MeterValuesResponse
630 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
631 connectorId
: transactionConnectorId
,
632 transactionId
: requestPayload
.transactionId
,
634 OCPP16ServiceUtils
.buildTransactionEndMeterValue(
636 transactionConnectorId
,
637 requestPayload
.meterStop
642 chargingStation
.isChargingStationAvailable() === false ||
643 chargingStation
.isConnectorAvailable(transactionConnectorId
) === false
645 await chargingStation
.ocppRequestService
.requestHandler
<
646 OCPP16StatusNotificationRequest
,
647 OCPP16StatusNotificationResponse
648 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
649 connectorId
: transactionConnectorId
,
650 status: OCPP16ChargePointStatus
.UNAVAILABLE
,
651 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
653 chargingStation
.getConnectorStatus(transactionConnectorId
).status =
654 OCPP16ChargePointStatus
.UNAVAILABLE
;
656 await chargingStation
.ocppRequestService
.requestHandler
<
657 OCPP16BootNotificationRequest
,
658 OCPP16BootNotificationResponse
659 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
660 connectorId
: transactionConnectorId
,
661 status: OCPP16ChargePointStatus
.AVAILABLE
,
662 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
664 chargingStation
.getConnectorStatus(transactionConnectorId
).status =
665 OCPP16ChargePointStatus
.AVAILABLE
;
667 if (chargingStation
.stationInfo
.powerSharedByConnectors
) {
668 chargingStation
.powerDivider
--;
670 chargingStation
.resetConnectorStatus(transactionConnectorId
);
671 const logMsg
= `${chargingStation.logPrefix()} Transaction ${requestPayload.transactionId.toString()} STOPPED on ${
672 chargingStation.stationInfo.chargingStationId
673 }#${transactionConnectorId?.toString()} with status '${
674 payload.idTagInfo?.status ?? 'undefined'
677 Utils
.isNullOrUndefined(payload
.idTagInfo
) ||
678 payload
.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED