Skip to content

Commit

Permalink
added ability to load profile from database
Browse files Browse the repository at this point in the history
Signed-off-by: Coury Richards <[email protected]>
  • Loading branch information
couryrr-afs authored and christopher-davis-afs committed Jul 24, 2024
1 parent c759871 commit 8d7b375
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 7 deletions.
6 changes: 6 additions & 0 deletions config/v201/core_migrations/1_up-initial.sql
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,9 @@ CREATE TABLE METER_VALUE_ITEMS (
ENCODING_METHOD TEXT,
PUBLIC_KEY TEXT
);

CREATE TABLE CHARGING_PROFILES (
ID INT PRIMARY KEY NOT NULL,
EVSE_ID INT NOT NULL,
PROFILE TEXT NOT NULL
);
2 changes: 1 addition & 1 deletion doc/ocpp_201_status.md
Original file line number Diff line number Diff line change
Expand Up @@ -1252,7 +1252,7 @@ This document contains the status of which OCPP 2.0.1 numbered functional requir
| K01.FR.21 | | |
| K01.FR.22 | | |
| K01.FR.26 || |
| K01.FR.27 | | |
| K01.FR.27 | | |
| K01.FR.28 || |
| K01.FR.29 | | |
| K01.FR.30 | | |
Expand Down
2 changes: 2 additions & 0 deletions include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include <ocpp/v201/messages/UpdateFirmware.hpp>

#include "component_state_manager.hpp"
#include "ocpp/v201/smart_charging.hpp"

