refactored consumption method
MODIFY
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/OCPIMapping.ts
src/server/ocpi/ocpi-services-impl/ocpi-2.1.1/OCPIMapping.ts
@@ -591,9 +591,9 @@ export default class OCPIMapping {
return [];
}
const chargingPeriods: OCPIChargingPeriod[] = [];
- const consumptions = await ConsumptionStorage.getTransactionConsumptions(tenantID, { transactionId: transaction.id });
- if (consumptions) {
- for (const consumption of consumptions) {
+ const consumptions = await ConsumptionStorage.getTransactionConsumptions(tenantID, { transactionId: transaction.id }, Constants.DB_PARAMS_MAX_LIMIT);
+ if (consumptions.result) {
+ for (const consumption of consumptions.result) {
const chargingPeriod = this.buildChargingPeriod(consumption);
if (chargingPeriod && chargingPeriod.dimensions && chargingPeriod.dimensions.length > 0) {
chargingPeriods.push(chargingPeriod);

MODIFY
src/server/ocpp/services/OCPPService.ts
src/server/ocpp/services/OCPPService.ts
@@ -1483,9 +1483,8 @@ export default class OCPPService {
if (this.chargingStationConfig.notifEndOfChargeEnabled &&
((transaction.currentTotalConsumptionWh > 0) && (transaction.currentTotalInactivitySecs >= 300) || transaction.currentStateOfCharge === 100)) {
// Check last 5 consumptions
- let consumptions = await ConsumptionStorage.getTransactionConsumptions(tenantID, { transactionId: transaction.id });
- consumptions = consumptions.slice(-5);
- if (consumptions.every((element) => element.instantAmps === 0)) {
+ const consumptions = await ConsumptionStorage.getTransactionConsumptions(tenantID, { transactionId: transaction.id }, { limit: 5, skip: 0, sort: { startedAt: -1 } });
+ if (consumptions.result.every((element) => element.instantAmps === 0)) {
// Send Notification
await this.notifyEndOfCharge(tenantID, chargingStation, transaction);
}

MODIFY
src/server/rest/service/TransactionService.ts
src/server/rest/service/TransactionService.ts
@@ -389,7 +389,8 @@ export default class TransactionService {
// Get the consumption
let consumptions: Consumption[];
if (filteredRequest.LoadAllConsumptions) {
- consumptions = await ConsumptionStorage.getTransactionConsumptions(req.user.tenantID, { transactionId: transaction.id });
+ const consumptionsMDB = await ConsumptionStorage.getTransactionConsumptions(req.user.tenantID, { transactionId: transaction.id }, Constants.DB_PARAMS_MAX_LIMIT);
+ consumptions = consumptionsMDB.result;
} else {
consumptions = await ConsumptionStorage.getOptimizedTransactionConsumptions(req.user.tenantID, { transactionId: transaction.id });
}

MODIFY
src/storage/mongodb/ConsumptionStorage.ts
src/storage/mongodb/ConsumptionStorage.ts
+import Constants from '../../utils/Constants';
import Consumption from '../../types/Consumption';
import Cypher from '../../utils/Cypher';
+import { DataResult } from '../../types/DataResult';
import DatabaseUtils from './DatabaseUtils';
+import DbParams from '../../types/database/DbParams';
import Logging from '../../utils/Logging';
import Utils from '../../utils/Utils';
import global from '../../types/GlobalType';
@@ -173,11 +176,17 @@ export default class ConsumptionStorage {
return consumptionsMDB;
}
- static async getTransactionConsumptions(tenantID: string, params: { transactionId: number }): Promise<Consumption[]> {
+ static async getTransactionConsumptions(tenantID: string, params: { transactionId: number }, dbParams: DbParams): Promise<DataResult<Consumption>> {
// Debug
const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'getTransactionConsumptions');
// Check
await Utils.checkTenant(tenantID);
+ // Clone before updating the values
+ dbParams = Utils.cloneJSonDocument(dbParams);
+ // Check Limit
+ dbParams.limit = Utils.checkRecordLimit(dbParams.limit);
+ // Check Skip
+ dbParams.skip = Utils.checkRecordSkip(dbParams.skip);
// Create Aggregation
const aggregation = [];
// Filters
@@ -186,13 +195,41 @@ export default class ConsumptionStorage {
transactionId: Utils.convertToInt(params.transactionId)
}
});
+ // Limit records?
+ if (!dbParams.onlyRecordCount) {
+ aggregation.push({ $limit: Constants.DB_RECORD_COUNT_CEIL });
+ }
+ // Count Records
+ const consumptionsCountMDB = await global.database.getCollection<any>(tenantID, 'consumptions')
+ .aggregate([...aggregation, { $count: 'count' }], { allowDiskUse: true })
+ .toArray();
+ // Check if only the total count is requested
+ if (dbParams.onlyRecordCount) {
+ return {
+ count: (consumptionsCountMDB.length > 0 ? consumptionsCountMDB[0].count : 0),
+ result: []
+ };
+ }
+ // Remove the limit
+ aggregation.pop();
// Convert Object ID to string
DatabaseUtils.pushConvertObjectIDToString(aggregation, 'siteAreaID');
DatabaseUtils.pushConvertObjectIDToString(aggregation, 'siteID');
DatabaseUtils.pushConvertObjectIDToString(aggregation, 'userID');
// Sort
+ if (!dbParams.sort) {
+ dbParams.sort = { startedAt: 1 };
+ }
+ aggregation.push({
+ $sort: dbParams.sort
+ });
+ // Skip
+ aggregation.push({
+ $skip: dbParams.skip
+ });
+ // Limit
aggregation.push({
- $sort: { startedAt: 1 }
+ $limit: dbParams.limit
});
// Read DB
const consumptionsMDB = await global.database.getCollection<Consumption>(tenantID, 'consumptions')
@@ -200,7 +237,11 @@ export default class ConsumptionStorage {
.toArray();
// Debug
Logging.traceEnd('ConsumptionStorage', 'getTransactionConsumptions', uniqueTimerID, { transactionId: params.transactionId });
- return consumptionsMDB;
+ return {
+ count: (consumptionsCountMDB.length > 0 ?
+ (consumptionsCountMDB[0].count === Constants.DB_RECORD_COUNT_CEIL ? -1 : consumptionsCountMDB[0].count) : 0),
+ result: consumptionsMDB
+ };
}
static async getLastTransactionConsumption(tenantID: string, params: { transactionId: number }): Promise<Consumption> {

refactored consumption method