Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
Fix PENDING state boot notification handling
Browse files Browse the repository at this point in the history
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
  • Loading branch information
Jérôme Benoit committed Feb 4, 2022
1 parent c3ee95a commit 16cd35a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/charging-station/AutomaticTransactionGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ export default class AutomaticTransactionGenerator {
this.stopConnector(connectorId);
break;
}
if (!this.chargingStation.isRegistered()) {
logger.error(this.logPrefix(connectorId) + ' entered in transaction loop while the charging station is not registered');
if (!this.chargingStation.isInAcceptedState()) {
logger.error(this.logPrefix(connectorId) + ' entered in transaction loop while the charging station is in accepted state');
this.stopConnector(connectorId);
break;
}
Expand Down
26 changes: 24 additions & 2 deletions src/charging-station/ChargingStation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,22 @@ export default class ChargingStation {
return this?.wsConnection?.readyState === OPEN;
}

public isRegistered(): boolean {
public isInPendingState(): boolean {
return this?.bootNotificationResponse?.status === RegistrationStatus.PENDING;
}

public isInAcceptedState(): boolean {
return this?.bootNotificationResponse?.status === RegistrationStatus.ACCEPTED;
}

public isInRejectedState(): boolean {
return this?.bootNotificationResponse?.status === RegistrationStatus.REJECTED;
}

public isRegistered(): boolean {
return this.isInAcceptedState() || this.isInPendingState();
}

public isChargingStationAvailable(): boolean {
return this.getConnectorStatus(0).availability === AvailabilityType.OPERATIVE;
}
Expand Down Expand Up @@ -644,12 +656,22 @@ export default class ChargingStation {
await this.ocppRequestService.sendBootNotification(this.bootNotificationRequest.chargePointModel,
this.bootNotificationRequest.chargePointVendor, this.bootNotificationRequest.chargeBoxSerialNumber, this.bootNotificationRequest.firmwareVersion);
}
if (this.isRegistered()) {
if (this.isInAcceptedState()) {
await this.startMessageSequence();
this.stopped && (this.stopped = false);
if (this.wsConnectionRestarted && this.isWebSocketConnectionOpened()) {
this.flushMessageBuffer();
}
} else if (this.isInPendingState()) {
// The central server shall issue a triggerMessage to the charging station for the boot notification at the end of its configuration process
while (!this.isInAcceptedState()) {
await this.startMessageSequence();
this.stopped && (this.stopped = false);
if (this.wsConnectionRestarted && this.isWebSocketConnectionOpened()) {
this.flushMessageBuffer();
}
await Utils.sleep(Constants.CHARGING_STATION_DEFAULT_START_SEQUENCE_DELAY);
}
} else {
logger.error(`${this.logPrefix()} Registration failure: max retries reached (${this.getRegistrationMaxRetries()}) or retry disabled (${this.getRegistrationMaxRetries()})`);
}
Expand Down
6 changes: 4 additions & 2 deletions src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer

public async handleRequest(messageId: string, commandName: OCPP16IncomingRequestCommand, commandPayload: Record<string, unknown>): Promise<void> {
let result: Record<string, unknown>;
if (this.chargingStation.isRegistered()) {
if (this.chargingStation.isRegistered() &&

This comment has been minimized.

Copy link
@captaineaglex

captaineaglex Feb 4, 2022

Contributor

2 points regarding this condition

Let's think of this case:

1- In the initialisation, CPO accepts token and then CPO sets the charging station in pending phase, create the auth token and issues a changeConfig with new ocppUrl with Auth token.

In the handleRequest,
if evaluates the following:
(isRegistered == true && not isPendingState == false && (command == 'ChangeConfig' hence false )) --> false

then throws error: security error, The charging station is not registered on the central server. change configuration

But our capability of being able to auto-config ocpp URL should be dependent on CS's capability of enabling config request or not. In this case independent of the CS's capabilities, any CS will not allow auto-config, with the above request specification which is sent by a CPO.

2- Also the error is not correct. isRegistered() == true, hence "charging station is not registered" is not a compatible error text. The other conditions which result in false do not mean that CS is not registered.

Would you agree? What are your comments about this?

This comment has been minimized.

Copy link
@jerome-benoit

jerome-benoit Feb 4, 2022

Owner

I think the issue is coming from the logical proposition and from the typo ...

!(this.chargingStation.isInPendingState

This comment has been minimized.

Copy link
@captaineaglex

captaineaglex Feb 4, 2022

Contributor
      !(this.chargingStation.isInPendingState()

typo fix

&& (commandName === OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION || commandName === OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION))) {
if (this.incomingRequestHandlers.has(commandName)) {
try {
// Call the method to build the result
Expand Down Expand Up @@ -295,7 +297,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
if (this.chargingStation.getAuthorizeRemoteTxRequests()) {
let authorized = false;
if (this.chargingStation.getLocalAuthListEnabled() && this.chargingStation.hasAuthorizedTags()
&& this.chargingStation.authorizedTags.find((value) => value === commandPayload.idTag)) {
&& this.chargingStation.authorizedTags.find((value) => value === commandPayload.idTag)) {
this.chargingStation.getConnectorStatus(transactionConnectorId).localAuthorizeIdTag = commandPayload.idTag;
this.chargingStation.getConnectorStatus(transactionConnectorId).idTagLocalAuthorized = true;
authorized = true;
Expand Down
1 change: 1 addition & 0 deletions src/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default class Constants {
static readonly OCPP_WEBSOCKET_TIMEOUT = 60000; // Ms
static readonly OCPP_TRIGGER_MESSAGE_DELAY = 2000; // Ms

static readonly CHARGING_STATION_DEFAULT_START_SEQUENCE_DELAY = 60000; // Ms
static readonly CHARGING_STATION_DEFAULT_RESET_TIME = 60000; // Ms
static readonly CHARGING_STATION_ATG_INITIALIZATION_TIME = 1000; // Ms
static readonly CHARGING_STATION_ATG_DEFAULT_STOP_AFTER_HOURS = 0.25; // Hours
Expand Down

0 comments on commit 16cd35a

Please sign in to comment.