Skip to content

Commit

Permalink
Rename DeviceModelStorage to DeviceModelInterface (#768)
Browse files Browse the repository at this point in the history
* Rename `DeviceModelStorage` to `DeviceModelInterface`
* Changes to the database and distinguish between external and ocpp values. 

Signed-off-by: Maaike Zijderveld, iolar <[email protected]>
  • Loading branch information
maaikez authored Nov 14, 2024
1 parent 5416829 commit b00d278
Show file tree
Hide file tree
Showing 25 changed files with 171 additions and 125 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14)

project(ocpp
VERSION 0.19.0
VERSION 0.20.0
DESCRIPTION "A C++ implementation of the Open Charge Point Protocol"
LANGUAGES CXX
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE VARIABLE
DROP COLUMN SOURCE;
2 changes: 2 additions & 0 deletions config/v201/device_model_migrations/2_up-variable_source.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE VARIABLE
ADD COLUMN SOURCE TEXT;
12 changes: 6 additions & 6 deletions include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include <ocpp/v201/ctrlr_component_variables.hpp>
#include <ocpp/v201/database_handler.hpp>
#include <ocpp/v201/device_model.hpp>
#include <ocpp/v201/device_model_storage.hpp>
#include <ocpp/v201/device_model_storage_interface.hpp>
#include <ocpp/v201/evse_manager.hpp>
#include <ocpp/v201/monitoring_updater.hpp>
#include <ocpp/v201/ocpp_enums.hpp>
Expand Down Expand Up @@ -808,17 +808,17 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa
/// \param evse_connector_structure Map that defines the structure of EVSE and connectors of the chargepoint. The
/// key represents the id of the EVSE and the value represents the number of connectors for this EVSE. The ids of
/// the EVSEs have to increment starting with 1.
/// \param device_model_storage device model storage instance
/// \param device_model_storage_interface device model interface instance
/// \param ocpp_main_path Path where utility files for OCPP are read and written to
/// \param core_database_path Path to directory where core database is located
/// \param message_log_path Path to where logfiles are written to
/// \param evse_security Pointer to evse_security that manages security related operations
/// \param callbacks Callbacks that will be registered for ChargePoint
ChargePoint(const std::map<int32_t, int32_t>& evse_connector_structure,
std::unique_ptr<DeviceModelStorage> device_model_storage, const std::string& ocpp_main_path,
const std::string& core_database_path, const std::string& sql_init_path,
const std::string& message_log_path, const std::shared_ptr<EvseSecurity> evse_security,
const Callbacks& callbacks);
std::unique_ptr<DeviceModelStorageInterface> device_model_storage_interface,
const std::string& ocpp_main_path, const std::string& core_database_path,
const std::string& sql_init_path, const std::string& message_log_path,
const std::shared_ptr<EvseSecurity> evse_security, const Callbacks& callbacks);

/// \brief Construct a new ChargePoint object
/// \param evse_connector_structure Map that defines the structure of EVSE and connectors of the chargepoint. The
Expand Down
25 changes: 12 additions & 13 deletions include/ocpp/v201/device_model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#include <everest/logging.hpp>

#include <ocpp/v201/device_model_storage.hpp>
#include <ocpp/v201/device_model_storage_interface.hpp>

