4#ifndef DEVICE_MODEL_HPP
5#define DEVICE_MODEL_HPP
9#include <everest/logging.hpp>
11#include <ocpp/v2/device_model_storage_interface.hpp>
19 GetVariableStatusEnum status;
20 std::optional<T> value;
27template <
typename T> T to_specific_type(
const std::string& value) {
28 static_assert(std::is_same<T, std::string>::value || std::is_same<T, int>::value ||
29 std::is_same<T, double>::value || std::is_same<T, size_t>::value ||
30 std::is_same<T, DateTime>::value || std::is_same<T, bool>::value ||
31 std::is_same<T, uint64_t>::value,
32 "Requested unknown datatype");
34 if constexpr (std::is_same<T, std::string>::value) {
36 }
else if constexpr (std::is_same<T, int>::value) {
37 return std::stoi(value);
38 }
else if constexpr (std::is_same<T, double>::value) {
39 return std::stod(value);
40 }
else if constexpr (std::is_same<T, size_t>::value) {
41 size_t res = std::stoul(value);
43 }
else if constexpr (std::is_same<T, DateTime>::value) {
44 return DateTime(value);
45 }
else if constexpr (std::is_same<T, bool>::value) {
46 return ocpp::conversions::string_to_bool(value);
47 }
else if constexpr (std::is_same<T, uint64_t>::value) {
48 return std::stoull(value);
52template <DataEnum T>
auto to_specific_type_auto(
const std::string& value) {
53 static_assert(T == DataEnum::string || T == DataEnum::integer || T == DataEnum::decimal ||
54 T == DataEnum::dateTime || T == DataEnum::boolean,
55 "Requested unknown datatype");
57 if constexpr (T == DataEnum::string) {
58 return to_specific_type<std::string>(value);
59 }
else if constexpr (T == DataEnum::integer) {
60 return to_specific_type<int>(value);
61 }
else if constexpr (T == DataEnum::decimal) {
62 return to_specific_type<double>(value);
63 }
else if constexpr (T == DataEnum::dateTime) {
64 return to_specific_type<DateTime>(value);
65 }
else if constexpr (T == DataEnum::boolean) {
66 return to_specific_type<bool>(value);
70template <DataEnum T>
bool is_type_numeric() {
71 static_assert(T == DataEnum::string || T == DataEnum::integer || T == DataEnum::decimal ||
72 T == DataEnum::dateTime || T == DataEnum::boolean || T == DataEnum::OptionList ||
73 T == DataEnum::SequenceList || T == DataEnum::MemberList,
74 "Requested unknown datatype");
76 if constexpr (T == DataEnum::integer || T == DataEnum::decimal) {
83typedef std::function<void(
const std::unordered_map<int64_t, VariableMonitoringMeta>& monitors,
84 const Component& component,
const Variable& variable,
85 const VariableCharacteristics& characteristics,
const VariableAttribute& attribute,
86 const std::string& value_previous,
const std::string& value_current)>
89typedef std::function<void(
const VariableMonitoringMeta& updated_monitor,
const Component& component,
90 const Variable& variable,
const VariableCharacteristics& characteristics,
91 const VariableAttribute& attribute,
const std::string& current_value)>
99 DeviceModelMap device_model_map;
100 std::unique_ptr<DeviceModelStorageInterface> device_model;
103 on_variable_changed variable_listener;
105 on_monitor_updated monitor_update_listener;
116 GetVariableStatusEnum request_value_internal(
const Component& component_id,
const Variable& variable_id,
117 const AttributeEnum& attribute_enum, std::string& value,
118 bool allow_write_only)
const;
127 bool component_criteria_match(
const Component& component_id,
128 const std::vector<ComponentCriterionEnum>& component_criteria);
135 bool component_variables_match(
const std::vector<ComponentVariable>& component_variables,
141 explicit DeviceModel(std::unique_ptr<DeviceModelStorageInterface> device_model_storage_interface);
149 template <
typename T>
151 const AttributeEnum& attribute_enum = AttributeEnum::Actual)
const {
153 auto response = GetVariableStatusEnum::UnknownVariable;
154 if (component_variable.variable.has_value()) {
155 response = this->request_value_internal(component_variable.component, component_variable.variable.value(),
156 attribute_enum, value,
true);
158 if (response == GetVariableStatusEnum::Accepted) {
159 return to_specific_type<T>(value);
161 EVLOG_critical <<
"Directly requested value for ComponentVariable that doesn't exist in the device model: "
162 << component_variable;
163 EVLOG_AND_THROW(std::runtime_error(
164 "Directly requested value for ComponentVariable that doesn't exist in the device model."));
174 template <
typename T>
176 const AttributeEnum& attribute_enum = AttributeEnum::Actual)
const {
178 auto response = GetVariableStatusEnum::UnknownVariable;
179 if (component_variable.variable.has_value()) {
180 response = this->request_value_internal(component_variable.component, component_variable.variable.value(),
181 attribute_enum, value,
true);
183 if (response == GetVariableStatusEnum::Accepted) {
184 return to_specific_type<T>(value);
198 template <
typename T>
200 const AttributeEnum& attribute_enum) {
202 const auto req_status = this->request_value_internal(component_id, variable_id, attribute_enum, value,
false);
204 if (req_status == GetVariableStatusEnum::Accepted) {
205 return {GetVariableStatusEnum::Accepted, to_specific_type<T>(value)};
217 const AttributeEnum& attribute_enum);
230 const AttributeEnum& attribute_enum,
const std::string& value,
231 const std::string& source,
const bool allow_read_only =
false);
241 const AttributeEnum& attribute_enum,
const std::string& value,
242 const std::string& source);
264 std::vector<ReportData>
265 get_custom_report_data(
const std::optional<std::vector<ComponentVariable>>& component_variables = std::nullopt,
266 const std::optional<std::vector<ComponentCriterionEnum>>& component_criteria = std::nullopt);
268 void register_variable_listener(on_variable_changed&& listener) {
269 variable_listener = std::move(listener);
272 void register_monitor_listener(on_monitor_updated&& listener) {
273 monitor_update_listener = std::move(listener);
282 std::vector<SetMonitoringResult>
set_monitors(
const std::vector<SetMonitoringData>& requests,
283 const VariableMonitorType type = VariableMonitorType::CustomMonitor);
285 bool update_monitor_reference(int32_t monitor_id,
const std::string& reference_value);
287 std::vector<VariableMonitoringPeriodic> get_periodic_monitors();
293 std::vector<MonitoringData>
get_monitors(
const std::vector<MonitoringCriterionEnum>& criteria,
294 const std::vector<ComponentVariable>& component_variables);
301 std::vector<ClearMonitoringResult>
clear_monitors(
const std::vector<int>& request_ids,
302 bool allow_protected =
false);
310 void check_integrity(
const std::map<int32_t, int32_t>& evse_connector_structure);
This class manages access to the device model representation and to the device model interface and pr...
Definition: device_model.hpp:96
std::vector< ReportData > get_custom_report_data(const std::optional< std::vector< ComponentVariable > > &component_variables=std::nullopt, const std::optional< std::vector< ComponentCriterionEnum > > &component_criteria=std::nullopt)
Gets the ReportData for the specifed filter component_variables and component_criteria.
Definition: device_model.cpp:391
std::optional< MutabilityEnum > get_mutability(const Component &component_id, const Variable &variable, const AttributeEnum &attribute_enum)
Get the mutability for the given component, variable and attribute_enum.
Definition: device_model.cpp:253
std::vector< ReportData > get_base_report_data(const ReportBaseEnum &report_base)
Gets the ReportData for the specifed filter report_base component_variables and component_criteria.
Definition: device_model.cpp:349
SetVariableStatusEnum set_read_only_value(const Component &component_id, const Variable &variable_id, const AttributeEnum &attribute_enum, const std::string &value, const std::string &source)
Sets the variable_id attribute value specified by component_id , variable_id and attribute_enum for r...
Definition: device_model.cpp:329
void check_integrity(const std::map< int32_t, int32_t > &evse_connector_structure)
Check data integrity of the device model provided by the device model data storage: For "required" va...
Definition: device_model.cpp:423
std::optional< VariableMetaData > get_variable_meta_data(const Component &component_id, const Variable &variable_id)
Gets the VariableMetaData for the given component_id and variable_id.
Definition: device_model.cpp:340
RequestDeviceModelResponse< T > request_value(const Component &component_id, const Variable &variable_id, const AttributeEnum &attribute_enum)
Requests a value of a VariableAttribute specified by combination of component_id and variable_id from...
Definition: device_model.hpp:199
std::optional< T > get_optional_value(const ComponentVariable &component_variable, const AttributeEnum &attribute_enum=AttributeEnum::Actual) const
Access to std::optional of a VariableAttribute for the given component, variable and attribute_enum.
Definition: device_model.hpp:175
std::vector< MonitoringData > get_monitors(const std::vector< MonitoringCriterionEnum > &criteria, const std::vector< ComponentVariable > &component_variables)
Gets the Monitoring data for the request criteria and component_variables.
Definition: device_model.cpp:731
T get_value(const RequiredComponentVariable &component_variable, const AttributeEnum &attribute_enum=AttributeEnum::Actual) const
Direct access to value of a VariableAttribute for the given component, variable and attribute_enum....
Definition: device_model.hpp:150
std::vector< ClearMonitoringResult > clear_monitors(const std::vector< int > &request_ids, bool allow_protected=false)
Clears the given request_ids from the registered monitors if request_id is present.
Definition: device_model.cpp:811
SetVariableStatusEnum set_value(const Component &component_id, const Variable &variable_id, const AttributeEnum &attribute_enum, const std::string &value, const std::string &source, const bool allow_read_only=false)
Sets the variable_id attribute value specified by component_id , variable_id and attribute_enum.
Definition: device_model.cpp:263
DeviceModel(std::unique_ptr< DeviceModelStorageInterface > device_model_storage_interface)
Constructor for the device model.
Definition: device_model.cpp:324
int32_t clear_custom_monitors()
Clears all the custom monitors (set by the CSMS) present in the database.
Definition: device_model.cpp:846
std::vector< SetMonitoringResult > set_monitors(const std::vector< SetMonitoringData > &requests, const VariableMonitorType type=VariableMonitorType::CustomMonitor)
Sets the given monitor requests in the device model.
Definition: device_model.cpp:533
Definition: ocpp_types.hpp:334
Definition: ocpp_types.hpp:303
Response to requesting a value from the device model.
Definition: device_model.hpp:18
Definition: ocpp_types.hpp:969
Definition: ocpp_types.hpp:319