Skip to content

Commit

Permalink
Validate a TxDefaultProfile.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
gberardi-pillar committed Mar 11, 2024
1 parent 51b3a62 commit 6327074
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 49 deletions.
8 changes: 8 additions & 0 deletions include/ocpp/v201/evse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ class Evse {
/// \return
uint32_t get_number_of_connectors();

/// \brief Returns true if evse_id is 0.
/// \return
bool is_station_wide() const;

/// \brief Returns true if evse_id is 0.
/// \return
static bool is_station_wide_id(int32_t id);

/// \brief Opens a new transaction
/// \param transaction_id id of the transaction
/// \param connector_id id of the connector
Expand Down
23 changes: 20 additions & 3 deletions include/ocpp/v201/smart_charging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ enum class ProfileValidationResultEnum {
TxProfileEvseIdNotGreaterThanZero,
TxProfileTransactionNotOnEvse,
TxProfileEvseHasNoActiveTransaction,
TxProfileConflictingStackLevel
TxProfileConflictingStackLevel,
DuplicateTxDefaultProfileFound
};

struct EvseProfile {
int32_t evse_id;

Check notice on line 28 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#L28

struct member 'EvseProfile::evse_id' is never used.
ChargingProfile profile;
};

/// \brief This class handles and maintains incoming ChargingProfiles and contains the logic
Expand All @@ -29,18 +35,29 @@ class SmartChargingHandler {
private:
std::shared_ptr<ocpp::v201::DatabaseHandler> database_handler;
// cppcheck-suppress unusedStructMember
std::vector<ChargingProfile> charging_profiles;
std::vector<EvseProfile> charging_profiles;

public:
explicit SmartChargingHandler();

///
/// \brief validates the given \p profile according to the specification
///
ProfileValidationResultEnum validate_tx_default_profile(const ChargingProfile& profile, Evse& evse) const;

///
/// \brief validates the given \p profile according to the specification
///
ProfileValidationResultEnum validate_tx_profile(const ChargingProfile& profile, Evse& evse) const;

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

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

} // namespace ocpp::v201
Expand Down
9 changes: 9 additions & 0 deletions lib/ocpp/v201/evse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ EVSE Evse::get_evse_info() {
return evse;
}

bool Evse::is_station_wide() const {
return is_station_wide_id(evse_id);
}

bool Evse::is_station_wide_id(int32_t id) {
const int32_t STATION_WIDE_ID = 0;
return id == STATION_WIDE_ID;
}

uint32_t Evse::get_number_of_connectors() {
return static_cast<uint32_t>(this->id_connector_map.size());
}
Expand Down
50 changes: 46 additions & 4 deletions lib/ocpp/v201/smart_charging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

#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>

Expand All @@ -15,6 +17,21 @@ namespace ocpp::v201 {
SmartChargingHandler::SmartChargingHandler() {
}

ProfileValidationResultEnum SmartChargingHandler::validate_tx_default_profile(const ChargingProfile& profile,
Evse& evse) const {
auto profiles =
evse.is_station_wide() ? get_evse_specific_tx_default_profiles() : get_station_wide_tx_default_profiles();
for (auto iter = profiles.begin(); iter != profiles.end(); ++iter) {
if (iter->profile.stackLevel == profile.stackLevel) {
if (iter->profile.id != profile.id) {
return ProfileValidationResultEnum::DuplicateTxDefaultProfileFound;
}
}
}

return ProfileValidationResultEnum::Valid;
}

ProfileValidationResultEnum SmartChargingHandler::validate_tx_profile(const ChargingProfile& profile,
Evse& evse) const {
if (!profile.transactionId.has_value()) {
Expand All @@ -35,8 +52,9 @@ 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 EvseProfile& candidate) {
return candidate.profile.transactionId == profile.transactionId &&
candidate.profile.stackLevel == profile.stackLevel;
};
if (std::any_of(charging_profiles.begin(), charging_profiles.end(), conflicts_with)) {
return ProfileValidationResultEnum::TxProfileConflictingStackLevel;
Expand All @@ -45,8 +63,32 @@ ProfileValidationResultEnum SmartChargingHandler::validate_tx_profile(const Char
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) {
charging_profiles.push_back(EvseProfile{evse_id = evse_id, profile = profile});
}

std::vector<EvseProfile> SmartChargingHandler::get_evse_specific_tx_default_profiles() const {
std::vector<EvseProfile> evse_specific_tx_default_profiles;
auto pred = [](const EvseProfile& candidate) {
return !Evse::is_station_wide_id(candidate.evse_id) &&
candidate.profile.chargingProfilePurpose == ChargingProfilePurposeEnum::TxDefaultProfile;
};
std::copy_if(charging_profiles.begin(), charging_profiles.end(),
std::back_inserter(evse_specific_tx_default_profiles), pred);

return evse_specific_tx_default_profiles;
}

std::vector<EvseProfile> SmartChargingHandler::get_station_wide_tx_default_profiles() const {
std::vector<EvseProfile> station_wide_tx_default_profiles;
auto pred = [](const EvseProfile& candidate) {
return Evse::is_station_wide_id(candidate.evse_id) &&
candidate.profile.chargingProfilePurpose == ChargingProfilePurposeEnum::TxDefaultProfile;
};
std::copy_if(charging_profiles.begin(), charging_profiles.end(),
std::back_inserter(station_wide_tx_default_profiles), pred);

return station_wide_tx_default_profiles;
}

} // namespace ocpp::v201

0 comments on commit 6327074

Please sign in to comment.