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

Commit

Permalink
Keep track of authorize request idtag status.
Browse files Browse the repository at this point in the history
And use it to add sanity check at start transaction.

Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
  • Loading branch information
Jérôme Benoit committed Jun 21, 2021
1 parent 7486490 commit 163547b
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 109 deletions.
232 changes: 139 additions & 93 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,23 @@
"@types/node": "^14.17.3",
"@types/uuid": "^8.3.0",
"@types/ws": "^7.4.5",
"@typescript-eslint/eslint-plugin": "^4.27.0",
"@typescript-eslint/parser": "^4.27.0",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.28.0",
"auto-changelog": "^2.3.0",
"clinic": "^9.0.0",
"cross-env": "^7.0.3",
"eslint": "^7.29.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsdoc": "^35.3.2",
"eslint-plugin-jsdoc": "^35.4.0",
"eslint-plugin-node": "^11.1.0",
"expect": "^27.0.2",
"mbt": "^1.2.1",
"mocha": "^9.0.1",
"mochawesome": "^6.2.2",
"npm-check": "^5.9.2",
"nyc": "^15.1.0",
"release-it": "^14.9.0",
"rollup": "^2.52.1",
"release-it": "^14.10.0",
"rollup": "^2.52.2",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-delete": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/charging-station/AutomaticTransactionGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export default class AutomaticTransactionGenerator {
const tagId = self.chargingStation.getRandomTagId();
if (self.chargingStation.getAutomaticTransactionGeneratorRequireAuthorize()) {
// Authorize tagId
const authorizeResponse = await self.chargingStation.ocppRequestService.sendAuthorize(tagId);
const authorizeResponse = await self.chargingStation.ocppRequestService.sendAuthorize(connectorId, tagId);
if (authorizeResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
logger.info(self.logPrefix(connectorId) + ' start transaction for tagID ' + tagId);
// Start transaction
Expand Down
9 changes: 6 additions & 3 deletions src/charging-station/ChargingStation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export default class ChargingStation {
public getTransactionIdTag(transactionId: number): string | undefined {
for (const connector in this.connectors) {
if (Utils.convertToInt(connector) > 0 && this.getConnector(Utils.convertToInt(connector)).transactionId === transactionId) {
return this.getConnector(Utils.convertToInt(connector)).idTag;
return this.getConnector(Utils.convertToInt(connector)).transactionIdTag;
}
}
}
Expand Down Expand Up @@ -219,7 +219,7 @@ export default class ChargingStation {
return;
}
if (measurand !== MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER && !this.getConfigurationKey(StandardParametersKey.MeterValuesSampledData).value.includes(measurand)) {
logger.warn(`${this.logPrefix()} Trying to get MeterValues measurand ${measurand} ${phase ? `on phase ${phase} ` : ''}in template on connectorId ${connectorId} not found in '${StandardParametersKey.MeterValuesSampledData}' OCPP parameter`);
logger.debug(`${this.logPrefix()} Trying to get MeterValues measurand ${measurand} ${phase ? `on phase ${phase} ` : ''}in template on connectorId ${connectorId} not found in '${StandardParametersKey.MeterValuesSampledData}' OCPP parameter`);
return;
}
const sampledValueTemplates: SampledValueTemplate[] = this.getConnector(connectorId).MeterValues;
Expand Down Expand Up @@ -386,9 +386,11 @@ export default class ChargingStation {
}

public resetTransactionOnConnector(connectorId: number): void {
this.getConnector(connectorId).authorized = false;
this.getConnector(connectorId).transactionStarted = false;
delete this.getConnector(connectorId).authorizeIdTag;
delete this.getConnector(connectorId).transactionId;
delete this.getConnector(connectorId).idTag;
delete this.getConnector(connectorId).transactionIdTag;
this.getConnector(connectorId).transactionEnergyActiveImportRegisterValue = 0;
delete this.getConnector(connectorId).transactionBeginMeterValue;
this.stopMeterValues(connectorId);
Expand Down Expand Up @@ -1027,6 +1029,7 @@ export default class ChargingStation {
}

private initTransactionAttributesOnConnector(connectorId: number): void {
this.getConnector(connectorId).authorized = false;
this.getConnector(connectorId).transactionStarted = false;
this.getConnector(connectorId).energyActiveImportRegisterValue = 0;
this.getConnector(connectorId).transactionEnergyActiveImportRegisterValue = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer
}
}
if (!authorized) {
const authorizeResponse = await this.chargingStation.ocppRequestService.sendAuthorize(commandPayload.idTag);
const authorizeResponse = await this.chargingStation.ocppRequestService.sendAuthorize(transactionConnectorID, commandPayload.idTag);
if (authorizeResponse?.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
authorized = true;
}
Expand Down
4 changes: 3 additions & 1 deletion src/charging-station/ocpp/1.6/OCPP16RequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ export default class OCPP16RequestService extends OCPPRequestService {
}
}

public async sendAuthorize(idTag?: string): Promise<OCPP16AuthorizeResponse> {
public async sendAuthorize(connectorId: number, idTag?: string): Promise<OCPP16AuthorizeResponse> {
try {
const payload: AuthorizeRequest = {
...!Utils.isUndefined(idTag) ? { idTag } : { idTag: Constants.TRANSACTION_DEFAULT_IDTAG },
};
this.chargingStation.getConnector(connectorId).authorizeIdTag = idTag;
return await this.sendMessage(Utils.generateUUID(), payload, MessageType.CALL_MESSAGE, OCPP16RequestCommand.AUTHORIZE) as OCPP16AuthorizeResponse;
} catch (error) {
this.handleRequestError(OCPP16RequestCommand.AUTHORIZE, error);
Expand Down Expand Up @@ -93,6 +94,7 @@ export default class OCPP16RequestService extends OCPPRequestService {
for (const connector in this.chargingStation.connectors) {
if (Utils.convertToInt(connector) > 0 && this.chargingStation.getConnector(Utils.convertToInt(connector))?.transactionId === transactionId) {
connectorId = Utils.convertToInt(connector);
break;
}
}
const transactionEndMeterValue = OCPP16ServiceUtils.buildTransactionEndMeterValue(this.chargingStation, connectorId, meterStop);
Expand Down
22 changes: 20 additions & 2 deletions src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ export default class OCPP16ResponseService extends OCPPResponseService {
logger.error(this.chargingStation.logPrefix() + ' Trying to start a transaction on a non existing connector Id ' + connectorId.toString());
return;
}
if (this.chargingStation.getConnector(connectorId).authorized && this.chargingStation.getConnector(connectorId).authorizeIdTag !== requestPayload.idTag) {
logger.error(this.chargingStation.logPrefix() + ' Trying to start a transaction with an idTag ' + requestPayload.idTag + ' different from the authorize request one ' + this.chargingStation.getConnector(connectorId).authorizeIdTag + ' on connector Id ' + connectorId.toString());
return;
}
if (this.chargingStation.getConnector(connectorId)?.transactionStarted) {
logger.debug(this.chargingStation.logPrefix() + ' Trying to start a transaction on an already used connector ' + connectorId.toString() + ': %j', this.chargingStation.getConnector(connectorId));
return;
Expand All @@ -54,7 +58,7 @@ export default class OCPP16ResponseService extends OCPPResponseService {
if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
this.chargingStation.getConnector(connectorId).transactionStarted = true;
this.chargingStation.getConnector(connectorId).transactionId = payload.transactionId;
this.chargingStation.getConnector(connectorId).idTag = requestPayload.idTag;
this.chargingStation.getConnector(connectorId).transactionIdTag = requestPayload.idTag;
this.chargingStation.getConnector(connectorId).transactionEnergyActiveImportRegisterValue = 0;
this.chargingStation.getConnector(connectorId).transactionBeginMeterValue = OCPP16ServiceUtils.buildTransactionBeginMeterValue(this.chargingStation, connectorId,
requestPayload.meterStart);
Expand Down Expand Up @@ -122,6 +126,20 @@ export default class OCPP16ResponseService extends OCPPResponseService {
}

private handleResponseAuthorize(payload: OCPP16AuthorizeResponse, requestPayload: AuthorizeRequest): void {
logger.debug(this.chargingStation.logPrefix() + ' Authorize response received: %j to Authorize request: %j', payload, requestPayload);
let authorizeConnectorId: number;
for (const connector in this.chargingStation.connectors) {
if (Utils.convertToInt(connector) > 0 && this.chargingStation.getConnector(Utils.convertToInt(connector))?.authorizeIdTag === requestPayload.idTag) {
authorizeConnectorId = Utils.convertToInt(connector);
break;
}
}
if (payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED) {
this.chargingStation.getConnector(authorizeConnectorId).authorized = true;
logger.debug(`${this.chargingStation.logPrefix()} IdTag ${requestPayload.idTag} authorized on connector ${authorizeConnectorId}`);
} else {
this.chargingStation.getConnector(authorizeConnectorId).authorized = false;
delete this.chargingStation.getConnector(authorizeConnectorId).authorizeIdTag;
logger.debug(`${this.chargingStation.logPrefix()} IdTag ${requestPayload.idTag} refused with status ${payload.idTagInfo.status} on connector ${authorizeConnectorId}`);
}
}
}
2 changes: 1 addition & 1 deletion src/charging-station/ocpp/OCPPRequestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export default abstract class OCPPRequestService {
public abstract sendHeartbeat(): Promise<void>;
public abstract sendBootNotification(chargePointModel: string, chargePointVendor: string, chargeBoxSerialNumber?: string, firmwareVersion?: string, chargePointSerialNumber?: string, iccid?: string, imsi?: string, meterSerialNumber?: string, meterType?: string): Promise<BootNotificationResponse>;
public abstract sendStatusNotification(connectorId: number, status: ChargePointStatus, errorCode?: ChargePointErrorCode): Promise<void>;
public abstract sendAuthorize(idTag?: string): Promise<AuthorizeResponse>;
public abstract sendAuthorize(connectorId: number, idTag?: string): Promise<AuthorizeResponse>;
public abstract sendStartTransaction(connectorId: number, idTag?: string): Promise<StartTransactionResponse>;
public abstract sendStopTransaction(transactionId: number, meterStop: number, idTag?: string, reason?: StopTransactionReason): Promise<StopTransactionResponse>;
public abstract sendMeterValues(connectorId: number, transactionId: number, interval: number, self: OCPPRequestService): Promise<void>;
Expand Down
4 changes: 3 additions & 1 deletion src/types/Connectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ export interface Connector {
bootStatus?: ChargePointStatus;
status?: ChargePointStatus;
MeterValues: SampledValueTemplate[];
authorizeIdTag?: string;
authorized?: boolean;
transactionStarted?: boolean;
transactionId?: number;
transactionSetInterval?: NodeJS.Timeout;
idTag?: string;
transactionIdTag?: string;
energyActiveImportRegisterValue?: number; // In Wh
transactionEnergyActiveImportRegisterValue?: number; // In Wh
transactionBeginMeterValue?: MeterValue;
Expand Down
2 changes: 1 addition & 1 deletion src/types/ocpp/1.6/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export interface IdTagInfo {

export interface AuthorizeRequest {
idTag: string;

}

export interface OCPP16AuthorizeResponse {
idTagInfo: IdTagInfo;
}
Expand Down

0 comments on commit 163547b

Please sign in to comment.