Fixed example in getChargingStations + Fixed Charging Station OCPP commands not following the refactored route VERBs + Anonymized examples
MODIFY
src/assets/server/rest/v1/docs/e-mobility-oas.json
src/assets/server/rest/v1/docs/e-mobility-oas.json
"content": {
"application/json": {
"example": {
+ "count": 1,
+ "result": [
+ {
"chargeBoxSerialNumber": "####",
"chargePointModel": "####",
"chargePointSerialNumber": "####",
},
"id": "####"
}
+ ]
+ }
}
}
},
"content": {
"application/json": {
"example": {
- "chargeBoxSerialNumber": "EV.2S22P44R3N164750700100350246E2",
- "chargePointModel": "MONOBLOCK",
- "chargePointSerialNumber": "3N163730715E2S1B7551700014",
- "chargePointVendor": "Schneider Electric",
+ "id": "####",
+ "chargeBoxSerialNumber": "####",
+ "chargePointModel": "####",
+ "chargePointSerialNumber": "####",
+ "chargePointVendor": "####",
"connectors": [
{
"connectorId": 1,
"phaseAssignmentToGrid": null
}
],
- "endpoint": "http://192.168.0.114:8080/",
- "firmwareVersion": "3.3.0.12",
+ "endpoint": "####",
+ "firmwareVersion": "3",
"lastReboot": "2020-12-08T09:06:14.948Z",
"ocppVersion": "1.5",
- "siteAreaID": "5abebb1b4bae1457eb565e98",
- "chargingStationURL": "wss://sap-ev-chargebox-json-server-prod.cfapps.eu10.hana.ondemand.com",
+ "siteAreaID": "####",
+ "chargingStationURL": "wss://####",
"maximumPower": 44160,
"ocppProtocol": "soap",
"powerLimitUnit": "A",
"createdOn": "2019-03-20T07:41:57.583Z",
- "currentIPAddress": "37.71.38.83, 10.0.136.8",
+ "currentIPAddress": "####",
"coordinates": [
- 7.01643370298905,
- 43.6120451027249
+ 7,
+ 43
],
"capabilities": {
"supportStaticLimitation": true,
"supportCreditCard": false,
"supportRFIDCard": false
},
- "ocppStandardParameters": [
- {
- "key": "AllowOfflineTxForUnknownId",
- "value": "true"
- },
- {
- "key": "AuthorizationCacheEnabled",
- "value": "false"
- },
- {
- "key": "StopTransactionOnInvalidId",
- "value": "true"
- }
- ],
- "ocppVendorParameters": [
- {
- "key": "authenticationmanager",
- "value": "2"
- },
- {
- "key": "ocppconnecttimeout",
- "value": "60"
- },
- {
- "key": "clockaligneddatainterval",
- "value": "0"
- },
- {
- "key": "metervaluessampleddata",
- "value": "Energy.Active.Import.Register,Current.Import,Current.Import.L1,Current.Import.L2,Current.Import.L3,Voltage,Voltage.L1,Voltage.L2,Voltage.L3"
- },
- {
- "key": "metervaluesampleinterval",
- "value": "60"
- },
- {
- "key": "emsetting",
- "value": "3"
- },
- {
- "key": "enableevdetection",
- "value": "true"
- },
- {
- "key": "useautotimemanagment",
- "value": "true"
- },
- {
- "key": "timeservername",
- "value": "pool.ntp.org"
- },
- {
- "key": "websocketpinginterval",
- "value": "30"
- }
- ],
"issuer": true,
"chargePoints": [
{
"lastSeen": "2020-12-20T22:34:37.468Z",
"inactive": true,
"siteArea": {
- "name": "Mougins - South",
- "siteID": "5abeba8d4bae1457eb565e5b",
+ "name": "####",
+ "siteID": "####",
"smartCharging": true,
- "id": "5abebb1b4bae1457eb565e98",
+ "id": "####",
"site": {
- "name": "SAP Labs Mougins",
- "id": "5abeba8d4bae1457eb565e5b"
+ "name": "####",
+ "id": "####"
+ }
}
- },
- "id": "65465898"
}
}
}
}
}
},
- "/api/chargingstations/{id}/reset": {
- "get": {
+ "/api/chargingstations/reset": {
+ "post": {
"security": [
{
"bearerAuth": []
}
],
"description": "Reset a Charging Station",
- "parameters": [
- {
- "$ref": "#/components/parameters/chargingStationID"
- },
- {
- "in": "query",
- "name": "type",
- "required": true,
- "description": "Reset type",
+ "requestBody": {
+ "content": {
+ "application/json": {
"schema": {
+ "type": "object",
+ "properties": {
+ "chargeBoxID": {
+ "type": "string",
+ "example": ""
+ },
+ "args": {
+ "type": "object",
+ "properties": {
+ "type": {
"type": "string",
"enum": [
"Soft",
"example": "Soft"
}
}
- ],
+ }
+ }
+ }
+ }
+ }
+ },
"tags": [
"Charging Stations"
],
}
}
},
- "/api/chargingstations/{id}/cache/clear": {
- "get": {
+ "/api/chargingstations/cache/clear": {
+ "post": {
"security": [
{
"bearerAuth": []
}
],
"description": "Clear a Charging Station cache",
- "parameters": [
- {
- "$ref": "#/components/parameters/chargingStationID"
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "chargeBoxID": {
+ "type": "string",
+ "example": ""
}
- ],
+ }
+ }
+ }
+ }
+ },
"tags": [
"Charging Stations"
],
}
}
},
- "/api/chargingstations/{id}/configuration": {
- "get": {
+ "/api/chargingstations/configuration/retrieve": {
+ "post": {
"security": [
{
"bearerAuth": []
}
],
- "description": "Get a Charging Station configuration",
- "parameters": [
- {
- "$ref": "#/components/parameters/chargingStationID"
- },
- {
- "in": "query",
- "name": "key",
- "description": "Configuration key",
+ "description": "Get the Charging Station's configuration",
+ "requestBody": {
+ "content": {
+ "application/json": {
"schema": {
+ "type": "object",
+ "properties": {
+ "chargeBoxID": {
+ "type": "string",
+ "example": ""
+ },
+ "args": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "type": "array",
+ "items": {
"type": "string"
+ },
+ "example": []
}
}
- ],
+ }
+ },
+ "required": ["chargeBoxID"]
+ }
+ }
+ }
+ },
"tags": [
"Charging Stations"
],
"type": "object",
"properties": {
"chargeBoxID": {
- "type": "string"
+ "type": "string",
+ "example": ""
+ },
+ "carID": {
+ "type": "string",
+ "example": ""
},
+ "args": {
+ "type": "object",
+ "properties": {
"connectorId": {
"type": "integer",
"minimum": 1,
}
}
}
+ }
+ }
},
"tags": [
"Charging Stations"
"type": "object",
"properties": {
"chargeBoxID": {
- "type": "string"
+ "type": "string",
+ "example": ""
},
+ "args": {
+ "type": "object",
+ "properties": {
"transactionId": {
- "type": "string"
+ "type": "number"
+ }
+ }
}
}
}
"type": "object",
"properties": {
"chargeBoxID": {
- "type": "string"
+ "type": "string",
+ "example": ""
},
+ "args": {
+ "type": "object",
+ "properties": {
"connectorID": {
"type": "integer",
"minimum": 1,
}
}
}
+ }
+ }
},
"tags": [
"Charging Stations"

MODIFY
src/server/rest/v1/router/api/ChargingStationRouter.ts
src/server/rest/v1/router/api/ChargingStationRouter.ts
@@ -27,7 +27,7 @@ export default class ChargingStationRouter {
this.buildRouteChargingStationDelete();
this.buildRouteChargingStationReset();
this.buildRouteChargingStationClearCache();
- this.buildRouteChargingStationConfiguration();
+ this.buildRouteChargingStationRetrieveConfiguration();
this.buildRouteChargingStationRemoteStart();
this.buildRouteChargingStationRemoteStop();
this.buildRouteChargingStationUnlockConnector();
@@ -65,29 +65,25 @@ export default class ChargingStationRouter {
}
protected buildRouteChargingStationReset(): void {
- this.router.get(`/${ServerRoute.REST_CHARGING_STATIONS_RESET}`, async (req: Request, res: Response, next: NextFunction) => {
- req.query.chargeBoxID = req.params.id;
+ this.router.post(`/${ServerRoute.REST_CHARGING_STATIONS_RESET}`, async (req: Request, res: Response, next: NextFunction) => {
await RouterUtils.handleServerAction(ChargingStationService.handleAction.bind(this), ServerAction.CHARGING_STATION_RESET, req, res, next);
});
}
protected buildRouteChargingStationClearCache(): void {
- this.router.get(`/${ServerRoute.REST_CHARGING_STATIONS_CACHE_CLEAR}`, async (req: Request, res: Response, next: NextFunction) => {
- req.query.chargeBoxID = req.params.id;
+ this.router.post(`/${ServerRoute.REST_CHARGING_STATIONS_CACHE_CLEAR}`, async (req: Request, res: Response, next: NextFunction) => {
await RouterUtils.handleServerAction(ChargingStationService.handleAction.bind(this), ServerAction.CHARGING_STATION_CLEAR_CACHE, req, res, next);
});
}
- protected buildRouteChargingStationConfiguration(): void {
- this.router.get(`/${ServerRoute.REST_CHARGING_STATIONS_CONFIGURATION}`, async (req: Request, res: Response, next: NextFunction) => {
- req.query.chargeBoxID = req.params.id;
+ protected buildRouteChargingStationRetrieveConfiguration(): void {
+ this.router.post(`/${ServerRoute.REST_CHARGING_STATIONS_RETRIEVE_CONFIGURATION}`, async (req: Request, res: Response, next: NextFunction) => {
await RouterUtils.handleServerAction(ChargingStationService.handleAction.bind(this), ServerAction.CHARGING_STATION_GET_CONFIGURATION, req, res, next);
});
}
protected buildRouteChargingStationRemoteStart(): void {
this.router.post(`/${ServerRoute.REST_CHARGING_STATIONS_REMOTE_START}`, async (req: Request, res: Response, next: NextFunction) => {
- req.query.chargeBoxID = req.params.id;
await RouterUtils.handleServerAction(ChargingStationService.handleAction.bind(this), ServerAction.CHARGING_STATION_REMOTE_START_TRANSACTION, req, res, next);
});
}

MODIFY
src/server/rest/v1/service/ChargingStationService.ts
src/server/rest/v1/service/ChargingStationService.ts
@@ -994,8 +994,7 @@ export default class ChargingStationService {
public static async handleAction(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Filter - Type is hacked because code below is. Would need approval to change code structure.
const command = action.slice(15) as Command;
- const filteredRequest: HttpChargingStationCommandRequest =
- ChargingStationSecurity.filterChargingStationActionRequest({ ...req.query, ...req.body });
+ const filteredRequest = ChargingStationSecurity.filterChargingStationActionRequest(req.body);
UtilsService.assertIdIsProvided(action, filteredRequest.chargeBoxID, MODULE_NAME, 'handleAction', req.user);
// Get the Charging station
const chargingStation = await ChargingStationStorage.getChargingStation(req.user.tenantID, filteredRequest.chargeBoxID);
@@ -1023,7 +1022,7 @@ export default class ChargingStationService {
// Add connector ID
filteredRequest.args.connectorId = transaction.connectorId;
// Check Tag ID
- if (!req.user.tagIDs || req.user.tagIDs.length === 0) {
+ if (Utils.isEmptyArray(req.user.tagIDs)) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.USER_NO_BADGE_ERROR,
@@ -1046,7 +1045,7 @@ export default class ChargingStationService {
// Save Transaction
await TransactionStorage.saveTransaction(req.user.tenantID, transaction);
// Ok: Execute it
- result = await this.handleChargingStationCommand(
+ result = await ChargingStationService.handleChargingStationCommand(
req.user.tenantID, req.user, chargingStation, action, command, filteredRequest.args);
// Remote Start Transaction
} else if (command === Command.REMOTE_START_TRANSACTION) {
@@ -1076,7 +1075,7 @@ export default class ChargingStationService {
});
}
// Ok: Execute it
- result = await this.handleChargingStationCommand(
+ result = await ChargingStationService.handleChargingStationCommand(
req.user.tenantID, req.user, chargingStation, action, command, filteredRequest.args);
// Save Car ID
if (Utils.isComponentActiveFromToken(req.user, TenantComponents.CAR)) {

MODIFY
src/server/rest/v1/service/security/ChargingStationSecurity.ts
src/server/rest/v1/service/security/ChargingStationSecurity.ts
@@ -186,8 +186,7 @@ export default class ChargingStationSecurity {
}
public static filterChargingStationActionRequest(request: any): HttpChargingStationCommandRequest {
- const filteredRequest: HttpChargingStationCommandRequest = {} as HttpChargingStationCommandRequest;
- // Check
+ const filteredRequest = {} as HttpChargingStationCommandRequest;
filteredRequest.chargeBoxID = sanitize(request.chargeBoxID);
if (Utils.objectHasProperty(request, 'carID')) {
filteredRequest.carID = sanitize(request.carID);

MODIFY
src/types/Server.ts
src/types/Server.ts
@@ -400,9 +400,9 @@ export enum ServerRoute {
REST_CHARGING_STATIONS = 'chargingstations',
REST_CHARGING_STATION = 'chargingstations/:id',
- REST_CHARGING_STATIONS_RESET = 'chargingstations/:id/reset',
- REST_CHARGING_STATIONS_CACHE_CLEAR = 'chargingstations/:id/cache/clear',
- REST_CHARGING_STATIONS_CONFIGURATION = 'chargingstations/:id/configuration',
+ REST_CHARGING_STATIONS_RESET = 'chargingstations/reset',
+ REST_CHARGING_STATIONS_CACHE_CLEAR = 'chargingstations/cache/clear',
+ REST_CHARGING_STATIONS_RETRIEVE_CONFIGURATION = 'chargingstations/configuration/retrieve',
REST_CHARGING_STATIONS_REMOTE_START = 'chargingstations/remote/start',
REST_CHARGING_STATIONS_REMOTE_STOP = 'chargingstations/remote/stop',
REST_CHARGING_STATIONS_UNLOCK_CONNECTOR = 'chargingstations/connectors/unlock',

Fixed example in getChargingStations + Fixed Charging Station OCPP commands not following the refactored route VERBs + Anonymized examples