namespace ocpp {
namespace v201 {
Expand Down Expand Up @@ -780,6 +781,7 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa
std::shared_ptr<SmartChargingHandlerInterface> smart_charging_handler;

void handle_message(const EnhancedMessage<v201::MessageType>& message);
void load_charging_profiles();

public:
/// \brief Construct a new ChargePoint object
Expand Down
14 changes: 14 additions & 0 deletions include/ocpp/v201/database_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,20 @@ class DatabaseHandler : public common::DatabaseHandlerCommon {
/// \param transaction_id transaction id of the transaction to clear from.
/// \return true if succeeded
void transaction_delete(const std::string& transaction_id);

/// charging profiles

/// \brief Inserts or updates the given \p profile to CHARGING_PROFILES table
virtual void insert_or_update_charging_profile(const int evse_id, const v201::ChargingProfile& profile);

/// \brief Deletes the profile with the given \p profile_id
virtual void delete_charging_profile(const int profile_id);

/// \brief Deletes all profiles from table CHARGING_PROFILES
void delete_charging_profiles();

/// \brief Retrieves all ChargingProfiles
virtual std::map<int32_t, std::vector<v201::ChargingProfile>> get_all_charging_profiles_by_evse();
};

} // namespace v201
Expand Down
3 changes: 2 additions & 1 deletion include/ocpp/v201/smart_charging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ class SmartChargingHandler : public SmartChargingHandlerInterface {
std::map<int32_t, std::vector<ChargingProfile>> charging_profiles;

public:
SmartChargingHandler(EvseManagerInterface& evse_manager, std::shared_ptr<DeviceModel>& device_model);
SmartChargingHandler(EvseManagerInterface& evse_manager, std::shared_ptr<DeviceModel>& device_model,
std::shared_ptr<ocpp::v201::DatabaseHandler> database_handler);

///
/// \brief validates the given \p profile according to the specification.
Expand Down
35 changes: 34 additions & 1 deletion lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ ChargePoint::ChargePoint(const std::map<int32_t, int32_t>& evse_connector_struct
evse_connector_structure, *this->device_model, this->database_handler, component_state_manager,
transaction_meter_value_callback, this->callbacks.pause_charging_callback);

this->smart_charging_handler = std::make_shared<SmartChargingHandler>(*this->evse_manager, this->device_model);
this->smart_charging_handler =
std::make_shared<SmartChargingHandler>(*this->evse_manager, this->device_model, this->database_handler);

// configure logging
this->configure_message_logging_format(message_log_path);
Expand Down Expand Up @@ -220,6 +221,8 @@ void ChargePoint::start(BootReasonEnum bootreason) {
// get transaction messages from db (if there are any) so they can be sent again.
this->message_queue->get_persisted_messages_from_db();
this->boot_notification_req(bootreason);
// K01.27 - call load_charging_profiles when system boots
this->load_charging_profiles();
this->start_websocket();

if (this->bootreason == BootReasonEnum::RemoteReset) {
Expand Down Expand Up @@ -3817,6 +3820,36 @@ void ChargePoint::execute_change_availability_request(ChangeAvailabilityRequest
}
}

// K01.27 - load profiles from database
void ChargePoint::load_charging_profiles() {
try {
auto evses = this->database_handler->get_all_charging_profiles_by_evse();
EVLOG_info << "Found " << evses.size() << " evse in the database";
for (auto& profiles : evses) {
try {
auto evse_id = profiles.first;
for (auto profile : profiles.second) {
if (this->smart_charging_handler->validate_profile(profile, evse_id) ==
ProfileValidationResultEnum::Valid) {
this->smart_charging_handler->add_profile(profile, evse_id);
} else {
// delete if not valid anymore
this->database_handler->delete_charging_profile(profile.id);
}
}
} catch (common::RequiredEntryNotFoundException& e) {
EVLOG_warning << "Could not get connector id from database: " << e.what();
} catch (const QueryExecutionException& e) {
EVLOG_warning << "Could not get connector id from database: " << e.what();
}
}
} catch (const QueryExecutionException& e) {
EVLOG_warning << "Could not load charging profiles from database: " << e.what();
} catch (const std::exception& e) {
EVLOG_warning << "Unknown error while loading charging profiles from database: " << e.what();
}
}

std::vector<GetVariableResult>
ChargePoint::get_variables(const std::vector<GetVariableData>& get_variable_data_vector) {
std::vector<GetVariableResult> response;
Expand Down
53 changes: 53 additions & 0 deletions lib/ocpp/v201/database_handler.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest

#include "everest/logging.hpp"
#include <ocpp/common/message_queue.hpp>
#include <ocpp/v201/database_handler.hpp>
#include <ocpp/v201/types.hpp>
Expand Down Expand Up @@ -719,5 +720,57 @@ void DatabaseHandler::transaction_delete(const std::string& transaction_id) {
}
}

void DatabaseHandler::insert_or_update_charging_profile(const int evse_id, const v201::ChargingProfile& profile) {
// add or replace
std::string sql = "INSERT OR REPLACE INTO CHARGING_PROFILES (ID, EVSE_ID, PROFILE) VALUES "
"(@id, @evse_id, @profile)";
auto stmt = this->database->new_statement(sql);

json json_profile(profile);

stmt->bind_int("@id", profile.id);
stmt->bind_int("@evse_id", evse_id);
stmt->bind_text("@profile", json_profile.dump(), SQLiteString::Transient);

if (stmt->step() != SQLITE_DONE) {
EVLOG_error << "Could not insert into table: " << this->database->get_error_message();
throw std::runtime_error("db access error");
}
}

void DatabaseHandler::delete_charging_profile(const int profile_id) {
std::string sql = "DELETE FROM CHARGING_PROFILES WHERE ID = @profile_id;";
auto stmt = this->database->new_statement(sql);

stmt->bind_int("@profile_id", profile_id);
if (stmt->step() != SQLITE_DONE) {
EVLOG_error << "Could not delete from table: " << this->database->get_error_message();
}
}

void DatabaseHandler::delete_charging_profiles() {
this->database->clear_table("CHARGING_PROFILES");
}

std::map<int32_t, std::vector<v201::ChargingProfile>> DatabaseHandler::get_all_charging_profiles_by_evse() {
std::map<int32_t, std::vector<v201::ChargingProfile>> map;

std::string sql = "SELECT EVSE_ID, PROFILE FROM CHARGING_PROFILES";

auto stmt = this->database->new_statement(sql);

while (stmt->step() != SQLITE_DONE) {
auto evse_id = stmt->column_int(0);
auto profile = json::parse(stmt->column_text(1));

auto profiles = map[evse_id];
profiles.emplace_back(profile);

map[evse_id] = profiles;
}

return map;
}

} // namespace v201
} // namespace ocpp
6 changes: 4 additions & 2 deletions lib/ocpp/v201/smart_charging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "date/tz.h"
#include "everest/logging.hpp"
#include "ocpp/common/message_queue.hpp"
#include "ocpp/common/types.hpp"
#include "ocpp/v201/ctrlr_component_variables.hpp"
#include "ocpp/v201/device_model.hpp"
Expand Down Expand Up @@ -141,8 +142,9 @@ SmartChargingHandlerInterface::~SmartChargingHandlerInterface() {
}

SmartChargingHandler::SmartChargingHandler(EvseManagerInterface& evse_manager,
std::shared_ptr<DeviceModel>& device_model) :
evse_manager(evse_manager), device_model(device_model) {
std::shared_ptr<DeviceModel>& device_model,
std::shared_ptr<ocpp::v201::DatabaseHandler> database_handler) :
evse_manager(evse_manager), device_model(device_model), database_handler(database_handler) {
}

ProfileValidationResultEnum SmartChargingHandler::validate_profile(ChargingProfile& profile, int32_t evse_id) {
Expand Down
1 change: 1 addition & 0 deletions tests/lib/ocpp/v201/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ target_include_directories(libocpp_unit_tests PUBLIC

target_sources(libocpp_unit_tests PRIVATE
test_charge_point.cpp
test_database_handler.cpp
test_database_migration_files.cpp
test_device_model_storage_sqlite.cpp
test_notify_report_requests_splitter.cpp
Expand Down
Loading

0 comments on commit 8d7b375

Please sign in to comment.