Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

smart charging: updated validation to be explicit when conforming profile #838

Merged
merged 5 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions include/ocpp/v201/smart_charging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ class SmartChargingHandlerInterface {
public:
virtual ~SmartChargingHandlerInterface() = default;

virtual SetChargingProfileResponse validate_and_add_profile(
virtual SetChargingProfileResponse conform_validate_and_add_profile(
ChargingProfile& profile, int32_t evse_id,
ChargingLimitSourceEnum charging_limit_source = ChargingLimitSourceEnum::CSO,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) = 0;

virtual void delete_transaction_tx_profiles(const std::string& transaction_id) = 0;

virtual ProfileValidationResultEnum
validate_profile(ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) = 0;
virtual ProfileValidationResultEnum conform_and_validate_profile(
ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) = 0;

virtual SetChargingProfileResponse
add_profile(ChargingProfile& profile, int32_t evse_id,
Expand Down Expand Up @@ -121,7 +121,7 @@ class SmartChargingHandler : public SmartChargingHandlerInterface {
/// \brief validates the given \p profile according to the specification,
/// adding it to our stored list of profiles if valid.
///
SetChargingProfileResponse validate_and_add_profile(
SetChargingProfileResponse conform_validate_and_add_profile(
ChargingProfile& profile, int32_t evse_id,
ChargingLimitSourceEnum charging_limit_source = ChargingLimitSourceEnum::CSO,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) override;
Expand All @@ -131,7 +131,7 @@ class SmartChargingHandler : public SmartChargingHandlerInterface {
/// If a profile does not have validFrom or validTo set, we conform the values
/// to a representation that fits the spec.
///
ProfileValidationResultEnum validate_profile(
ProfileValidationResultEnum conform_and_validate_profile(
ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) override;

Expand Down Expand Up @@ -181,7 +181,7 @@ class SmartChargingHandler : public SmartChargingHandlerInterface {
///
/// \brief validates the given \p profile and associated \p evse_id according to the specification
///
ProfileValidationResultEnum validate_tx_default_profile(ChargingProfile& profile, int32_t evse_id) const;
ProfileValidationResultEnum validate_tx_default_profile(const ChargingProfile& profile, int32_t evse_id) const;

///
/// \brief validates the given \p profile according to the specification
Expand Down Expand Up @@ -216,6 +216,7 @@ class SmartChargingHandler : public SmartChargingHandlerInterface {
std::vector<ChargingProfile> get_evse_specific_tx_default_profiles() const;
std::vector<ChargingProfile> get_station_wide_tx_default_profiles() const;
std::vector<ChargingProfile> get_valid_profiles_for_evse(int32_t evse_id);
void conform_schedule_number_phases(int32_t profile_id, ChargingSchedulePeriod& charging_schedule_period) const;
void conform_validity_periods(ChargingProfile& profile) const;
CurrentPhaseType get_current_phase_type(const std::optional<EvseInterface*> evse_opt) const;
};
Expand Down
6 changes: 3 additions & 3 deletions lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3121,7 +3121,7 @@ void ChargePoint::handle_remote_start_transaction_request(Call<RequestStartTrans

if (charging_profile.chargingProfilePurpose == ChargingProfilePurposeEnum::TxProfile) {

const auto add_profile_response = this->smart_charging_handler->validate_and_add_profile(
const auto add_profile_response = this->smart_charging_handler->conform_validate_and_add_profile(
msg.chargingProfile.value(), evse_id, ChargingLimitSourceEnum::CSO,
AddChargingProfileSource::RequestStartTransactionRequest);
if (add_profile_response.status == ChargingProfileStatusEnum::Accepted) {
Expand Down Expand Up @@ -3367,7 +3367,7 @@ void ChargePoint::handle_set_charging_profile_req(Call<SetChargingProfileRequest
return;
}

response = this->smart_charging_handler->validate_and_add_profile(msg.chargingProfile, msg.evseId);
response = this->smart_charging_handler->conform_validate_and_add_profile(msg.chargingProfile, msg.evseId);
if (response.status == ChargingProfileStatusEnum::Accepted) {
EVLOG_debug << "Accepting SetChargingProfileRequest";
this->callbacks.set_charging_profiles_callback();
Expand Down Expand Up @@ -4416,7 +4416,7 @@ void ChargePoint::clear_invalid_charging_profiles() {
for (const auto& [evse_id, profiles] : evses) {
for (auto profile : profiles) {
try {
if (this->smart_charging_handler->validate_profile(profile, evse_id) !=
if (this->smart_charging_handler->conform_and_validate_profile(profile, evse_id) !=
ProfileValidationResultEnum::Valid) {
this->database_handler->delete_charging_profile(profile.id);
}
Expand Down
53 changes: 39 additions & 14 deletions lib/ocpp/v201/smart_charging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,14 @@ void SmartChargingHandler::delete_transaction_tx_profiles(const std::string& tra
this->database_handler->delete_charging_profile_by_transaction_id(transaction_id);
}

SetChargingProfileResponse SmartChargingHandler::validate_and_add_profile(ChargingProfile& profile, int32_t evse_id,
ChargingLimitSourceEnum charging_limit_source,
AddChargingProfileSource source_of_request) {
SetChargingProfileResponse
SmartChargingHandler::conform_validate_and_add_profile(ChargingProfile& profile, int32_t evse_id,
ChargingLimitSourceEnum charging_limit_source,
AddChargingProfileSource source_of_request) {
SetChargingProfileResponse response;
response.status = ChargingProfileStatusEnum::Rejected;

auto result = this->validate_profile(profile, evse_id, source_of_request);
auto result = this->conform_and_validate_profile(profile, evse_id, source_of_request);
if (result == ProfileValidationResultEnum::Valid) {
response = this->add_profile(profile, evse_id, charging_limit_source);
} else {
Expand All @@ -173,8 +174,9 @@ SetChargingProfileResponse SmartChargingHandler::validate_and_add_profile(Chargi
return response;
}

ProfileValidationResultEnum SmartChargingHandler::validate_profile(ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request) {
ProfileValidationResultEnum
SmartChargingHandler::conform_and_validate_profile(ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request) {

auto result = ProfileValidationResultEnum::Valid;

Expand Down Expand Up @@ -256,7 +258,7 @@ ProfileValidationResultEnum SmartChargingHandler::validate_charging_station_max_
return ProfileValidationResultEnum::Valid;
}

ProfileValidationResultEnum SmartChargingHandler::validate_tx_default_profile(ChargingProfile& profile,
ProfileValidationResultEnum SmartChargingHandler::validate_tx_default_profile(const ChargingProfile& profile,
int32_t evse_id) const {
auto profiles = evse_id == 0 ? get_evse_specific_tx_default_profiles() : get_station_wide_tx_default_profiles();

Expand Down Expand Up @@ -396,10 +398,7 @@ SmartChargingHandler::validate_profile_schedules(ChargingProfile& profile,
return ProfileValidationResultEnum::ChargingSchedulePeriodUnsupportedNumberPhases;
}

// K01.FR.49
if (!charging_schedule_period.numberPhases.has_value()) {
charging_schedule_period.numberPhases.emplace(DEFAULT_AND_MAX_NUMBER_PHASES);
}
conform_schedule_number_phases(profile.id, charging_schedule_period);
}
}

Expand Down Expand Up @@ -465,7 +464,7 @@ std::vector<ChargingProfile> SmartChargingHandler::get_valid_profiles_for_evse(i

auto evse_profiles = this->database_handler->get_charging_profiles_for_evse(evse_id);
for (auto profile : evse_profiles) {
if (this->validate_profile(profile, evse_id) == ProfileValidationResultEnum::Valid) {
if (this->conform_and_validate_profile(profile, evse_id) == ProfileValidationResultEnum::Valid) {
valid_profiles.push_back(profile);
}
}
Expand Down Expand Up @@ -538,9 +537,35 @@ bool SmartChargingHandler::is_overlapping_validity_period(const ChargingProfile&
return false;
}

/// \brief sets attributes of the given \p charging_schedule_period according to the specification.
/// 2.11. ChargingSchedulePeriodType if absent numberPhases set to 3
void SmartChargingHandler::conform_schedule_number_phases(int32_t profileId,
ChargingSchedulePeriod& charging_schedule_period) const {
// K01.FR.49
if (!charging_schedule_period.numberPhases.has_value()) {
EVLOG_debug << "Conforming profile: " << profileId << " added number phase as "
<< DEFAULT_AND_MAX_NUMBER_PHASES;
charging_schedule_period.numberPhases.emplace(DEFAULT_AND_MAX_NUMBER_PHASES);
}
}

///
/// \brief sets attributes of the given \p profile according to the specification.
/// 2.10. ChargingProfileType validFrom if absent set to current date
/// 2.10. ChargingProfileType validTo if absent set to max date
///
void SmartChargingHandler::conform_validity_periods(ChargingProfile& profile) const {
profile.validFrom = profile.validFrom.value_or(ocpp::DateTime());
profile.validTo = profile.validTo.value_or(ocpp::DateTime(date::utc_clock::time_point::max()));
if (!profile.validFrom.has_value()) {
auto validFrom = ocpp::DateTime();
EVLOG_debug << "Conforming profile: " << profile.id << " added validFrom as " << validFrom;
profile.validFrom = validFrom;
}

if (!profile.validTo.has_value()) {
auto validTo = ocpp::DateTime(date::utc_clock::time_point::max());
EVLOG_debug << "Conforming profile: " << profile.id << " added validTo as " << validTo;
profile.validTo = validTo;
}
}

ProfileValidationResultEnum
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/ocpp/v201/mocks/smart_charging_handler_mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
namespace ocpp::v201 {
class SmartChargingHandlerMock : public SmartChargingHandlerInterface {
public:
MOCK_METHOD(SetChargingProfileResponse, validate_and_add_profile,
MOCK_METHOD(SetChargingProfileResponse, conform_validate_and_add_profile,
(ChargingProfile & profile, int32_t evse_id, ChargingLimitSourceEnum charging_limit_source,
AddChargingProfileSource source_of_request));
MOCK_METHOD(ProfileValidationResultEnum, validate_profile,
MOCK_METHOD(ProfileValidationResultEnum, conform_and_validate_profile,
(ChargingProfile & profile, int32_t evse_id, AddChargingProfileSource source_of_request));
MOCK_METHOD(void, delete_transaction_tx_profiles, (const std::string& transaction_id));
MOCK_METHOD(SetChargingProfileResponse, add_profile,
Expand Down
18 changes: 9 additions & 9 deletions tests/lib/ocpp/v201/test_charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,8 +666,8 @@ TEST_F(ChargePointFunctionalityTestFixtureV201, K01_SetChargingProfileRequest_Va
request_to_enhanced_message<SetChargingProfileRequest, MessageType::SetChargingProfile>(req);

EXPECT_CALL(*smart_charging_handler,
validate_and_add_profile(profile, DEFAULT_EVSE_ID, ChargingLimitSourceEnum::CSO,
DEFAULT_REQUEST_TO_ADD_PROFILE_SOURCE));
conform_validate_and_add_profile(profile, DEFAULT_EVSE_ID, ChargingLimitSourceEnum::CSO,
DEFAULT_REQUEST_TO_ADD_PROFILE_SOURCE));

charge_point->handle_message(set_charging_profile_req);
}
Expand All @@ -689,7 +689,7 @@ TEST_F(ChargePointFunctionalityTestFixtureV201, K01FR07_SetChargingProfileReques
SetChargingProfileResponse accept_response;
accept_response.status = ChargingProfileStatusEnum::Accepted;

ON_CALL(*smart_charging_handler, validate_and_add_profile).WillByDefault(testing::Return(accept_response));
ON_CALL(*smart_charging_handler, conform_validate_and_add_profile).WillByDefault(testing::Return(accept_response));
EXPECT_CALL(set_charging_profiles_callback_mock, Call);

charge_point->handle_message(set_charging_profile_req);
Expand Down Expand Up @@ -717,7 +717,7 @@ TEST_F(ChargePointFunctionalityTestFixtureV201, K01FR07_SetChargingProfileReques
reject_response.statusInfo->additionalInfo = conversions::profile_validation_result_to_string(
ProfileValidationResultEnum::TxProfileEvseHasNoActiveTransaction);

ON_CALL(*smart_charging_handler, validate_and_add_profile).WillByDefault(testing::Return(reject_response));
ON_CALL(*smart_charging_handler, conform_validate_and_add_profile).WillByDefault(testing::Return(reject_response));
EXPECT_CALL(set_charging_profiles_callback_mock, Call).Times(0);

charge_point->handle_message(set_charging_profile_req);
Expand All @@ -738,7 +738,7 @@ TEST_F(ChargePointFunctionalityTestFixtureV201,
auto set_charging_profile_req =
request_to_enhanced_message<SetChargingProfileRequest, MessageType::SetChargingProfile>(req);

EXPECT_CALL(*smart_charging_handler, validate_and_add_profile).Times(0);
EXPECT_CALL(*smart_charging_handler, conform_validate_and_add_profile).Times(0);
EXPECT_CALL(set_charging_profiles_callback_mock, Call).Times(0);

charge_point->handle_message(set_charging_profile_req);
Expand All @@ -765,7 +765,7 @@ TEST_F(ChargePointFunctionalityTestFixtureV201, K01FR29_SmartChargingCtrlrAvaila
auto set_charging_profile_req =
request_to_enhanced_message<SetChargingProfileRequest, MessageType::SetChargingProfile>(req);

EXPECT_CALL(*smart_charging_handler, validate_and_add_profile).Times(0);
EXPECT_CALL(*smart_charging_handler, conform_validate_and_add_profile).Times(0);

charge_point->handle_message(set_charging_profile_req);
}
Expand All @@ -789,7 +789,7 @@ TEST_F(ChargePointFunctionalityTestFixtureV201,
auto start_transaction_req =
request_to_enhanced_message<RequestStartTransactionRequest, MessageType::RequestStartTransaction>(req);

EXPECT_CALL(*smart_charging_handler, validate_and_add_profile).Times(1);
EXPECT_CALL(*smart_charging_handler, conform_validate_and_add_profile).Times(1);

charge_point->handle_message(start_transaction_req);
}
Expand All @@ -815,7 +815,7 @@ TEST_F(ChargePointFunctionalityTestFixtureV201, K01FR29_SmartChargingCtrlrAvaila
auto set_charging_profile_req =
request_to_enhanced_message<SetChargingProfileRequest, MessageType::SetChargingProfile>(req);

EXPECT_CALL(*smart_charging_handler, validate_and_add_profile).Times(1);
EXPECT_CALL(*smart_charging_handler, conform_validate_and_add_profile).Times(1);

charge_point->handle_message(set_charging_profile_req);
}
Expand Down Expand Up @@ -915,7 +915,7 @@ TEST_F(ChargePointFunctionalityTestFixtureV201,
auto start_transaction_req =
request_to_enhanced_message<RequestStartTransactionRequest, MessageType::RequestStartTransaction>(req);

EXPECT_CALL(*smart_charging_handler, validate_and_add_profile).Times(0);
EXPECT_CALL(*smart_charging_handler, conform_validate_and_add_profile).Times(0);

charge_point->handle_message(start_transaction_req);
}
Expand Down
6 changes: 4 additions & 2 deletions tests/lib/ocpp/v201/test_composite_schedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,8 +690,10 @@ TEST_F(CompositeScheduleTestFixtureV201, K08_CalculateCompositeSchedule_DemoCase
CompositeSchedule actual =
handler.calculate_composite_schedule(profiles, start_time, end_time, DEFAULT_EVSE_ID, ChargingRateUnitEnum::W);

ASSERT_EQ(ProfileValidationResultEnum::Valid, handler.validate_profile(profiles.at(0), DEFAULT_EVSE_ID));
ASSERT_EQ(ProfileValidationResultEnum::Valid, handler.validate_profile(profiles.at(1), DEFAULT_EVSE_ID));
ASSERT_EQ(ProfileValidationResultEnum::Valid,
handler.conform_and_validate_profile(profiles.at(0), DEFAULT_EVSE_ID));
ASSERT_EQ(ProfileValidationResultEnum::Valid,
handler.conform_and_validate_profile(profiles.at(1), DEFAULT_EVSE_ID));
ASSERT_EQ(actual, expected);
}

Expand Down
Loading
Loading