Skip to content

Commit

Permalink
Validate a TxDefaultProfile. (#524)
Browse files Browse the repository at this point in the history
* Validate a TxDefaultProfile.

These changes apply to K01FR52 and K01FR53.

Signed-off-by: Christoph <367712+folkengine@users.noreply.github.com>
Signed-off-by: Gianfranco Berardi <54074967+gberardi-pillar@users.noreply.github.com>

* Review fixes.

Signed-off-by: Gianfranco Berardi <54074967+gberardi-pillar@users.noreply.github.com>

* Review fix.

Signed-off-by: Gianfranco Berardi <54074967+gberardi-pillar@users.noreply.github.com>

* Add test case.

Signed-off-by: Gianfranco Berardi <54074967+gberardi-pillar@users.noreply.github.com>

* Review fix.

Signed-off-by: Gianfranco Berardi <54074967+gberardi-pillar@users.noreply.github.com>

* Review fix.

Signed-off-by: Gianfranco Berardi <54074967+gberardi-pillar@users.noreply.github.com>

---------

Signed-off-by: Christoph <367712+folkengine@users.noreply.github.com>
Signed-off-by: Gianfranco Berardi <54074967+gberardi-pillar@users.noreply.github.com>
  • Loading branch information
gberardi-pillar committed Apr 10, 2024
1 parent 6399842 commit d47fd2d
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 66 deletions.
19 changes: 16 additions & 3 deletions include/ocpp/v201/smart_charging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ enum class ProfileValidationResultEnum {
ChargingProfileExtraneousStartSchedule,
ChargingSchedulePeriodsOutOfOrder,
ChargingSchedulePeriodInvalidPhaseToUse,
DuplicateTxDefaultProfileFound
};

/// \brief This class handles and maintains incoming ChargingProfiles and contains the logic
Expand All @@ -38,7 +39,8 @@ class SmartChargingHandler {

std::shared_ptr<ocpp::v201::DatabaseHandler> database_handler;
// cppcheck-suppress unusedStructMember
std::vector<ChargingProfile> charging_profiles;
std::map<int32_t, std::vector<ChargingProfile>> charging_profiles;
std::vector<ChargingProfile> station_wide_charging_profiles;

public:
explicit SmartChargingHandler(std::map<int32_t, std::unique_ptr<EvseInterface>>& evses);
Expand All @@ -48,6 +50,11 @@ class SmartChargingHandler {
///
ProfileValidationResultEnum validate_evse_exists(int32_t evse_id) const;

///
/// \brief validates the given \p profile and associated \p evse_id according to the specification
///
ProfileValidationResultEnum validate_tx_default_profile(const ChargingProfile& profile, int32_t evse_id) const;

///
/// \brief validates the given \p profile according to the specification
///
Expand All @@ -56,8 +63,14 @@ class SmartChargingHandler {
/// \brief validates that the given \p profile has valid charging schedules
ProfileValidationResultEnum validate_profile_schedules(const ChargingProfile& profile) const;

/// \brief Adds a given \p profile to our stored list of profiles
void add_profile(const ChargingProfile& profile);
///
/// \brief Adds a given \p profile and associated \p evse_id to our stored list of profiles
///
void add_profile(int32_t evse_id, ChargingProfile& profile);

private:
std::vector<ChargingProfile> get_evse_specific_tx_default_profiles() const;
std::vector<ChargingProfile> get_station_wide_tx_default_profiles() const;
};

} // namespace ocpp::v201
Expand Down
58 changes: 54 additions & 4 deletions lib/ocpp/v201/smart_charging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
#include "everest/logging.hpp"
#include "ocpp/common/types.hpp"
#include "ocpp/v201/enums.hpp"
#include "ocpp/v201/evse.hpp"
#include "ocpp/v201/ocpp_types.hpp"
#include "ocpp/v201/transaction.hpp"
#include <iterator>
#include <memory>
#include <ocpp/v201/smart_charging.hpp>

using namespace std::chrono;

namespace ocpp::v201 {

const int32_t STATION_WIDE_ID = 0;

SmartChargingHandler::SmartChargingHandler(std::map<int32_t, std::unique_ptr<EvseInterface>>& evses) : evses(evses) {
}

Expand All @@ -21,6 +25,20 @@ ProfileValidationResultEnum SmartChargingHandler::validate_evse_exists(int32_t e
: ProfileValidationResultEnum::Valid;
}

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();
for (auto candidate : profiles) {
if (candidate.stackLevel == profile.stackLevel) {
if (candidate.id != profile.id) {
return ProfileValidationResultEnum::DuplicateTxDefaultProfileFound;
}
}
}

return ProfileValidationResultEnum::Valid;
}

ProfileValidationResultEnum SmartChargingHandler::validate_tx_profile(const ChargingProfile& profile,
EvseInterface& evse) const {
if (!profile.transactionId.has_value()) {
Expand All @@ -41,8 +59,12 @@ ProfileValidationResultEnum SmartChargingHandler::validate_tx_profile(const Char
return ProfileValidationResultEnum::TxProfileTransactionNotOnEvse;
}

auto conflicts_with = [&profile](const ChargingProfile& candidate) {
return candidate.transactionId == profile.transactionId && candidate.stackLevel == profile.stackLevel;
auto conflicts_with = [&profile](const std::pair<int32_t, std::vector<ChargingProfile>>& candidate) {
return std::any_of(candidate.second.begin(), candidate.second.end(),
[&profile](const ChargingProfile& candidateProfile) {
return candidateProfile.transactionId == profile.transactionId &&
candidateProfile.stackLevel == profile.stackLevel;
});
};
if (std::any_of(charging_profiles.begin(), charging_profiles.end(), conflicts_with)) {
return ProfileValidationResultEnum::TxProfileConflictingStackLevel;
Expand Down Expand Up @@ -102,8 +124,36 @@ ProfileValidationResultEnum SmartChargingHandler::validate_profile_schedules(con
return ProfileValidationResultEnum::Valid;
}

void SmartChargingHandler::add_profile(const ChargingProfile& profile) {
charging_profiles.push_back(profile);
void 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);
}
}

std::vector<ChargingProfile> SmartChargingHandler::get_evse_specific_tx_default_profiles() const {
std::vector<ChargingProfile> evse_specific_tx_default_profiles;

for (auto evse_profile_pair : charging_profiles) {
for (auto profile : evse_profile_pair.second)
if (profile.chargingProfilePurpose == ChargingProfilePurposeEnum::TxDefaultProfile) {
evse_specific_tx_default_profiles.push_back(profile);
}
}

return evse_specific_tx_default_profiles;
}

std::vector<ChargingProfile> SmartChargingHandler::get_station_wide_tx_default_profiles() const {
std::vector<ChargingProfile> station_wide_tx_default_profiles;
for (auto profile : station_wide_charging_profiles) {
if (profile.chargingProfilePurpose == ChargingProfilePurposeEnum::TxDefaultProfile) {
station_wide_tx_default_profiles.push_back(profile);
}
}

return station_wide_tx_default_profiles;
}

} // namespace ocpp::v201

0 comments on commit d47fd2d

Please sign in to comment.