From 1d6dcb60374cc7c0665faacef6b437cf2723f8a1 Mon Sep 17 00:00:00 2001 From: Coury Richards <146002925+couryrr-afs@users.noreply.github.com> Date: Thu, 29 Feb 2024 14:52:11 -0500 Subject: [PATCH] Implemented K01.FR19 Signed-off-by: Coury Richards <146002925+couryrr-afs@users.noreply.github.com> --- include/ocpp/v201/smart_charging.hpp | 1 + lib/ocpp/v201/smart_charging.cpp | 29 +++++++++++-------- .../ocpp/v201/test_smart_charging_handler.cpp | 24 +++++++++++++++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/include/ocpp/v201/smart_charging.hpp b/include/ocpp/v201/smart_charging.hpp index e42f1b6ead..557bb9d9f9 100644 --- a/include/ocpp/v201/smart_charging.hpp +++ b/include/ocpp/v201/smart_charging.hpp @@ -28,6 +28,7 @@ enum class ProfileValidationResultEnum { ChargingProfileMissingRequiredStartSchedule, ChargingProfileExtraneousStartSchedule, ChargingSchedulePeriodsOutOfOrder, + ChargingSchedulePeriodInvalidPhaseToUse, }; /// \brief This class handles and maintains incoming ChargingProfiles and contains the logic diff --git a/lib/ocpp/v201/smart_charging.cpp b/lib/ocpp/v201/smart_charging.cpp index aa3df34776..c22a5dc6b2 100644 --- a/lib/ocpp/v201/smart_charging.cpp +++ b/lib/ocpp/v201/smart_charging.cpp @@ -56,26 +56,31 @@ ProfileValidationResultEnum SmartChargingHandler::validate_profile_schedules(con } // K01.FR.31 - auto first_start_period = schedule.chargingSchedulePeriod[0].startPeriod; - if (first_start_period != 0) { - return ProfileValidationResultEnum::ChargingProfileFirstStartScheduleIsNotZero; - } + auto charging_schedule_period = schedule.chargingSchedulePeriod[0]; // K01.FR.35 - // We start at one since we have the first startPeriod at this point. - for (auto i = 1; i < schedule.chargingSchedulePeriod.size(); i++) { - auto next_start_period = schedule.chargingSchedulePeriod[i].startPeriod; - if (next_start_period <= first_start_period) { - return ProfileValidationResultEnum::ChargingSchedulePeriodsOutOfOrder; - } else { - first_start_period = next_start_period; + for (auto i = 0; i < schedule.chargingSchedulePeriod.size(); i++) { + // K01.FR.19 + if (charging_schedule_period.numberPhases != 1 && charging_schedule_period.phaseToUse.has_value()){ + return ProfileValidationResultEnum::ChargingSchedulePeriodInvalidPhaseToUse; + } + + if (i == 0 && charging_schedule_period.startPeriod != 0) { + return ProfileValidationResultEnum::ChargingProfileFirstStartScheduleIsNotZero; + } else if (i != 0) { + auto next_charging_schedule_period = schedule.chargingSchedulePeriod[i]; + if (next_charging_schedule_period.startPeriod <= charging_schedule_period.startPeriod) { + return ProfileValidationResultEnum::ChargingSchedulePeriodsOutOfOrder; + } else { + charging_schedule_period = next_charging_schedule_period; + } } } // K01.FR.40 if (profile.chargingProfileKind != ChargingProfileKindEnum::Relative && !schedule.startSchedule.has_value()) { return ProfileValidationResultEnum::ChargingProfileMissingRequiredStartSchedule; - // K01.FR.41 + // K01.FR.41 } else if (profile.chargingProfileKind == ChargingProfileKindEnum::Relative && schedule.startSchedule.has_value()) { return ProfileValidationResultEnum::ChargingProfileExtraneousStartSchedule; diff --git a/tests/lib/ocpp/v201/test_smart_charging_handler.cpp b/tests/lib/ocpp/v201/test_smart_charging_handler.cpp index ef05e3a47b..2a14913f8c 100644 --- a/tests/lib/ocpp/v201/test_smart_charging_handler.cpp +++ b/tests/lib/ocpp/v201/test_smart_charging_handler.cpp @@ -90,6 +90,17 @@ class ChargepointTestFixtureV201 : public testing::Test { return charging_schedule_periods; } + std::vector create_charging_schedule_periods_with_phases(int32_t start_period, int32_t numberPhases, int32_t phaseToUse) { + auto charging_schedule_period = ChargingSchedulePeriod{ + .startPeriod = start_period, + .numberPhases = numberPhases, + .phaseToUse = phaseToUse + }; + + return {charging_schedule_period}; + } + + ChargingProfile create_tx_profile(ChargingSchedule charging_schedule, std::string transaction_id, int stack_level = 1, ChargingProfileKindEnum charging_profile_kind = ChargingProfileKindEnum::Absolute) { @@ -273,6 +284,18 @@ TEST_F(ChargepointTestFixtureV201, EXPECT_THAT(sut, testing::Eq(ProfileValidationResultEnum::Valid)); } +TEST_F(ChargepointTestFixtureV201, + K01FR19_NumberPhasesOtherThan1AndPhaseToUseSet_ThenProfileInvalid) { + auto periods = create_charging_schedule_periods_with_phases(0, 0, 1); + auto profile = create_tx_profile( + create_charge_schedule(ChargingRateUnitEnum::A, periods, ocpp::DateTime("2024-01-17T17:00:00")), uuid(), 1, + ChargingProfileKindEnum::Relative); + + auto sut = handler.validate_profile_schedules(profile); + + EXPECT_THAT(sut, testing::Eq(ProfileValidationResultEnum::ChargingSchedulePeriodInvalidPhaseToUse)); +} + TEST_F(ChargepointTestFixtureV201, K01_IfChargingSchedulePeriodsAreMissing_ThenProfileIsInvalid) { auto profile = create_tx_profile(create_charge_schedule(ChargingRateUnitEnum::A), uuid()); @@ -333,4 +356,5 @@ TEST_F(ChargepointTestFixtureV201, EXPECT_THAT(sut, testing::Eq(ProfileValidationResultEnum::ChargingProfileExtraneousStartSchedule)); } + } // namespace ocpp::v201