Added CS notifcations endpoints + doc + validation
MODIFY
src/assets/server/rest/v1/docs/e-mobility-oas.json
src/assets/server/rest/v1/docs/e-mobility-oas.json
}
}
},
+ "/api/charging-stations/notifications/boot": {
+ "get": {
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ],
+ "description": "Get Charging Stations boot notifications",
+ "tags": [
+ "Charging Stations"
+ ],
+ "responses": {
+ "200": {
+ "description": "Return the boot notification list",
+ "content": {
+ "application/json": {
+ "example": {
+ "count": 1,
+ "result": [
+ {
+ "_id": "####",
+ "chargePointVendor": "####",
+ "chargePointModel": "####",
+ "chargePointSerialNumber": "####",
+ "chargeBoxSerialNumber": "####",
+ "firmwareVersion": "####",
+ "ocppVersion": "####",
+ "endpoint": "####",
+ "timestamp": "2018-01-02T08:21:47.584Z",
+ "chargeBoxID": "####",
+ "__v": 0,
+ "createdBy": null,
+ "lastChangedBy": null
+ }
+ ]
+ }
+ }
+ }
+ },
+ "401": {
+ "$ref": "#/components/responses/UnauthorizedError"
+ },
+ "403": {
+ "$ref": "#/components/responses/ForbiddenError"
+ },
+ "500": {
+ "$ref": "#/components/responses/BackendError"
+ }
+ }
+ }
+ },
+ "/api/charging-stations/notifications/status": {
+ "get": {
+ "security": [
+ {
+ "bearerAuth": []
+ }
+ ],
+ "description": "Get Charging Stations status notifications",
+ "tags": [
+ "Charging Stations"
+ ],
+ "responses": {
+ "200": {
+ "description": "Return the status notification list",
+ "content": {
+ "application/json": {
+ "example": {
+ "count": 1,
+ "result": [
+ {
+ "_id": "####",
+ "chargeBoxID": "####",
+ "connectorId": 2,
+ "timestamp": "2019-03-25T10:45:42.000Z",
+ "status": "####",
+ "errorCode": "####",
+ "info": null,
+ "vendorId": null,
+ "vendorErrorCode": null
+ }
+ ]
+ }
+ }
+ }
+ },
+ "401": {
+ "$ref": "#/components/responses/UnauthorizedError"
+ },
+ "403": {
+ "$ref": "#/components/responses/ForbiddenError"
+ },
+ "500": {
+ "$ref": "#/components/responses/BackendError"
+ }
+ }
+ }
+ },
"/api/charging-profiles": {
"get": {
"security": [

ADD
src/assets/server/rest/v1/schemas/chargingstation/chargingstation-notifications.json
+{
+ "title": "Charging Station notification Request",
+ "type": "object",
+ "properties": {
+ "Limit": {
+ "$ref": "common.json#/definitions/limit"
+ },
+ "SortFields": {
+ "$ref": "common.json#/definitions/sortFields"
+ },
+ "Skip": {
+ "$ref": "common.json#/definitions/skip"
+ }
+ }
+}

MODIFY
src/server/odata/client/CentralServiceApi.ts
src/server/odata/client/CentralServiceApi.ts
import AuthenticatedApi from './AuthenticatedApi';
+import { ServerRoute } from '../../../../src/types/Server';
export default class CentralServiceApi extends AuthenticatedApi {
@@ -57,7 +58,7 @@ export default class CentralServiceApi extends AuthenticatedApi {
async getStatusNotifications(params) {
return await this.send({
method: 'GET',
- url: '/client/api/StatusNotifications',
+ url: `/v1/api/${ServerRoute.REST_CHARGING_STATIONS_STATUS_NOTIFICATIONS}`,
params: params
});
}
@@ -65,7 +66,7 @@ export default class CentralServiceApi extends AuthenticatedApi {
async getBootNotifications(params) {
return await this.send({
method: 'GET',
- url: '/client/api/BootNotifications',
+ url: `/v1/api/${ServerRoute.REST_CHARGING_STATIONS_BOOT_NOTIFICATIONS}`,
params: params
});
}

MODIFY
src/server/odata/odata-schema/ODataSchema.ts
src/server/odata/odata-schema/ODataSchema.ts
@@ -42,7 +42,7 @@ export default class ODataSchema {
}
} catch (error) {
// Add logging: login info
- Logging.logError({
+ await Logging.logError({
tenantID: Constants.DEFAULT_TENANT,
module: MODULE_NAME,
source: 'ODataServer', method: 'getSchema',

MODIFY
src/server/rest/v1/router/api/ChargingStationRouter.ts
src/server/rest/v1/router/api/ChargingStationRouter.ts
@@ -45,6 +45,8 @@ export default class ChargingStationRouter {
this.buildRouteChargingStationLimitPower();
this.buildRouteChargingStationCheckSmartCharging();
this.buildRouteChargingStationTriggerSmartCharging();
+ this.buildRouteChargingStationGetBootNotifications();
+ this.buildRouteChargingStationGetStatusNotifications();
return this.router;
}
@@ -257,4 +259,16 @@ export default class ChargingStationRouter {
await RouterUtils.handleServerAction(ChargingStationService.handleDeleteChargingProfile.bind(this), ServerAction.CHARGING_PROFILE_DELETE, req, res, next);
});
}
+
+ protected buildRouteChargingStationGetBootNotifications(): void {
+ this.router.get(`/${ServerRoute.REST_CHARGING_STATIONS_BOOT_NOTIFICATIONS}`, async (req: Request, res: Response, next: NextFunction) => {
+ await RouterUtils.handleServerAction(ChargingStationService.handleGetBootNotifications.bind(this), ServerAction.BOOT_NOTIFICATION, req, res, next);
+ });
+ }
+
+ protected buildRouteChargingStationGetStatusNotifications(): void {
+ this.router.get(`/${ServerRoute.REST_CHARGING_STATIONS_STATUS_NOTIFICATIONS}`, async (req: Request, res: Response, next: NextFunction) => {
+ await RouterUtils.handleServerAction(ChargingStationService.handleGetStatusNotifications.bind(this), ServerAction.STATUS_NOTIFICATIONS, req, res, next);
+ });
+ }
}

MODIFY
src/server/rest/v1/service/ChargingStationService.ts
src/server/rest/v1/service/ChargingStationService.ts
@@ -1127,10 +1127,10 @@ export default class ChargingStationService {
});
}
// Filter
- const filteredRequest = ChargingStationSecurity.filterNotificationsRequest(req.query);
+ const filteredRequest = ChargingStationValidator.getInstance().validateChargingStationNotificationsGetReq(req.query);
// Get all Status Notifications
const statusNotifications = await OCPPStorage.getStatusNotifications(req.user.tenantID, {},
- { limit: filteredRequest.Limit, skip: filteredRequest.Skip, sort: filteredRequest.SortFields });
+ { limit: filteredRequest.Limit, skip: filteredRequest.Skip, sort: UtilsService.httpSortFieldsToMongoDB(filteredRequest.SortFields) });
// Return
res.json(statusNotifications);
next();
@@ -1147,10 +1147,10 @@ export default class ChargingStationService {
});
}
// Filter
- const filteredRequest = ChargingStationSecurity.filterNotificationsRequest(req.query);
+ const filteredRequest = ChargingStationValidator.getInstance().validateChargingStationNotificationsGetReq(req.query);
// Get all Status Notifications
const bootNotifications = await OCPPStorage.getBootNotifications(req.user.tenantID, {},
- { limit: filteredRequest.Limit, skip: filteredRequest.Skip, sort: filteredRequest.SortFields });
+ { limit: filteredRequest.Limit, skip: filteredRequest.Skip, sort: UtilsService.httpSortFieldsToMongoDB(filteredRequest.SortFields) });
// Return
res.json(bootNotifications);
next();
@@ -1546,9 +1546,7 @@ export default class ChargingStationService {
Utils.replaceSpecialCharsInCSVValueParam(param.value),
ocppParams.siteAreaName,
ocppParams.siteName,
- ].map((value) => {
- return typeof value === 'string' ? '"' + value.replace('"', '""') + '"': value;
- });
+ ].map((value) => typeof value === 'string' ? '"' + value.replace('"', '""') + '"' : value);
return row;
}).join(Constants.CR_LF);
return Utils.isNullOrUndefined(headers) ? Constants.CR_LF + rows : [headers, rows].join(Constants.CR_LF);
@@ -1599,27 +1597,25 @@ export default class ChargingStationService {
i18nManager.formatDateTime(chargingStation.lastReboot, 'L') + ' ' + i18nManager.formatDateTime(chargingStation.lastReboot, 'LT'),
chargingStation.maximumPower,
chargingStation.powerLimitUnit
- ].map((value) => {
- return typeof value === 'string' ? '"' + value.replace('"', '""') + '"': value;
- });
+ ].map((value) => typeof value === 'string' ? '"' + value.replace('"', '""') + '"' : value);
return row;
}).join(Constants.CR_LF);
// Build createdOn cell
const getCreatedOnCell = (chargingStation: ChargingStation, i18nManager: I18nManager) => {
if (chargingStation.createdOn) {
return [i18nManager.formatDateTime(chargingStation.createdOn, 'L') + ' ' + i18nManager.formatDateTime(chargingStation.createdOn, 'LT')];
- } else {
- return [i18nManager.translate('general.invalidDate') + ' ' + i18nManager.translate('general.invalidTime')];
- }
}
+ return [i18nManager.translate('general.invalidDate') + ' ' + i18nManager.translate('general.invalidTime')];
+
+ };
// Build coordinates cell
const getCoordinatesCell = (chargingStation: ChargingStation) => {
if (chargingStation.coordinates && chargingStation.coordinates.length === 2) {
- return [chargingStation.coordinates[1], chargingStation.coordinates[0]]
- } else {
- return ['', '']
- }
+ return [chargingStation.coordinates[1], chargingStation.coordinates[0]];
}
+ return ['', ''];
+
+ };
return Utils.isNullOrUndefined(headers) ? Constants.CR_LF + rows : [headers, rows].join(Constants.CR_LF);
}

