Skip to content

Commit

Permalink
Add composed device model storage and everest device model storage. (#…
Browse files Browse the repository at this point in the history
…846)

* Add composed device model storage and everest device model storage.
* Distinguish between ocpp and external variables. 
* Rename device model interface to device model storage interface.


Signed-off-by: Maaike Zijderveld, iolar <[email protected]>
  • Loading branch information
maaikez authored and hikinggrass committed Nov 21, 2024
1 parent 5f7eaf3 commit cd5190a
Show file tree
Hide file tree
Showing 12 changed files with 456 additions and 4 deletions.
2 changes: 1 addition & 1 deletion dependencies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ libevse-security:
# OCPP
libocpp:
git: https://github.com/EVerest/libocpp.git
git_tag: v0.19.0
git_tag: v0.20.0
cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBOCPP"
# Josev
Josev:
Expand Down
2 changes: 2 additions & 0 deletions modules/OCPP201/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ target_sources(${MODULE_NAME}
"data_transfer/ocpp_data_transferImpl.cpp"
"ocpp_generic/ocppImpl.cpp"
"session_cost/session_costImpl.cpp"
"device_model/everest_device_model_storage.cpp"
"device_model/composed_device_model_storage.cpp"
)

# ev@c55432ab-152c-45a9-9d2e-7281d50c69c3:v1
Expand Down
10 changes: 7 additions & 3 deletions modules/OCPP201/OCPP201.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <websocketpp_utils/uri.hpp>

#include <conversions.hpp>
#include <device_model/composed_device_model_storage.hpp>
#include <error_handling.hpp>
#include <evse_security_ocpp.hpp>
#include <external_energy_limits.hpp>
Expand Down Expand Up @@ -691,10 +692,13 @@ void OCPP201::ready() {
const auto sql_init_path = this->ocpp_share_path / SQL_CORE_MIGRATIONS;

std::map<int32_t, int32_t> evse_connector_structure = this->get_connector_structure();
std::unique_ptr<module::device_model::ComposedDeviceModelStorage> device_model_storage =
std::make_unique<module::device_model::ComposedDeviceModelStorage>(
device_model_database_path, true, device_model_database_migration_path, device_model_config_path);
this->charge_point = std::make_unique<ocpp::v201::ChargePoint>(
evse_connector_structure, device_model_database_path, true, device_model_database_migration_path,
device_model_config_path, this->ocpp_share_path.string(), this->config.CoreDatabasePath, sql_init_path.string(),
this->config.MessageLogPath, std::make_shared<EvseSecurity>(*this->r_security), callbacks);
evse_connector_structure, std::move(device_model_storage), this->ocpp_share_path.string(),
this->config.CoreDatabasePath, sql_init_path.string(), this->config.MessageLogPath,
std::make_shared<EvseSecurity>(*this->r_security), callbacks);

// publish charging schedules at least once on startup
charging_schedules_callback();
Expand Down
110 changes: 110 additions & 0 deletions modules/OCPP201/device_model/composed_device_model_storage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest

#include <device_model/composed_device_model_storage.hpp>

static constexpr auto VARIABLE_SOURCE_OCPP = "OCPP";