namespace ocpp {
namespace v201 {
Expand Down Expand Up @@ -91,13 +91,13 @@ typedef std::function<void(const VariableMonitoringMeta& updated_monitor, const
const VariableAttribute& attribute, const std::string& current_value)>
on_monitor_updated;

/// \brief This class manages access to the device model representation and to the device model storage and provides
/// \brief This class manages access to the device model representation and to the device model interface and provides
/// functionality to support the use cases defined in the functional block Provisioning
class DeviceModel {

private:
DeviceModelMap device_model;
std::unique_ptr<DeviceModelStorage> storage;
DeviceModelMap device_model_map;
std::unique_ptr<DeviceModelStorageInterface> device_model;

/// \brief Listener for the internal change of a variable
on_variable_changed variable_listener;
Expand All @@ -106,7 +106,7 @@ class DeviceModel {

/// \brief Private helper method that does some checks with the device model representation in memory to evaluate if
/// a value for the given parameters can be requested. If it can be requested it will be retrieved from the device
/// model storage and the given \p value will be set to the value that was retrieved
/// model interface and the given \p value will be set to the value that was retrieved
/// \param component_id
/// \param variable_id
/// \param attribute_enum
Expand Down Expand Up @@ -138,15 +138,15 @@ class DeviceModel {

public:
/// \brief Constructor for the device model
/// \param device_model_storage pointer to a device model storage class
explicit DeviceModel(std::unique_ptr<DeviceModelStorage> device_model_storage);
/// \param device_model_storage_interface pointer to a device model interface class
explicit DeviceModel(std::unique_ptr<DeviceModelStorageInterface> device_model_storage_interface);

/// \brief Direct access to value of a VariableAttribute for the given component, variable and attribute_enum. This
/// should only be called for variables that have a role standardized in the OCPP2.0.1 specification.
/// \tparam T datatype of the value that is requested
/// \param component_variable Combination of Component and Variable that identifies the Variable
/// \param attribute_enum defaults to AttributeEnum::Actual
/// \return the requested value from the device model storage
/// \return the requested value from the device model interface
template <typename T>
T get_value(const RequiredComponentVariable& component_variable,
const AttributeEnum& attribute_enum = AttributeEnum::Actual) const {
Expand All @@ -159,11 +159,10 @@ class DeviceModel {
if (response == GetVariableStatusEnum::Accepted) {
return to_specific_type<T>(value);
} else {
EVLOG_critical
<< "Directly requested value for ComponentVariable that doesn't exist in the device model storage: "
<< component_variable;
EVLOG_critical << "Directly requested value for ComponentVariable that doesn't exist in the device model: "
<< component_variable;
EVLOG_AND_THROW(std::runtime_error(
"Directly requested value for ComponentVariable that doesn't exist in the device model storage."));
"Directly requested value for ComponentVariable that doesn't exist in the device model."));
}
}

Expand All @@ -190,7 +189,7 @@ class DeviceModel {
}

/// \brief Requests a value of a VariableAttribute specified by combination of \p component_id and \p variable_id
/// from the device model storage
/// from the device model
/// \tparam T datatype of the value that is requested
/// \param component_id
/// \param variable_id
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest

#ifndef OCPP_V201_DEVICE_MODEL_STORAGE_HPP
#define OCPP_V201_DEVICE_MODEL_STORAGE_HPP
#pragma once

#include <map>
#include <memory>
Expand Down Expand Up @@ -34,36 +33,37 @@ struct VariableMonitoringPeriodic {
struct VariableMetaData {
VariableCharacteristics characteristics;
std::unordered_map<int64_t, VariableMonitoringMeta> monitors;
std::optional<std::string> source;
};

using VariableMap = std::map<Variable, VariableMetaData>;
using DeviceModelMap = std::map<Component, VariableMap>;

class DeviceModelStorageError : public std::exception {
class DeviceModelError : public std::exception {
public:
[[nodiscard]] const char* what() const noexcept override {
return this->reason.c_str();
}
explicit DeviceModelStorageError(std::string msg) {
explicit DeviceModelError(std::string msg) {
this->reason = std::move(msg);
}
explicit DeviceModelStorageError(const char* msg) {
explicit DeviceModelError(const char* msg) {
this->reason = std::string(msg);
}

private:
std::string reason;
};

/// \brief Abstract base class for device model storage. This class provides an interface for accessing and modifying
/// \brief Abstract base class for device model interface. This class provides an interface for accessing and modifying
/// device model data. Implementations of this class should provide concrete implementations for the virtual methods
/// declared here.
class DeviceModelStorage {
class DeviceModelStorageInterface {

public:
virtual ~DeviceModelStorage() = default;
virtual ~DeviceModelStorageInterface() = default;

/// \brief Gets the device model from the device model storage
/// \brief Gets the device model from the device model interface
/// \return std::map<Component, std::map<Variable, VariableMetaData>> that will contain a full representation of the
/// device model except for the VariableAttribute(s) of each Variable.
virtual DeviceModelMap get_device_model() = 0;
Expand Down Expand Up @@ -140,5 +140,3 @@ class DeviceModelStorage {

} // namespace v201
} // namespace ocpp

#endif // OCPP_V201_DEVICE_MODEL_STORAGE_HPP
4 changes: 2 additions & 2 deletions include/ocpp/v201/device_model_storage_sqlite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@

#include <everest/logging.hpp>
#include <ocpp/common/database/database_connection.hpp>
#include <ocpp/v201/device_model_storage.hpp>
#include <ocpp/v201/device_model_storage_interface.hpp>

namespace ocpp {
namespace v201 {

class DeviceModelStorageSqlite : public DeviceModelStorage {
class DeviceModelStorageSqlite : public DeviceModelStorageInterface {

private:
std::unique_ptr<ocpp::common::DatabaseConnectionInterface> db;
Expand Down
2 changes: 2 additions & 0 deletions include/ocpp/v201/enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#ifndef OCPP_V201_ENUMS_HPP
#define OCPP_V201_ENUMS_HPP

#include <string>

namespace ocpp {
namespace v201 {

Expand Down
4 changes: 3 additions & 1 deletion include/ocpp/v201/init_device_model_db.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include <filesystem>

#include <ocpp/common/database/database_handler_common.hpp>
#include <ocpp/v201/device_model_storage.hpp>
#include <ocpp/v201/device_model_storage_interface.hpp>

namespace ocpp::v201 {
///
Expand Down Expand Up @@ -93,6 +93,8 @@ struct DeviceModelVariable {
std::optional<std::string> default_actual_value;
/// \brief Config monitors, if any
std::vector<VariableMonitoringMeta> monitors;
/// \brief Source of the variable.
std::optional<std::string> source;
};

/// \brief Convert from json to a ComponentKey struct.
Expand Down
4 changes: 2 additions & 2 deletions include/ocpp/v201/monitoring_updater.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <ocpp/v201/ocpp_enums.hpp>
#include <ocpp/v201/ocpp_types.hpp>

#include <ocpp/v201/device_model_storage.hpp>
#include <ocpp/v201/device_model_storage_interface.hpp>

namespace ocpp::v201 {

Expand Down Expand Up @@ -187,4 +187,4 @@ class MonitoringUpdater {
std::unordered_map<std::int32_t, UpdaterMonitorMeta> updater_monitors_meta;
};

} // namespace ocpp::v201
} // namespace ocpp::v201
23 changes: 11 additions & 12 deletions lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ ChargePoint::ChargePoint(const std::map<int32_t, int32_t>& evse_connector_struct
}

ChargePoint::ChargePoint(const std::map<int32_t, int32_t>& evse_connector_structure,
std::unique_ptr<DeviceModelStorage> device_model_storage, const std::string& ocpp_main_path,
const std::string& core_database_path, const std::string& sql_init_path,
const std::string& message_log_path, const std::shared_ptr<EvseSecurity> evse_security,
const Callbacks& callbacks) :
std::unique_ptr<DeviceModelStorageInterface> device_model_storage_interface,
const std::string& ocpp_main_path, const std::string& core_database_path,
const std::string& sql_init_path, const std::string& message_log_path,
const std::shared_ptr<EvseSecurity> evse_security, const Callbacks& callbacks) :
ChargePoint(
evse_connector_structure, std::make_shared<DeviceModel>(std::move(device_model_storage)),
evse_connector_structure, std::make_shared<DeviceModel>(std::move(device_model_storage_interface)),
std::make_shared<DatabaseHandler>(
std::make_unique<common::DatabaseConnection>(fs::path(core_database_path) / "cp.db"), sql_init_path),
nullptr /* message_queue initialized in this constructor */, message_log_path, evse_security, callbacks) {
Expand Down Expand Up @@ -2661,8 +2661,7 @@ void ChargePoint::handle_set_network_profile_req(Call<SetNetworkProfileRequest>
ControllerComponentVariables::NetworkConnectionProfiles.variable.value(),
AttributeEnum::Actual, network_connection_profiles.dump(),
VARIABLE_ATTRIBUTE_VALUE_SOURCE_INTERNAL) != SetVariableStatusEnum::Accepted) {
EVLOG_warning
<< "CSMS attempted to set a network profile that could not be written to the device model storage";
EVLOG_warning << "CSMS attempted to set a network profile that could not be written to the device model";
response.status = SetNetworkProfileStatusEnum::Rejected;
ocpp::CallResult<SetNetworkProfileResponse> call_result(response, call.uniqueId);
this->send<SetNetworkProfileResponse>(call_result);
Expand Down Expand Up @@ -3712,7 +3711,7 @@ void ChargePoint::handle_set_monitoring_base_req(Call<SetMonitoringBaseRequest>
msg.monitoringBase == MonitoringBaseEnum::FactoryDefault) {
try {
this->device_model->clear_custom_monitors();
} catch (const DeviceModelStorageError& e) {
} catch (const DeviceModelError& e) {
EVLOG_warning << "Could not clear custom monitors from DB: " << e.what();
response.status = GenericDeviceModelStatusEnum::Rejected;
}
Expand Down Expand Up @@ -3772,7 +3771,7 @@ void ChargePoint::handle_set_variable_monitoring_req(const EnhancedMessage<v201:

try {
response.setMonitoringResult = this->device_model->set_monitors(msg.setMonitoringData);
} catch (const DeviceModelStorageError& e) {
} catch (const DeviceModelError& e) {
EVLOG_error << "Set monitors failed:" << e.what();
}

Expand Down Expand Up @@ -3852,7 +3851,7 @@ void ChargePoint::handle_get_monitoring_report_req(Call<GetMonitoringReportReque
} else {
response.status = GenericDeviceModelStatusEnum::EmptyResultSet;
}
} catch (const DeviceModelStorageError& e) {
} catch (const DeviceModelError& e) {
EVLOG_error << "Get variable monitoring failed:" << e.what();
response.status = GenericDeviceModelStatusEnum::Rejected;
}
Expand All @@ -3872,7 +3871,7 @@ void ChargePoint::handle_clear_variable_monitoring_req(Call<ClearVariableMonitor

try {
response.clearMonitoringResult = this->device_model->clear_monitors(msg.id);
} catch (const DeviceModelStorageError& e) {
} catch (const DeviceModelError& e) {
EVLOG_error << "Clear variable monitoring failed:" << e.what();
}

Expand Down Expand Up @@ -4143,7 +4142,7 @@ void ChargePoint::handle_send_local_authorization_list_req(Call<SendLocalListReq
this->device_model->set_read_only_value(local_entries.component, local_entries.variable.value(),
AttributeEnum::Actual, std::to_string(entries),
VARIABLE_ATTRIBUTE_VALUE_SOURCE_INTERNAL);
} catch (const DeviceModelStorageError& e) {
} catch (const DeviceModelError& e) {
EVLOG_warning << "Could not get local list count from database:" << e.what();
} catch (const DatabaseException& e) {
EVLOG_warning << "Could not get local list count from database: " << e.what();
Expand Down
Loading

0 comments on commit b00d278

Please sign in to comment.