diff --git a/include/ocpp/v201/smart_charging.hpp b/include/ocpp/v201/smart_charging.hpp index d37eb0b2a..c573dfa3e 100644 --- a/include/ocpp/v201/smart_charging.hpp +++ b/include/ocpp/v201/smart_charging.hpp @@ -46,7 +46,8 @@ enum class ProfileValidationResultEnum { ChargingStationMaxProfileEvseIdGreaterThanZero, DuplicateTxDefaultProfileFound, DuplicateProfileValidityPeriod, - RequestStartTransactionNonTxProfile + RequestStartTransactionNonTxProfile, + ChargingProfileEmptyChargingSchedules }; /// \brief This is used to associate charging profiles with a source. diff --git a/lib/ocpp/v201/smart_charging.cpp b/lib/ocpp/v201/smart_charging.cpp index 29201b71f..2148ca73a 100644 --- a/lib/ocpp/v201/smart_charging.cpp +++ b/lib/ocpp/v201/smart_charging.cpp @@ -76,6 +76,8 @@ std::string profile_validation_result_to_string(ProfileValidationResultEnum e) { return "DuplicateProfileValidityPeriod"; case ProfileValidationResultEnum::RequestStartTransactionNonTxProfile: return "RequestStartTransactionNonTxProfile"; + case ProfileValidationResultEnum::ChargingProfileEmptyChargingSchedules: + return "ChargingProfileEmptyChargingSchedules"; } throw EnumToStringException{e, "ProfileValidationResultEnum"}; @@ -105,6 +107,7 @@ std::string profile_validation_result_to_reason_code(ProfileValidationResultEnum case ProfileValidationResultEnum::ChargingSchedulePeriodUnsupportedNumberPhases: case ProfileValidationResultEnum::ChargingSchedulePeriodExtraneousPhaseValues: case ProfileValidationResultEnum::ChargingSchedulePeriodPhaseToUseACPhaseSwitchingUnsupported: + case ProfileValidationResultEnum::ChargingProfileEmptyChargingSchedules: return "InvalidSchedule"; case ProfileValidationResultEnum::TxProfileMissingTransactionId: return "MissingParam"; @@ -338,6 +341,11 @@ SmartChargingHandler::validate_tx_profile(const ChargingProfile& profile, int32_ ProfileValidationResultEnum SmartChargingHandler::validate_profile_schedules(ChargingProfile& profile, std::optional evse_opt) const { + + if (profile.chargingSchedule.empty()) { + return ProfileValidationResultEnum::ChargingProfileEmptyChargingSchedules; + } + auto charging_station_supply_phases = this->device_model->get_value(ControllerComponentVariables::ChargingStationSupplyPhases); diff --git a/tests/lib/ocpp/v201/test_smart_charging_handler.cpp b/tests/lib/ocpp/v201/test_smart_charging_handler.cpp index 065eb8761..86af5d1c0 100644 --- a/tests/lib/ocpp/v201/test_smart_charging_handler.cpp +++ b/tests/lib/ocpp/v201/test_smart_charging_handler.cpp @@ -146,12 +146,12 @@ class SmartChargingHandlerTestFixtureV201 : public DatabaseTestingUtils { ChargingProfile create_charging_profile(int32_t charging_profile_id, ChargingProfilePurposeEnum charging_profile_purpose, - ChargingSchedule charging_schedule, std::optional transaction_id = {}, + std::vector charging_schedules, + std::optional transaction_id = {}, ChargingProfileKindEnum charging_profile_kind = ChargingProfileKindEnum::Absolute, int stack_level = DEFAULT_STACK_LEVEL, std::optional validFrom = {}, std::optional validTo = {}) { auto recurrency_kind = RecurrencyKindEnum::Daily; - std::vector charging_schedules = {charging_schedule}; ChargingProfile charging_profile; charging_profile.id = charging_profile_id; charging_profile.stackLevel = stack_level; @@ -166,6 +166,17 @@ class SmartChargingHandlerTestFixtureV201 : public DatabaseTestingUtils { return charging_profile; } + ChargingProfile + create_charging_profile(int32_t charging_profile_id, ChargingProfilePurposeEnum charging_profile_purpose, + ChargingSchedule charging_schedule, std::optional transaction_id = {}, + ChargingProfileKindEnum charging_profile_kind = ChargingProfileKindEnum::Absolute, + int stack_level = DEFAULT_STACK_LEVEL, std::optional validFrom = {}, + std::optional validTo = {}) { + return create_charging_profile(charging_profile_id, charging_profile_purpose, + std::vector{charging_schedule}, transaction_id, + charging_profile_kind, stack_level, validFrom, validTo); + } + ChargingProfileCriterion create_charging_profile_criteria( std::optional> sources = std::nullopt, std::optional> ids = std::nullopt, @@ -1747,4 +1758,12 @@ TEST_F(SmartChargingHandlerTestFixtureV201, K01_ValidateTxProfile_AllowsExisting EXPECT_THAT(sut, testing::Eq(ProfileValidationResultEnum::Valid)); } +TEST_F(SmartChargingHandlerTestFixtureV201, K01_ValidateTxProfile_EmptyChargingSchedule) { + auto profile = create_charging_profile(DEFAULT_PROFILE_ID, ChargingProfilePurposeEnum::ChargingStationMaxProfile, + std::vector{}, ocpp::DateTime("2024-01-17T17:00:00")); + + auto sut = handler.conform_and_validate_profile(profile, DEFAULT_EVSE_ID); + ASSERT_THAT(sut, testing::Eq(ProfileValidationResultEnum::ChargingProfileEmptyChargingSchedules)); +} + } // namespace ocpp::v201