namespace module::device_model {
ComposedDeviceModelStorage::ComposedDeviceModelStorage(const std::string& libocpp_device_model_storage_address,
const bool libocpp_initialize_device_model,
const std::string& device_model_migration_path,
const std::string& device_model_config_path) :
everest_device_model_storage(std::make_unique<EverestDeviceModelStorage>()),
libocpp_device_model_storage(std::make_unique<ocpp::v201::DeviceModelStorageSqlite>(
libocpp_device_model_storage_address, device_model_migration_path, device_model_config_path,
libocpp_initialize_device_model)),
device_model_map(get_device_model()) {
}

ocpp::v201::DeviceModelMap ComposedDeviceModelStorage::get_device_model() {
ocpp::v201::DeviceModelMap everest_dm = everest_device_model_storage->get_device_model();
ocpp::v201::DeviceModelMap libocpp_dm = libocpp_device_model_storage->get_device_model();
everest_dm.merge(libocpp_dm);
return everest_dm;
}

std::optional<ocpp::v201::VariableAttribute>
ComposedDeviceModelStorage::get_variable_attribute(const ocpp::v201::Component& component_id,
const ocpp::v201::Variable& variable_id,
const ocpp::v201::AttributeEnum& attribute_enum) {
if (get_variable_source(component_id, variable_id) == VARIABLE_SOURCE_OCPP) {
return libocpp_device_model_storage->get_variable_attribute(component_id, variable_id, attribute_enum);
}

return everest_device_model_storage->get_variable_attribute(component_id, variable_id, attribute_enum);
}

std::vector<ocpp::v201::VariableAttribute>
ComposedDeviceModelStorage::get_variable_attributes(const ocpp::v201::Component& component_id,
const ocpp::v201::Variable& variable_id,
const std::optional<ocpp::v201::AttributeEnum>& attribute_enum) {
if (get_variable_source(component_id, variable_id) == VARIABLE_SOURCE_OCPP) {
return libocpp_device_model_storage->get_variable_attributes(component_id, variable_id, attribute_enum);
}

return everest_device_model_storage->get_variable_attributes(component_id, variable_id, attribute_enum);
}

bool ComposedDeviceModelStorage::set_variable_attribute_value(const ocpp::v201::Component& component_id,
const ocpp::v201::Variable& variable_id,
const ocpp::v201::AttributeEnum& attribute_enum,
const std::string& value, const std::string& source) {
if (get_variable_source(component_id, variable_id) == VARIABLE_SOURCE_OCPP) {
return libocpp_device_model_storage->set_variable_attribute_value(component_id, variable_id, attribute_enum,
value, source);
}
return everest_device_model_storage->set_variable_attribute_value(component_id, variable_id, attribute_enum, value,
source);
}

std::optional<ocpp::v201::VariableMonitoringMeta>
ComposedDeviceModelStorage::set_monitoring_data(const ocpp::v201::SetMonitoringData& data,
const ocpp::v201::VariableMonitorType type) {
return libocpp_device_model_storage->set_monitoring_data(data, type);
}

bool ComposedDeviceModelStorage::update_monitoring_reference(const int32_t monitor_id,
const std::string& reference_value) {
return libocpp_device_model_storage->update_monitoring_reference(monitor_id, reference_value);
}

std::vector<ocpp::v201::VariableMonitoringMeta>
ComposedDeviceModelStorage::get_monitoring_data(const std::vector<ocpp::v201::MonitoringCriterionEnum>& criteria,
const ocpp::v201::Component& component_id,
const ocpp::v201::Variable& variable_id) {
if (get_variable_source(component_id, variable_id) == VARIABLE_SOURCE_OCPP) {
return libocpp_device_model_storage->get_monitoring_data(criteria, component_id, variable_id);
}

return everest_device_model_storage->get_monitoring_data(criteria, component_id, variable_id);
}

ocpp::v201::ClearMonitoringStatusEnum ComposedDeviceModelStorage::clear_variable_monitor(int monitor_id,
bool allow_protected) {
return libocpp_device_model_storage->clear_variable_monitor(monitor_id, allow_protected);
}

int32_t ComposedDeviceModelStorage::clear_custom_variable_monitors() {
return libocpp_device_model_storage->clear_custom_variable_monitors();
}

void ComposedDeviceModelStorage::check_integrity() {
everest_device_model_storage->check_integrity();
libocpp_device_model_storage->check_integrity();
}

std::string
module::device_model::ComposedDeviceModelStorage::get_variable_source(const ocpp::v201::Component& component,
const ocpp::v201::Variable& variable) {
std::optional<std::string> variable_source = device_model_map[component][variable].source;
if (variable_source.has_value() && variable_source.value() != VARIABLE_SOURCE_OCPP) {
// For now, this just throws because we only have the libocpp source. When the config service is
// implemented, this should not throw.
throw ocpp::v201::DeviceModelError("Source is not 'OCPP', not sure what to do");
}

return VARIABLE_SOURCE_OCPP;
}

} // namespace module::device_model
54 changes: 54 additions & 0 deletions modules/OCPP201/device_model/composed_device_model_storage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest

