From 80c580411036965e34b983809b663b812ed36997 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Tue, 25 Jul 2023 21:27:18 +0200 Subject: [PATCH] feat: warn if charging profile schedule periods are not sorted MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- src/charging-station/ChargingStationUtils.ts | 17 ++++++++++++++++- src/utils/Utils.ts | 9 +++++++++ src/utils/index.ts | 1 + test/utils/Utils.test.ts | 16 ++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/charging-station/ChargingStationUtils.ts b/src/charging-station/ChargingStationUtils.ts index ca4ec0b2..1af12661 100644 --- a/src/charging-station/ChargingStationUtils.ts +++ b/src/charging-station/ChargingStationUtils.ts @@ -49,6 +49,7 @@ import { cloneObject, convertToDate, convertToInt, + isArraySorted, isEmptyObject, isEmptyString, isNotEmptyArray, @@ -739,7 +740,21 @@ const getLimitFromChargingProfiles = ( }) ) { if (isNotEmptyArray(chargingSchedule.chargingSchedulePeriod)) { - chargingSchedule.chargingSchedulePeriod.sort((a, b) => a.startPeriod - b.startPeriod); + const chargingSchedulePeriodCompareFn = ( + a: ChargingSchedulePeriod, + b: ChargingSchedulePeriod, + ) => a.startPeriod - b.startPeriod; + if ( + isArraySorted( + chargingSchedule.chargingSchedulePeriod, + chargingSchedulePeriodCompareFn, + ) === false + ) { + logger.warn( + `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} schedule periods are not sorted by start period`, + ); + chargingSchedule.chargingSchedulePeriod.sort(chargingSchedulePeriodCompareFn); + } // Check if the first schedule period start period is equal to 0 if (chargingSchedule.chargingSchedulePeriod[0].startPeriod !== 0) { logger.error( diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index ff41faf8..14869b0d 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -354,3 +354,12 @@ export const getWebSocketCloseEventStatusString = (code: number): string => { } return '(Unknown)'; }; + +export const isArraySorted = (elements: T[], compareFn: (a: T, b: T) => number): boolean => { + for (let i = 0; i < elements.length - 1; ++i) { + if (compareFn(elements[i], elements[i + 1]) > 0) { + return false; + } + } + return true; +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index cdc98711..86649874 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -39,6 +39,7 @@ export { getRandomFloatRounded, getRandomInteger, getWebSocketCloseEventStatusString, + isArraySorted, isEmptyArray, isEmptyObject, isEmptyString, diff --git a/test/utils/Utils.test.ts b/test/utils/Utils.test.ts index 4677fcda..233ee75d 100644 --- a/test/utils/Utils.test.ts +++ b/test/utils/Utils.test.ts @@ -11,6 +11,7 @@ import { getRandomFloat, getRandomInteger, hasOwnProp, + isArraySorted, isEmptyArray, isEmptyObject, isEmptyString, @@ -365,4 +366,19 @@ describe('Utils test suite', () => { expect(isEmptyObject(new WeakMap())).toBe(false); expect(isEmptyObject(new WeakSet())).toBe(false); }); + + it('Verify isArraySorted()', () => { + expect( + isArraySorted([], (a, b) => { + return a - b; + }), + ).toBe(true); + expect( + isArraySorted([1], (a, b) => { + return a - b; + }), + ).toBe(true); + expect(isArraySorted([1, 2, 3, 4, 5], (a, b) => a - b)).toBe(true); + expect(isArraySorted([1, 2, 3, 5, 4], (a, b) => a - b)).toBe(false); + }); }); -- 2.34.1