}
},
"@eslint/eslintrc": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz",
- "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==",
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz",
+ "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
"ignore": "^4.0.6",
"import-fresh": "^3.2.1",
"js-yaml": "^3.13.1",
- "lodash": "^4.17.19",
+ "lodash": "^4.17.20",
"minimatch": "^3.0.4",
"strip-json-comments": "^3.1.1"
},
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ },
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"dev": true
},
"bufferutil": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.2.tgz",
- "integrity": "sha512-AtnG3W6M8B2n4xDQ5R+70EXvOpnXsFYg/AK2yTZd+HQ/oxAdz+GI+DvjmhBw3L0ole+LJ0ngqY4JMbDzkfNzhA==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz",
+ "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==",
"optional": true,
"requires": {
"node-gyp-build": "^4.2.0"
}
},
"eslint": {
- "version": "7.17.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.17.0.tgz",
- "integrity": "sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ==",
+ "version": "7.18.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz",
+ "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
- "@eslint/eslintrc": "^0.2.2",
+ "@eslint/eslintrc": "^0.3.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
- "lodash": "^4.17.19",
+ "lodash": "^4.17.20",
"minimatch": "^3.0.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
"type-check": "~0.4.0"
}
},
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
+ "dev": true
+ },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"dev": true
},
"utf-8-validate": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.3.tgz",
- "integrity": "sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A==",
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz",
+ "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==",
"optional": true,
"requires": {
"node-gyp-build": "^4.2.0"
"ws": "^7.4.2"
},
"optionalDependencies": {
- "bufferutil": "^4.0.2",
- "utf-8-validate": "^5.0.3"
+ "bufferutil": "^4.0.3",
+ "utf-8-validate": "^5.0.4"
},
"devDependencies": {
"@types/node": "^14.14.21",
"@typescript-eslint/parser": "^4.13.0",
"clinic": "^8.0.1",
"cross-env": "^7.0.3",
- "eslint": "^7.17.0",
+ "eslint": "^7.18.0",
"grunt": "^1.3.0",
"grunt-ts": "^6.0.0-beta.22",
"mbt": "^1.1.0",
async startConnector(connectorId: number): Promise<void> {
do {
+ if (this._timeToStop) {
+ logger.error(this._logPrefix(connectorId) + ' Entered in transaction loop while a request to stop it was made');
+ break;
+ }
+ if (!this._chargingStation._isRegistered()) {
+ logger.error(this._logPrefix(connectorId) + ' Entered in transaction loop while the charging station is not registered');
+ break;
+ }
+ if (!this._chargingStation._isChargingStationAvailable() || !this._chargingStation._isConnectorAvailable(connectorId)) {
+ logger.error(this._logPrefix(connectorId) + ' Entered in transaction loop while the charging station or connector is unavailable');
+ break;
+ }
const wait = Utils.getRandomInt(this._chargingStation.stationInfo.AutomaticTransactionGenerator.maxDelayBetweenTwoTransactions,
this._chargingStation.stationInfo.AutomaticTransactionGenerator.minDelayBetweenTwoTransactions) * 1000;
logger.info(this._logPrefix(connectorId) + ' wait for ' + Utils.milliSecondsToHHMMSS(wait));
await Utils.sleep(wait);
- if (this._timeToStop) {
- logger.debug(this._logPrefix(connectorId) + ' Entered in transaction loop while a request to stop it was made');
- break;
- }
const start = Math.random();
let skip = 0;
if (start < this._chargingStation.stationInfo.AutomaticTransactionGenerator.probabilityOfStart) {
}
// eslint-disable-next-line consistent-this
- async startTransaction(connectorId: number, self: AutomaticTransactionGenerator): Promise<StartTransactionResponse> {
+ private async startTransaction(connectorId: number, self: AutomaticTransactionGenerator): Promise<StartTransactionResponse> {
if (self._chargingStation.hasAuthorizedTags()) {
const tagId = self._chargingStation.getRandomTagId();
logger.info(self._logPrefix(connectorId) + ' start transaction for tagID ' + tagId);
}
// eslint-disable-next-line consistent-this
- async stopTransaction(connectorId: number, self: AutomaticTransactionGenerator): Promise<StopTransactionResponse> {
+ private async stopTransaction(connectorId: number, self: AutomaticTransactionGenerator): Promise<StopTransactionResponse> {
return await self._chargingStation.sendStopTransaction(self._chargingStation.getConnector(connectorId).transactionId);
}
}
return this.getConnector(id).availability === AvailabilityType.OPERATIVE;
}
+ _isChargingStationAvailable(): boolean {
+ return this.getConnector(0).availability === AvailabilityType.OPERATIVE;
+ }
+
_getTemplateMaxNumberOfConnectors(): number {
return Object.keys(this._stationInfo.Connectors).length;
}
return;
}
if (payload.idTagInfo?.status === AuthorizationStatus.ACCEPTED) {
- await this.sendStatusNotification(transactionConnectorId, ChargePointStatus.AVAILABLE);
+ if (!this._isChargingStationAvailable() || !this._isConnectorAvailable(transactionConnectorId)) {
+ await this.sendStatusNotification(transactionConnectorId, ChargePointStatus.UNAVAILABLE);
+ } else {
+ await this.sendStatusNotification(transactionConnectorId, ChargePointStatus.AVAILABLE);
+ }
if (this._stationInfo.powerSharedByConnectors) {
this._stationInfo.powerDivider--;
}
return Constants.OCPP_CHARGING_PROFILE_RESPONSE_ACCEPTED;
}
- // FIXME: Handle properly the transaction started case
handleRequestChangeAvailability(commandPayload: ChangeAvailabilityRequest): ChangeAvailabilityResponse {
const connectorId: number = commandPayload.connectorId;
if (!this.getConnector(connectorId)) {
response = Constants.OCPP_AVAILABILITY_RESPONSE_SCHEDULED;
}
this.getConnector(Utils.convertToInt(connector)).availability = commandPayload.type;
- void this.sendStatusNotification(Utils.convertToInt(connector), chargePointStatus);
+ response === Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED && this.sendStatusNotification(Utils.convertToInt(connector), chargePointStatus);
}
return response;
} else if (connectorId > 0 && (this.getConnector(0).availability === AvailabilityType.OPERATIVE || (this.getConnector(0).availability === AvailabilityType.INOPERATIVE && commandPayload.type === AvailabilityType.INOPERATIVE))) {
if (this.getConnector(connectorId)?.transactionStarted) {
this.getConnector(connectorId).availability = commandPayload.type;
- void this.sendStatusNotification(connectorId, chargePointStatus);
return Constants.OCPP_AVAILABILITY_RESPONSE_SCHEDULED;
}
this.getConnector(connectorId).availability = commandPayload.type;
async handleRequestRemoteStartTransaction(commandPayload: RemoteStartTransactionRequest): Promise<DefaultResponse> {
const transactionConnectorID: number = commandPayload.connectorId ? commandPayload.connectorId : 1;
- if (this._getAuthorizeRemoteTxRequests() && this._getLocalAuthListEnabled() && this.hasAuthorizedTags()) {
- // Check if authorized
- if (this._authorizedTags.find((value) => value === commandPayload.idTag)) {
- await this.sendStatusNotification(transactionConnectorID, ChargePointStatus.PREPARING);
- // Authorization successful start transaction
- await this.sendStartTransaction(transactionConnectorID, commandPayload.idTag);
- logger.debug(this._logPrefix() + ' Transaction remotely STARTED on ' + this._stationInfo.name + '#' + transactionConnectorID.toString() + ' for idTag ' + commandPayload.idTag);
- return Constants.OCPP_RESPONSE_ACCEPTED;
+ if (this._isChargingStationAvailable() && this._isConnectorAvailable(transactionConnectorID)) {
+ if (this._getAuthorizeRemoteTxRequests() && this._getLocalAuthListEnabled() && this.hasAuthorizedTags()) {
+ // Check if authorized
+ if (this._authorizedTags.find((value) => value === commandPayload.idTag)) {
+ await this.sendStatusNotification(transactionConnectorID, ChargePointStatus.PREPARING);
+ // Authorization successful start transaction
+ await this.sendStartTransaction(transactionConnectorID, commandPayload.idTag);
+ logger.debug(this._logPrefix() + ' Transaction remotely STARTED on ' + this._stationInfo.name + '#' + transactionConnectorID.toString() + ' for idTag ' + commandPayload.idTag);
+ return Constants.OCPP_RESPONSE_ACCEPTED;
+ }
+ logger.error(this._logPrefix() + ' Remote starting transaction REJECTED on connector Id ' + transactionConnectorID.toString() + ', idTag ' + commandPayload.idTag);
+ return Constants.OCPP_RESPONSE_REJECTED;
}
- logger.error(this._logPrefix() + ' Remote starting transaction REJECTED, idTag ' + commandPayload.idTag);
- return Constants.OCPP_RESPONSE_REJECTED;
+ await this.sendStatusNotification(transactionConnectorID, ChargePointStatus.PREPARING);
+ // No local authorization check required => start transaction
+ await this.sendStartTransaction(transactionConnectorID, commandPayload.idTag);
+ logger.debug(this._logPrefix() + ' Transaction remotely STARTED on ' + this._stationInfo.name + '#' + transactionConnectorID.toString() + ' for idTag ' + commandPayload.idTag);
+ return Constants.OCPP_RESPONSE_ACCEPTED;
}
- await this.sendStatusNotification(transactionConnectorID, ChargePointStatus.PREPARING);
- // No local authorization check required => start transaction
- await this.sendStartTransaction(transactionConnectorID, commandPayload.idTag);
- logger.debug(this._logPrefix() + ' Transaction remotely STARTED on ' + this._stationInfo.name + '#' + transactionConnectorID.toString() + ' for idTag ' + commandPayload.idTag);
- return Constants.OCPP_RESPONSE_ACCEPTED;
+ logger.error(this._logPrefix() + ' Remote starting transaction REJECTED on unavailable connector Id ' + transactionConnectorID.toString() + ', idTag ' + commandPayload.idTag);
+ return Constants.OCPP_RESPONSE_REJECTED;
}
async handleRequestRemoteStopTransaction(commandPayload: RemoteStopTransactionRequest): Promise<DefaultResponse> {
}
}
if (!Utils.isUndefined(WebSocketCloseEventStatusString[code])) {
- return WebSocketCloseEventStatusString[code];
+ return WebSocketCloseEventStatusString[code] as string;
}
return '(Unknown)';
}