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

Validate a TxDefaultProfile. #524

Merged
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
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 @@
ChargingProfileExtraneousStartSchedule,
ChargingSchedulePeriodsOutOfOrder,
ChargingSchedulePeriodInvalidPhaseToUse,
DuplicateTxDefaultProfileFound
};

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

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;

Check notice on line 43 in include/ocpp/v201/smart_charging.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

include/ocpp/v201/smart_charging.hpp#L43

class member 'SmartChargingHandler::station_wide_charging_profiles' is never used.

public:
explicit SmartChargingHandler(std::map<int32_t, std::unique_ptr<EvseInterface>>& evses);
Expand All @@ -48,6 +50,11 @@
///
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 @@
/// \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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the function docs according to the added param

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


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 {
marcemmers marked this conversation as resolved.
Show resolved Hide resolved
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
Loading
Loading