Skip to content

Commit

Permalink
SmartChargingHandler: Add validation for TxProfiles
Browse files Browse the repository at this point in the history
Creates a skeleton for SmartChargingHandler and adds a method
to validate TxProfiles and TxProfiles only. This method
ensures that a given profile (assumed to be TxProfile) fits all of
the functional requirements specific to TxProfiles per K01.

The function, `validate_tx_profile ()`, takes a profile and an
EVSE, and returns a variant of `ProfileValidationResultEnum`.
This enum allows us to have detailed responses for the different types
of invalid profiles, and eventually will let us log *why* a profile
is invalid if the general validation fails.

Part of the prerequisites for #361

Co-authored-by: Gianfranco Berardi <[email protected]>
Signed-off-by: Christopher Davis <[email protected]>
  • Loading branch information
christopher-davis-afs and gberardi-pillar committed Feb 6, 2024
1 parent 4d019a6 commit 26746ac
Show file tree
Hide file tree
Showing 5 changed files with 483 additions and 1 deletion.
51 changes: 51 additions & 0 deletions include/ocpp/v201/smart_charging.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest

#ifndef OCPP_V201_SMART_CHARGING_HPP
#define OCPP_V201_SMART_CHARGING_HPP

#include "ocpp/v201/enums.hpp"
#include <limits>

#include <ocpp/v201/database_handler.hpp>
#include <ocpp/v201/evse.hpp>
#include <ocpp/v201/ocpp_types.hpp>
#include <ocpp/v201/transaction.hpp>

namespace ocpp {
namespace v201 {

enum class ProfileValidationResultEnum {
Valid,
TxProfileMissingTransactionId,
TxProfileEvseIdNotGreaterThanZero,
TxProfileTransactionNotOnEvse,
TxProfileEvseHasNoActiveTransaction,
TxProfileConflictingStackLevel
};

/// \brief This class handles and maintains incoming ChargingProfiles and contains the logic
/// to calculate the composite schedules
class SmartChargingHandler {
private:
std::shared_ptr<ocpp::v201::DatabaseHandler> database_handler;
std::vector<ChargingProfile> charging_profiles;

Check notice on line 32 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#L32

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

public:
explicit SmartChargingHandler(std::shared_ptr<DatabaseHandler> database_handler);

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

void add_profile(ChargingProfile& profile);
};

bool validate_schedule(const ChargingSchedule& schedule, const int charging_schedule_max_periods,
const std::vector<ChargingRateUnitEnum>& charging_schedule_allowed_charging_rate_units);

} // namespace v201
} // namespace ocpp

#endif // OCPP_V201_SMART_CHARGING_HPP
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ target_sources(ocpp
ocpp/v16/types.cpp
ocpp/v201/average_meter_values.cpp
ocpp/v201/charge_point.cpp
ocpp/v201/smart_charging.cpp
ocpp/v201/connector.cpp
ocpp/v201/ctrlr_component_variables.cpp
ocpp/v201/database_handler.cpp
Expand Down
54 changes: 54 additions & 0 deletions lib/ocpp/v201/smart_charging.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest

#include "ocpp/common/types.hpp"
#include "ocpp/v201/enums.hpp"
#include "ocpp/v201/ocpp_types.hpp"
#include "ocpp/v201/transaction.hpp"
#include <memory>
#include <ocpp/v201/smart_charging.hpp>

using namespace std::chrono;

namespace ocpp {
namespace v201 {

SmartChargingHandler::SmartChargingHandler(std::shared_ptr<DatabaseHandler> database_handler) :
database_handler(database_handler) {
}

ProfileValidationResultEnum SmartChargingHandler::validate_tx_profile(ChargingProfile& profile, Evse& evse) const {
if (!profile.transactionId.has_value()) {
return ProfileValidationResultEnum::TxProfileMissingTransactionId;
}

int32_t evseId = evse.get_evse_info().id;
if (evseId <= 0) {
return ProfileValidationResultEnum::TxProfileEvseIdNotGreaterThanZero;
}

if (!evse.has_active_transaction()) {
return ProfileValidationResultEnum::TxProfileEvseHasNoActiveTransaction;
}

auto& transaction = evse.get_transaction();
if (transaction->transactionId != profile.transactionId.value()) {
return ProfileValidationResultEnum::TxProfileTransactionNotOnEvse;
}

auto conflicts_with = [&profile](const ChargingProfile& candidate) {
return candidate.transactionId == profile.transactionId && candidate.stackLevel == profile.stackLevel;
};
if (std::any_of(charging_profiles.begin(), charging_profiles.end(), conflicts_with)) {
return ProfileValidationResultEnum::TxProfileConflictingStackLevel;
}

return ProfileValidationResultEnum::Valid;
}

void SmartChargingHandler::add_profile(ChargingProfile& profile) {
charging_profiles.push_back(profile);
}

} // namespace v201
} // namespace ocpp
3 changes: 2 additions & 1 deletion tests/lib/ocpp/v201/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ target_sources(libocpp_unit_tests PRIVATE
test_device_model_storage_sqlite.cpp
test_notify_report_requests_splitter.cpp
test_ocsp_updater.cpp
test_component_state_manager.cpp)
test_component_state_manager.cpp
test_smart_charging_handler.cpp)
Loading

0 comments on commit 26746ac

Please sign in to comment.