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 OCPP16GetCompositeScheduleResponse
,
28 type OCPP16HeartbeatResponse
,
29 OCPP16IncomingRequestCommand
,
30 type OCPP16MeterValuesRequest
,
31 type OCPP16MeterValuesResponse
,
33 OCPP16StandardParametersKey
,
34 type OCPP16StartTransactionRequest
,
35 type OCPP16StartTransactionResponse
,
36 type OCPP16StatusNotificationRequest
,
37 type OCPP16StatusNotificationResponse
,
38 type OCPP16StopTransactionRequest
,
39 type OCPP16StopTransactionResponse
,
40 type OCPP16TriggerMessageResponse
,
41 type OCPP16UpdateFirmwareResponse
,
43 RegistrationStatusEnumType
,
45 type SetChargingProfileResponse
,
46 type UnlockConnectorResponse
,
47 } from
'../../../types';
48 import { Constants
, Utils
, logger
} from
'../../../utils';
49 import { OCPP16ServiceUtils
, OCPPResponseService
} from
'../internal';
51 const moduleName
= 'OCPP16ResponseService';
53 export class OCPP16ResponseService
extends OCPPResponseService
{
54 public jsonIncomingRequestResponseSchemas
: Map
<
55 OCPP16IncomingRequestCommand
,
56 JSONSchemaType
<JsonObject
>
59 private responseHandlers
: Map
<OCPP16RequestCommand
, ResponseHandler
>;
60 private jsonSchemas
: Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>;
62 public constructor() {
63 // if (new.target?.name === moduleName) {
64 // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
66 super(OCPPVersion
.VERSION_16
);
67 this.responseHandlers
= new Map
<OCPP16RequestCommand
, ResponseHandler
>([
68 [OCPP16RequestCommand
.BOOT_NOTIFICATION
, this.handleResponseBootNotification
.bind(this)],
69 [OCPP16RequestCommand
.HEARTBEAT
, this.emptyResponseHandler
.bind(this)],
70 [OCPP16RequestCommand
.AUTHORIZE
, this.handleResponseAuthorize
.bind(this)],
71 [OCPP16RequestCommand
.START_TRANSACTION
, this.handleResponseStartTransaction
.bind(this)],
72 [OCPP16RequestCommand
.STOP_TRANSACTION
, this.handleResponseStopTransaction
.bind(this)],
73 [OCPP16RequestCommand
.STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
74 [OCPP16RequestCommand
.METER_VALUES
, this.emptyResponseHandler
.bind(this)],
75 [OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
76 [OCPP16RequestCommand
.DATA_TRANSFER
, this.emptyResponseHandler
.bind(this)],
77 [OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, this.emptyResponseHandler
.bind(this)],
79 this.jsonSchemas
= new Map
<OCPP16RequestCommand
, JSONSchemaType
<JsonObject
>>([
81 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
82 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16BootNotificationResponse
>(
83 '../../../assets/json-schemas/ocpp/1.6/BootNotificationResponse.json',
89 OCPP16RequestCommand
.HEARTBEAT
,
90 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16HeartbeatResponse
>(
91 '../../../assets/json-schemas/ocpp/1.6/HeartbeatResponse.json',
97 OCPP16RequestCommand
.AUTHORIZE
,
98 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16AuthorizeResponse
>(
99 '../../../assets/json-schemas/ocpp/1.6/AuthorizeResponse.json',
105 OCPP16RequestCommand
.START_TRANSACTION
,
106 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StartTransactionResponse
>(
107 '../../../assets/json-schemas/ocpp/1.6/StartTransactionResponse.json',
113 OCPP16RequestCommand
.STOP_TRANSACTION
,
114 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StopTransactionResponse
>(
115 '../../../assets/json-schemas/ocpp/1.6/StopTransactionResponse.json',
121 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
122 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16StatusNotificationResponse
>(
123 '../../../assets/json-schemas/ocpp/1.6/StatusNotificationResponse.json',
129 OCPP16RequestCommand
.METER_VALUES
,
130 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16MeterValuesResponse
>(
131 '../../../assets/json-schemas/ocpp/1.6/MeterValuesResponse.json',
137 OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
,
138 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DiagnosticsStatusNotificationResponse
>(
139 '../../../assets/json-schemas/ocpp/1.6/DiagnosticsStatusNotificationResponse.json',
145 OCPP16RequestCommand
.DATA_TRANSFER
,
146 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
147 '../../../assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
153 OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
,
154 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16FirmwareStatusNotificationResponse
>(
155 '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json',
161 this.jsonIncomingRequestResponseSchemas
= new Map([
163 OCPP16IncomingRequestCommand
.RESET
,
164 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
165 '../../../assets/json-schemas/ocpp/1.6/ResetResponse.json',
171 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
172 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
173 '../../../assets/json-schemas/ocpp/1.6/ClearCacheResponse.json',
179 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
180 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityResponse
>(
181 '../../../assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json',
187 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
188 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorResponse
>(
189 '../../../assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json',
195 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
196 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationResponse
>(
197 '../../../assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json',
203 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
204 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationResponse
>(
205 '../../../assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json',
211 OCPP16IncomingRequestCommand
.GET_COMPOSITE_SCHEDULE
,
212 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16GetCompositeScheduleResponse
>(
213 '../../../assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json',
219 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
220 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileResponse
>(
221 '../../../assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json',
227 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
228 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileResponse
>(
229 '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json',
235 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
236 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
237 '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json',
243 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
244 OCPP16ServiceUtils
.parseJsonSchemaFile
<GenericResponse
>(
245 '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json',
251 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
252 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsResponse
>(
253 '../../../assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json',
259 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
260 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageResponse
>(
261 '../../../assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json',
267 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
268 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferResponse
>(
269 '../../../assets/json-schemas/ocpp/1.6/DataTransferResponse.json',
275 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
276 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareResponse
>(
277 '../../../assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json',
283 this.validatePayload
.bind(this);
286 public async responseHandler(
287 chargingStation
: ChargingStation
,
288 commandName
: OCPP16RequestCommand
,
290 requestPayload
: JsonType
293 chargingStation
.isRegistered() === true ||
294 commandName
=== OCPP16RequestCommand
.BOOT_NOTIFICATION
297 this.responseHandlers
.has(commandName
) === true &&
298 OCPP16ServiceUtils
.isRequestCommandSupported(chargingStation
, commandName
) === true
301 this.validatePayload(chargingStation
, commandName
, payload
);
302 await this.responseHandlers
.get(commandName
)(chargingStation
, payload
, requestPayload
);
305 `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`,
313 ErrorType
.NOT_IMPLEMENTED
,
314 `${commandName} is not implemented to handle response PDU ${JSON.stringify(
325 ErrorType
.SECURITY_ERROR
,
326 `${commandName} cannot be issued to handle response PDU ${JSON.stringify(
330 )} while the charging station is not registered on the central server.`,
337 private validatePayload(
338 chargingStation
: ChargingStation
,
339 commandName
: OCPP16RequestCommand
,
342 if (this.jsonSchemas
.has(commandName
) === true) {
343 return this.validateResponsePayload(
346 this.jsonSchemas
.get(commandName
),
351 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
356 private handleResponseBootNotification(
357 chargingStation
: ChargingStation
,
358 payload
: OCPP16BootNotificationResponse
360 if (payload
.status === RegistrationStatusEnumType
.ACCEPTED
) {
361 ChargingStationConfigurationUtils
.addConfigurationKey(
363 OCPP16StandardParametersKey
.HeartbeatInterval
,
364 payload
.interval
.toString(),
366 { overwrite
: true, save
: true }
368 ChargingStationConfigurationUtils
.addConfigurationKey(
370 OCPP16StandardParametersKey
.HeartBeatInterval
,
371 payload
.interval
.toString(),
373 { overwrite
: true, save
: true }
375 OCPP16ServiceUtils
.startHeartbeatInterval(chargingStation
, payload
.interval
);
377 if (Object.values(RegistrationStatusEnumType
).includes(payload
.status)) {
378 const logMsg
= `${chargingStation.logPrefix()} Charging station in '${
380 }' state on the central server`;
381 payload
.status === RegistrationStatusEnumType
.REJECTED
382 ? logger
.warn(logMsg
)
383 : logger
.info(logMsg
);
386 `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
392 private handleResponseAuthorize(
393 chargingStation
: ChargingStation
,
394 payload
: OCPP16AuthorizeResponse
,
395 requestPayload
: OCPP16AuthorizeRequest
397 let authorizeConnectorId
: number;
398 for (const connectorId
of chargingStation
.connectors
.keys()) {
401 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
=== requestPayload
.idTag
403 authorizeConnectorId
= connectorId
;
407 const authorizeConnectorIdDefined
= !Utils
.isNullOrUndefined(authorizeConnectorId
);
408 if (payload
.idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
409 authorizeConnectorIdDefined
&&
410 (chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= true);
412 `${chargingStation.logPrefix()} IdTag '${requestPayload.idTag}' accepted${
413 authorizeConnectorIdDefined ? ` on connector ${authorizeConnectorId}
` : ''
417 if (authorizeConnectorIdDefined
) {
418 chargingStation
.getConnectorStatus(authorizeConnectorId
).idTagAuthorized
= false;
419 delete chargingStation
.getConnectorStatus(authorizeConnectorId
)?.authorizeIdTag
;
422 `${chargingStation.logPrefix()} IdTag '${requestPayload.idTag}' rejected with status '${
423 payload.idTagInfo.status
424 }'${authorizeConnectorIdDefined ? ` on connector ${authorizeConnectorId}` : ''}`
429 private async handleResponseStartTransaction(
430 chargingStation: ChargingStation,
431 payload: OCPP16StartTransactionResponse,
432 requestPayload: OCPP16StartTransactionRequest
434 const connectorId = requestPayload.connectorId;
436 let transactionConnectorId: number;
437 for (const id of chargingStation.connectors.keys()) {
438 if (id > 0 && id === connectorId) {
439 transactionConnectorId = id;
443 if (Utils.isNullOrUndefined(transactionConnectorId)) {
445 `${chargingStation.logPrefix()} Trying to start a transaction on a non existing connector Id ${connectorId.toString()}
`
450 chargingStation.getConnectorStatus(connectorId)?.transactionRemoteStarted === true &&
451 chargingStation.getAuthorizeRemoteTxRequests() === true &&
452 chargingStation.getLocalAuthListEnabled() === true &&
453 chargingStation.hasIdTags() &&
454 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized === false
457 `${chargingStation.logPrefix()} Trying to start a transaction
with a not local authorized idTag $
{
458 chargingStation
.getConnectorStatus(connectorId
)?.localAuthorizeIdTag
459 } on connector Id ${connectorId.toString()}
`
461 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
465 chargingStation.getConnectorStatus(connectorId)?.transactionRemoteStarted === true &&
466 chargingStation.getAuthorizeRemoteTxRequests() === true &&
467 chargingStation.getMustAuthorizeAtRemoteStart() === true &&
468 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized === false &&
469 chargingStation.getConnectorStatus(connectorId)?.idTagAuthorized === false
472 `${chargingStation.logPrefix()} Trying to start a transaction
with a not authorized idTag $
{
473 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
474 } on connector Id ${connectorId.toString()}
`
476 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
480 chargingStation.getConnectorStatus(connectorId)?.idTagAuthorized &&
481 chargingStation.getConnectorStatus(connectorId)?.authorizeIdTag !== requestPayload.idTag
484 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
486 } different from the authorize request one $
{
487 chargingStation
.getConnectorStatus(connectorId
)?.authorizeIdTag
488 } on connector Id ${connectorId.toString()}
`
490 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
494 chargingStation.getConnectorStatus(connectorId)?.idTagLocalAuthorized &&
495 chargingStation.getConnectorStatus(connectorId)?.localAuthorizeIdTag !== requestPayload.idTag
498 `${chargingStation.logPrefix()} Trying to start a transaction
with an idTag $
{
500 } different from the local authorized one $
{
501 chargingStation
.getConnectorStatus(connectorId
)?.localAuthorizeIdTag
502 } on connector Id ${connectorId.toString()}
`
504 await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
507 if (chargingStation.getConnectorStatus(connectorId)?.transactionStarted === true) {
509 `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector ${connectorId.toString()}
: %j
`,
510 chargingStation.getConnectorStatus(connectorId)
515 chargingStation.getConnectorStatus(connectorId)?.status !==
516 OCPP16ChargePointStatus.Available &&
517 chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Preparing
520 `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()}
with status $
{
521 chargingStation
.getConnectorStatus(connectorId
)?.status
526 // if (!Number.isInteger(payload.transactionId)) {
528 // `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()}
with a non integer transaction Id $
{
529 // payload.transactionId
530 // }, converting to integer`
532 // payload.transactionId = Utils.convertToInt(payload.transactionId);
535 if (payload
.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
536 chargingStation
.getConnectorStatus(connectorId
).transactionStarted
= true;
537 chargingStation
.getConnectorStatus(connectorId
).transactionId
= payload
.transactionId
;
538 chargingStation
.getConnectorStatus(connectorId
).transactionIdTag
= requestPayload
.idTag
;
539 chargingStation
.getConnectorStatus(
541 ).transactionEnergyActiveImportRegisterValue
= 0;
542 chargingStation
.getConnectorStatus(connectorId
).transactionBeginMeterValue
=
543 OCPP16ServiceUtils
.buildTransactionBeginMeterValue(
546 requestPayload
.meterStart
548 chargingStation
.getBeginEndMeterValues() &&
549 (await chargingStation
.ocppRequestService
.requestHandler
<
550 OCPP16MeterValuesRequest
,
551 OCPP16MeterValuesResponse
552 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
554 transactionId
: payload
.transactionId
,
555 meterValue
: [chargingStation
.getConnectorStatus(connectorId
).transactionBeginMeterValue
],
557 await chargingStation
.ocppRequestService
.requestHandler
<
558 OCPP16StatusNotificationRequest
,
559 OCPP16StatusNotificationResponse
560 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
562 status: OCPP16ChargePointStatus
.Charging
,
563 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
565 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.Charging
;
567 `${chargingStation.logPrefix()} Transaction ${payload.transactionId.toString()} STARTED on ${
568 chargingStation.stationInfo.chargingStationId
569 }#${connectorId.toString()} for idTag '${requestPayload.idTag}'`
571 if (chargingStation
.stationInfo
.powerSharedByConnectors
) {
572 chargingStation
.powerDivider
++;
574 const configuredMeterValueSampleInterval
=
575 ChargingStationConfigurationUtils
.getConfigurationKey(
577 OCPP16StandardParametersKey
.MeterValueSampleInterval
579 chargingStation
.startMeterValues(
581 configuredMeterValueSampleInterval
582 ? Utils
.convertToInt(configuredMeterValueSampleInterval
.value
) * 1000
583 : Constants
.DEFAULT_METER_VALUES_INTERVAL
587 `${chargingStation.logPrefix()} Starting transaction id ${payload.transactionId.toString()} REJECTED with status '${
588 payload.idTagInfo?.status
589 }', idTag '${requestPayload.idTag}'`
591 await this.resetConnectorOnStartTransactionError(chargingStation
, connectorId
);
595 private async resetConnectorOnStartTransactionError(
596 chargingStation
: ChargingStation
,
599 chargingStation
.resetConnectorStatus(connectorId
);
601 chargingStation
.getConnectorStatus(connectorId
)?.status !== OCPP16ChargePointStatus
.Available
603 await chargingStation
.ocppRequestService
.requestHandler
<
604 OCPP16StatusNotificationRequest
,
605 OCPP16StatusNotificationResponse
606 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
608 status: OCPP16ChargePointStatus
.Available
,
609 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
611 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.Available
;
615 private async handleResponseStopTransaction(
616 chargingStation
: ChargingStation
,
617 payload
: OCPP16StopTransactionResponse
,
618 requestPayload
: OCPP16StopTransactionRequest
620 const transactionConnectorId
= chargingStation
.getConnectorIdByTransactionId(
621 requestPayload
.transactionId
623 if (Utils
.isNullOrUndefined(transactionConnectorId
)) {
625 `${chargingStation.logPrefix()} Trying to stop a non existing transaction ${requestPayload.transactionId.toString()}`
629 chargingStation
.getBeginEndMeterValues() === true &&
630 chargingStation
.getOcppStrictCompliance() === false &&
631 chargingStation
.getOutOfOrderEndMeterValues() === true &&
632 (await chargingStation
.ocppRequestService
.requestHandler
<
633 OCPP16MeterValuesRequest
,
634 OCPP16MeterValuesResponse
635 >(chargingStation
, OCPP16RequestCommand
.METER_VALUES
, {
636 connectorId
: transactionConnectorId
,
637 transactionId
: requestPayload
.transactionId
,
639 OCPP16ServiceUtils
.buildTransactionEndMeterValue(
641 transactionConnectorId
,
642 requestPayload
.meterStop
647 chargingStation
.isChargingStationAvailable() === false ||
648 chargingStation
.isConnectorAvailable(transactionConnectorId
) === false
650 await chargingStation
.ocppRequestService
.requestHandler
<
651 OCPP16StatusNotificationRequest
,
652 OCPP16StatusNotificationResponse
653 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
654 connectorId
: transactionConnectorId
,
655 status: OCPP16ChargePointStatus
.Unavailable
,
656 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
658 chargingStation
.getConnectorStatus(transactionConnectorId
).status =
659 OCPP16ChargePointStatus
.Unavailable
;
661 await chargingStation
.ocppRequestService
.requestHandler
<
662 OCPP16BootNotificationRequest
,
663 OCPP16BootNotificationResponse
664 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
665 connectorId
: transactionConnectorId
,
666 status: OCPP16ChargePointStatus
.Available
,
667 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
669 chargingStation
.getConnectorStatus(transactionConnectorId
).status =
670 OCPP16ChargePointStatus
.Available
;
672 if (chargingStation
.stationInfo
.powerSharedByConnectors
) {
673 chargingStation
.powerDivider
--;
675 chargingStation
.resetConnectorStatus(transactionConnectorId
);
676 const logMsg
= `${chargingStation.logPrefix()} Transaction ${requestPayload.transactionId.toString()} STOPPED on ${
677 chargingStation.stationInfo.chargingStationId
678 }#${transactionConnectorId?.toString()} with status '${
679 payload.idTagInfo?.status ?? 'undefined'
682 Utils
.isNullOrUndefined(payload
.idTagInfo
) ||
683 payload
.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED