Skip to content

Commit

Permalink
smart_charging: Handle profile updates per K01.FR.05
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher Davis <[email protected]>
  • Loading branch information
christopher-davis-afs committed Apr 29, 2024
1 parent 8d32ed5 commit bd51be3
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 6 deletions.
2 changes: 1 addition & 1 deletion doc/ocpp_201_status.md
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,7 @@ This document contains the status of which OCPP 2.0.1 numbered requirements have
| K01.FR.02 | | |
| K01.FR.03 | | |
| K01.FR.04 | :white_check_mark: | |
| K01.FR.05 | | |
| K01.FR.05 | :white_check_mark: | |
| K01.FR.06 | | |
| K01.FR.07 | | |
| K01.FR.08 | | |
Expand Down
20 changes: 15 additions & 5 deletions lib/ocpp/v201/smart_charging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "ocpp/common/types.hpp"
#include "ocpp/v201/enums.hpp"
#include "ocpp/v201/evse.hpp"
#include "ocpp/v201/messages/SetChargingProfile.hpp"
#include "ocpp/v201/ocpp_types.hpp"
#include "ocpp/v201/transaction.hpp"
#include <iterator>
Expand Down Expand Up @@ -193,13 +194,22 @@ SmartChargingHandler::validate_profile_schedules(ChargingProfile& profile,
}

SetChargingProfileResponse SmartChargingHandler::add_profile(int32_t evse_id, ChargingProfile& profile) {
if (STATION_WIDE_ID == evse_id) {
station_wide_charging_profiles.push_back(profile);
} else {
charging_profiles[evse_id].push_back(profile);
}
SetChargingProfileResponse response;
response.status = ChargingProfileStatusEnum::Accepted;

auto& profile_storage = STATION_WIDE_ID == evse_id ? station_wide_charging_profiles : charging_profiles[evse_id];
auto pos = std::distance(profile_storage.begin(), std::find_if(profile_storage.begin(), profile_storage.end(),
[&profile](const ChargingProfile existing_profile) {
return profile.id == existing_profile.id;
}));

if (pos >= profile_storage.size() ||
profile_storage[pos].chargingProfilePurpose == ChargingProfilePurposeEnum::ChargingStationExternalConstraints) {
profile_storage.push_back(profile);
} else {
profile_storage[pos] = profile;
}

return response;
}

Expand Down
45 changes: 45 additions & 0 deletions tests/lib/ocpp/v201/test_smart_charging_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,4 +577,49 @@ TEST_F(ChargepointTestFixtureV201,
EXPECT_THAT(handler.get_profiles(), testing::Contains(profile));
}

TEST_F(ChargepointTestFixtureV201,
K01FR05_IfProfileWithSameIdExistsAndIsNotChargingStationExternalContraints_ThenProfileIsReplaced) {
create_evse_with_id(DEFAULT_EVSE_ID);

auto profile1 = create_charging_profile(DEFAULT_PROFILE_ID, ChargingProfilePurposeEnum::TxDefaultProfile,
create_charge_schedule(ChargingRateUnitEnum::A), uuid(),
ChargingProfileKindEnum::Absolute, DEFAULT_STACK_LEVEL);
auto profile2 = create_charging_profile(DEFAULT_PROFILE_ID, ChargingProfilePurposeEnum::TxProfile,
create_charge_schedule(ChargingRateUnitEnum::A), uuid(),
ChargingProfileKindEnum::Absolute, DEFAULT_STACK_LEVEL);

auto sut1 = handler.add_profile(DEFAULT_EVSE_ID, profile1);
auto sut2 = handler.add_profile(DEFAULT_EVSE_ID, profile2);

auto profiles = handler.get_profiles();

EXPECT_THAT(sut1.status, testing::Eq(ChargingProfileStatusEnum::Accepted));
EXPECT_THAT(sut2.status, testing::Eq(ChargingProfileStatusEnum::Accepted));
EXPECT_THAT(profiles, testing::Contains(profile2));
EXPECT_THAT(profiles, testing::Not(testing::Contains(profile1)));
}

TEST_F(ChargepointTestFixtureV201,
K01FR05_IfProfileWithSameIdExistsAndIsChargingStationExternalContraints_ThenProfileIsAppended) {
create_evse_with_id(DEFAULT_EVSE_ID);

auto profile1 =
create_charging_profile(DEFAULT_PROFILE_ID, ChargingProfilePurposeEnum::ChargingStationExternalConstraints,
create_charge_schedule(ChargingRateUnitEnum::A), uuid(),
ChargingProfileKindEnum::Absolute, DEFAULT_STACK_LEVEL);
auto profile2 = create_charging_profile(DEFAULT_PROFILE_ID, ChargingProfilePurposeEnum::TxProfile,
create_charge_schedule(ChargingRateUnitEnum::A), uuid(),
ChargingProfileKindEnum::Absolute, DEFAULT_STACK_LEVEL);

auto sut1 = handler.add_profile(DEFAULT_EVSE_ID, profile1);
auto sut2 = handler.add_profile(DEFAULT_EVSE_ID, profile2);

auto profiles = handler.get_profiles();

EXPECT_THAT(sut1.status, testing::Eq(ChargingProfileStatusEnum::Accepted));
EXPECT_THAT(sut2.status, testing::Eq(ChargingProfileStatusEnum::Accepted));
EXPECT_THAT(profiles, testing::Contains(profile1));
EXPECT_THAT(profiles, testing::Contains(profile2));
}

} // namespace ocpp::v201

0 comments on commit bd51be3

Please sign in to comment.