#pragma once

#include <device_model/everest_device_model_storage.hpp>
#include <ocpp/v201/device_model_storage_interface.hpp>
#include <ocpp/v201/device_model_storage_sqlite.hpp>

namespace module::device_model {
class ComposedDeviceModelStorage : public ocpp::v201::DeviceModelStorageInterface {
private: // Members
std::unique_ptr<EverestDeviceModelStorage> everest_device_model_storage;
std::unique_ptr<ocpp::v201::DeviceModelStorageSqlite> libocpp_device_model_storage;
ocpp::v201::DeviceModelMap device_model_map;

public:
ComposedDeviceModelStorage(const std::string& libocpp_device_model_storage_address,
const bool libocpp_initialize_device_model,
const std::string& device_model_migration_path,
const std::string& device_model_config_path);
virtual ~ComposedDeviceModelStorage() override = default;
virtual ocpp::v201::DeviceModelMap get_device_model() override;
virtual std::optional<ocpp::v201::VariableAttribute>
get_variable_attribute(const ocpp::v201::Component& component_id, const ocpp::v201::Variable& variable_id,
const ocpp::v201::AttributeEnum& attribute_enum) override;
virtual std::vector<ocpp::v201::VariableAttribute>
get_variable_attributes(const ocpp::v201::Component& component_id, const ocpp::v201::Variable& variable_id,
const std::optional<ocpp::v201::AttributeEnum>& attribute_enum) override;
virtual bool set_variable_attribute_value(const ocpp::v201::Component& component_id,
const ocpp::v201::Variable& variable_id,
const ocpp::v201::AttributeEnum& attribute_enum, const std::string& value,
const std::string& source) override;
virtual std::optional<ocpp::v201::VariableMonitoringMeta>
set_monitoring_data(const ocpp::v201::SetMonitoringData& data, const ocpp::v201::VariableMonitorType type) override;
virtual bool update_monitoring_reference(const int32_t monitor_id, const std::string& reference_value) override;
virtual std::vector<ocpp::v201::VariableMonitoringMeta>
get_monitoring_data(const std::vector<ocpp::v201::MonitoringCriterionEnum>& criteria,
const ocpp::v201::Component& component_id, const ocpp::v201::Variable& variable_id) override;
virtual ocpp::v201::ClearMonitoringStatusEnum clear_variable_monitor(int monitor_id, bool allow_protected) override;
virtual int32_t clear_custom_variable_monitors() override;
virtual void check_integrity() override;

private: // Functions
///
/// \brief Get variable source of given variable.
/// \param component Component the variable belongs to.
/// \param variable The variable to get the source from.
/// \return The variable source. Defaults to 'OCPP'.
/// \throws DeviceModelError When source is something else than 'OCPP' (not implemented yet)
///
std::string get_variable_source(const ocpp::v201::Component& component, const ocpp::v201::Variable& variable);
};
} // namespace module::device_model
62 changes: 62 additions & 0 deletions modules/OCPP201/device_model/everest_device_model_storage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest

#include <device_model/everest_device_model_storage.hpp>

