32 #include "eds_library.h"
33 #include "eds_reader.h"
36 #include "canopen_error.h"
39 #include "global_config.h"
43 #include <unordered_map>
45 #include <boost/filesystem.hpp>
46 #include <boost/property_tree/ptree.hpp>
47 #include <boost/property_tree/json_parser.hpp>
55 namespace fs = boost::filesystem;
57 EDSLibrary::EDSLibrary(std::unordered_map<Address, Entry>& dictionary, std::unordered_map<std::string, Address>& name_to_address)
58 : m_dictionary(dictionary), m_name_to_address(name_to_address), m_ready(false)
65 std::vector<std::string> paths;
67 paths.push_back(path+
"/eds_files.json");
70 paths.push_back(SHARE_SOURCE_PATH
"/eds_library/eds_files.json");
71 paths.push_back(SHARE_INSTALLED_PATH
"/eds_library/eds_files.json");
72 paths.push_back(
"/usr/local/share/kacanopen/eds_library/eds_files.json");
73 paths.push_back(
"/usr/share/kacanopen/eds_library/eds_files.json");
78 for (
const std::string& path : paths) {
79 if (fs::exists(path)) {
80 m_library_path = fs::path(path).parent_path().string();
81 DEBUG_LOG(
"[EDSLibrary::lookup_library] Found EDS library in "<<m_library_path);
88 DEBUG_LOG(
"[EDSLibrary::lookup_library] Could not find EDS library. You should pass a custum path or check your local installation.")
104 std::string path = m_library_path +
"/CiA_profiles/"+std::to_string(device_profile_number)+
".eds";
105 if (!fs::exists(path)) {
106 DEBUG_LOG(
"[EDSLibrary::load_default_eds] Default EDS file not available: "<<path);
115 EDSReader reader(m_dictionary, m_name_to_address);
119 ERROR(
"[EDSLibrary::load_default_eds] Loading file not successful.");
123 DEBUG_LOG(
"[EDSLibrary::load_default_eds] Found EDS file: "<<path);
125 most_recent_eds_file = path;
128 ERROR(
"[EDSLibrary::load_default_eds] Importing entries failed.");
138 boost::property_tree::ptree eds_files;
139 boost::property_tree::json_parser::read_json(m_library_path+
"/eds_files.json", eds_files);
140 std::unordered_map<std::string,Value> cache;
142 for (
const auto& level0 : eds_files) {
144 const std::string& filename = level0.second.get<std::string>(
"file");
145 DEBUG_LOG(
"Testing if "<<filename<<
" fits.");
146 const boost::property_tree::ptree& matches = level0.second.get_child(
"match");
149 for (
const auto& level1 : matches) {
151 const std::string& field = level1.first;
152 const std::string& value_expected = level1.second.get_value<std::string>();
153 bool has_field =
false;
155 if (cache.count(field)>0) {
157 if (cache[field].type != Type::invalid) {
166 DEBUG_LOG(
" ("<<err.what()<<
")");
167 cache[field] =
Value();
172 const std::string& value = cache[field].to_string().substr(0,value_expected.length());
173 if (value_expected == value) {
174 DEBUG_LOG(
" "<<field<<
": "<<value<<
" == "<<value_expected<<
" (expected) -> continue.");
176 DEBUG_LOG(
" "<<field<<
": "<<value<<
" != "<<value_expected<<
" (expected) -> break.");
180 DEBUG_LOG(
" Field does not exist -> break...");
192 DEBUG_LOG(
" "<<filename<<
" fits.");
193 const std::string path = m_library_path +
"/"+filename;
194 assert(fs::exists(path));
200 EDSReader reader(m_dictionary, m_name_to_address);
204 ERROR(
"[EDSLibrary::load_manufacturer_eds] Loading file not successful.");
209 most_recent_eds_file = path;
212 ERROR(
"[EDSLibrary::load_manufacturer_eds] Importing entries failed.");
219 DEBUG_LOG(
" "<<filename<<
" does not fit.");
224 DEBUG_LOG(
"No suitable manufacturer EDS file found.");
233 std::string path = m_library_path +
"/"+std::to_string(vendor_id)+
"/"+std::to_string(product_code)+
"."+std::to_string(revision_number)+
".eds";
234 if (!fs::exists(path)) {
236 path = m_library_path +
"/"+std::to_string(vendor_id)+
"/"+std::to_string(product_code)+
".eds";
237 if (!fs::exists(path)) {
238 DEBUG_LOG(
"[EDSLibrary::load_manufacturer_eds] Manufacturer device specific EDS file not available: "<<path);
243 DEBUG_LOG(
"[EDSLibrary::load_manufacturer_eds] Found manufacturer EDS: "<<path);
249 EDSReader reader(m_dictionary, m_name_to_address);
251 most_recent_eds_file = path;
254 ERROR(
"[EDSLibrary::load_manufacturer_eds] Loading file not successful.");
261 ERROR(
"[EDSLibrary::load_manufacturer_eds] Importing entries failed.");
274 m_dictionary.clear();
275 m_name_to_address.clear();
279 return most_recent_eds_file;
const Value & get_entry(const std::string &entry_name, const ReadAccessMethod access_method=ReadAccessMethod::use_default)
Gets the value of a dictionary entry by name internally. If there is no cached value or the entry is ...
bool import_entries()
Import entries from the EDS file into the given dictionary.
This class allows reading EDS files (like standardized in CiA 306) and inserting all contained entrie...
bool load_default_eds(uint16_t device_profile_number)
Loads entries defined in generic CiA profile EDS files.
This is the base class of all types of exceptions thrown by the KaCanOpen library. It can be used directly like std::runtime_error if there isn't any more specific error class.
bool load_mandatory_entries()
Loads mandatory dictionary entries defined in CiA 301 standard.
bool lookup_library(std::string path="")
Finds EDS library on disk.
bool load_manufacturer_eds(Device &device)
Loads entries defined in device specific EDS files proviced by manufacturers.
This class represents a CanOpen slave device in the network.
bool ready() const
Checks if lookup_library() was successful.
static bool eds_library_clear_dictionary
If this is set to true, EDSLibrary will clear dictionary and me-to-address mappings before loading an...
bool load_file(std::string filename)
Loads an EDS file from file system.
void reset_dictionary()
Resets the dictionary and the name-address mapping.
EDSLibrary(std::unordered_map< Address, Entry > &dictionary, std::unordered_map< std::string, Address > &name_to_address)
Constructor.
std::string get_most_recent_eds_file_path() const
Returns the path to the most recently loaded EDS file.
This class contains a value to be stored in the object dictionary. The value can have one of the type...
bool load_manufacturer_eds_deprecated(uint32_t vendor_id, uint32_t product_code, uint32_t revision_number)
Loads entries defined in device specific EDS files proviced by manufacturers.