MODIFY
src/server/rest/v1/validator/ChargingStationValidator.ts
src/server/rest/v1/validator/ChargingStationValidator.ts
@@ -2,6 +2,7 @@ import { HttpChargingStationCommandRequest, HttpChargingStationConnectorRequest,
import { ChargingProfile } from '../../../../types/ChargingProfile';
import HttpByIDRequest from '../../../../types/requests/HttpByIDRequest';
+import HttpDatabaseRequest from '../../../../types/requests/HttpDatabaseRequest';
import Schema from '../../../../types/validator/Schema';
import SchemaValidator from './SchemaValidator';
import fs from 'fs';
@@ -20,6 +21,7 @@ export default class ChargingStationValidator extends SchemaValidator {
private chargingStationRequestOCPPParameters: Schema;
private chargingStationUpdateParameters: Schema;
private chargingStationLimitPower: Schema;
+ private chargingStationNotificationsGet: Schema;
private constructor() {
@@ -35,6 +37,7 @@ export default class ChargingStationValidator extends SchemaValidator {
this.chargingStationRequestOCPPParameters = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/chargingstation/chargingstation-ocpp-request-parameters.json`, 'utf8'));
this.chargingStationUpdateParameters = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/chargingstation/chargingstation-update-parameters.json`, 'utf8'));
this.chargingStationLimitPower = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/chargingstation/chargingstation-limit-power.json`, 'utf8'));
+ this.chargingStationNotificationsGet = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/chargingstation/chargingstation-notifications.json`, 'utf8'));
}
public static getInstance(): ChargingStationValidator {
@@ -110,4 +113,10 @@ export default class ChargingStationValidator extends SchemaValidator {
this.validate(this.chargingStationLimitPower, data);
return data;
}
+
+ public validateChargingStationNotificationsGetReq(data: any): HttpDatabaseRequest {
+ // Validate schema
+ this.validate(this.chargingStationNotificationsGet, data);
+ return data;
+ }
}

MODIFY
src/types/Server.ts
src/types/Server.ts
@@ -476,6 +476,8 @@ export enum ServerRoute {
REST_CHARGING_STATIONS_TRANSACTIONS = 'charging-stations/:id/transactions',
REST_CHARGING_STATIONS_IN_ERROR = 'charging-stations/status/in-error',
REST_CHARGING_STATIONS_EXPORT = 'charging-stations/action/export',
+ REST_CHARGING_STATIONS_BOOT_NOTIFICATIONS = 'charging-stations/notifications/boot',
+ REST_CHARGING_STATIONS_STATUS_NOTIFICATIONS = 'charging-stations/notifications/status',
REST_CHARGING_STATION_CHECK_SMART_CHARGING_CONNECTION = 'charging-stations/smartcharging/connection/check',
REST_CHARGING_STATION_TRIGGER_SMART_CHARGING = 'charging-stations/smartcharging/trigger',

Added CS notifcations endpoints + doc + validation