namespace module::device_model {
ocpp::v201::DeviceModelMap EverestDeviceModelStorage::get_device_model() {
return {};
}

std::optional<ocpp::v201::VariableAttribute>
EverestDeviceModelStorage::get_variable_attribute(const ocpp::v201::Component& /*component_id*/,
const ocpp::v201::Variable& /*variable_id*/,
const ocpp::v201::AttributeEnum& /*attribute_enum*/) {
return std::nullopt;
}

std::vector<ocpp::v201::VariableAttribute>
EverestDeviceModelStorage::get_variable_attributes(const ocpp::v201::Component& /*component_id*/,
const ocpp::v201::Variable& /*variable_id*/,
const std::optional<ocpp::v201::AttributeEnum>& /*attribute_enum*/) {
return {};
}

bool EverestDeviceModelStorage::set_variable_attribute_value(const ocpp::v201::Component& /*component_id*/,
const ocpp::v201::Variable& /*variable_id*/,
const ocpp::v201::AttributeEnum& /*attribute_enum*/,
const std::string& /*value*/,
const std::string& /*source*/) {
return false;
}

std::optional<ocpp::v201::VariableMonitoringMeta>
EverestDeviceModelStorage::set_monitoring_data(const ocpp::v201::SetMonitoringData& /*data*/,
const ocpp::v201::VariableMonitorType /*type*/) {
return std::nullopt;
}

bool EverestDeviceModelStorage::update_monitoring_reference(const int32_t /*monitor_id*/,
const std::string& /*reference_value*/) {
return false;
}

std::vector<ocpp::v201::VariableMonitoringMeta>
EverestDeviceModelStorage::get_monitoring_data(const std::vector<ocpp::v201::MonitoringCriterionEnum>& /*criteria*/,
const ocpp::v201::Component& /*component_id*/,
const ocpp::v201::Variable& /*variable_id*/) {
return {};
}

ocpp::v201::ClearMonitoringStatusEnum EverestDeviceModelStorage::clear_variable_monitor(int /*monitor_id*/,
bool /*allow_protected*/) {
return ocpp::v201::ClearMonitoringStatusEnum::NotFound;
}

int32_t EverestDeviceModelStorage::clear_custom_variable_monitors() {
return 0;
}

void EverestDeviceModelStorage::check_integrity() {
}
} // namespace module::device_model
33 changes: 33 additions & 0 deletions modules/OCPP201/device_model/everest_device_model_storage.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest

#pragma once

#include <ocpp/v201/device_model_storage_interface.hpp>

namespace module::device_model {
class EverestDeviceModelStorage : public ocpp::v201::DeviceModelStorageInterface {
public:
virtual ~EverestDeviceModelStorage() override = default;
virtual ocpp::v201::DeviceModelMap get_device_model() override;
virtual std::optional<ocpp::v201::VariableAttribute>
get_variable_attribute(const ocpp::v201::Component& component_id, const ocpp::v201::Variable& variable_id,
const ocpp::v201::AttributeEnum& attribute_enum) override;
virtual std::vector<ocpp::v201::VariableAttribute>
get_variable_attributes(const ocpp::v201::Component& component_id, const ocpp::v201::Variable& variable_id,
const std::optional<ocpp::v201::AttributeEnum>& attribute_enum) override;
virtual bool set_variable_attribute_value(const ocpp::v201::Component& component_id,
const ocpp::v201::Variable& variable_id,
const ocpp::v201::AttributeEnum& attribute_enum, const std::string& value,
const std::string& source) override;
virtual std::optional<ocpp::v201::VariableMonitoringMeta>
set_monitoring_data(const ocpp::v201::SetMonitoringData& data, const ocpp::v201::VariableMonitorType type) override;
virtual bool update_monitoring_reference(const int32_t monitor_id, const std::string& reference_value) override;
virtual std::vector<ocpp::v201::VariableMonitoringMeta>
get_monitoring_data(const std::vector<ocpp::v201::MonitoringCriterionEnum>& criteria,
const ocpp::v201::Component& component_id, const ocpp::v201::Variable& variable_id) override;
virtual ocpp::v201::ClearMonitoringStatusEnum clear_variable_monitor(int monitor_id, bool allow_protected) override;
virtual int32_t clear_custom_variable_monitors() override;
virtual void check_integrity() override;
};
} // namespace module::device_model
Loading

0 comments on commit cd5190a

Please sign in to comment.