MotionLib  1.0.0
SamBuCa motion library
DeviceStore.cpp
1 /*
2  * Copyright (C) 2021 CERN
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty. In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  * claim that you wrote the original software. If you use this software
14  * in a product, an acknowledgment in the product documentation would be
15  * appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  * misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  *
20  * Created on: 2021-10-27
21  * Author: Michal Mysior <mmysior> <michal.mysior@cern.ch>
22  *
23  */
24 
25 #include "DeviceStore.hpp"
26 
27 #include <memory>
28 #include <sstream>
29 #include <unordered_map>
30 
31 #include <ccut/ryml_internals.hpp>
32 #include <ccut/utils.hpp>
33 #include <logger/Logger.hpp>
34 
35 #include "Exception.hpp"
36 
37 using namespace smc;
38 namespace yml = ccut::yml;
39 
40 static const std::string s_loggerCat{"smc:devicestore"};
41 
42 namespace smc {
43 namespace internal {
44 
45 size_t DeviceStore::probeDevices(const PlatformBase::Shared &platform)
46 {
47  std::size_t newDeviceCount = 0;
48 
49  const std::lock_guard<std::mutex> lock(m_devicesMutex);
50  for (DeviceBase::Shared device :
51  platform->generateDevices(platform->getSupportedDevices()))
52  {
53  logger::notice(s_loggerCat) << "new device: " << device->uid();
54  m_devices[device->uid()] = device;
55  newDeviceCount++;
56  }
57 
58  return newDeviceCount;
59 }
60 
62 {
63  const std::lock_guard<std::mutex> lock(m_devicesMutex);
64  return m_devices.size();
65 }
66 
67 std::shared_ptr<DeviceBase> DeviceStore::getDevice(
68  const std::string &address) const
69 {
70  try
71  {
72  const std::lock_guard<std::mutex> lock{m_devicesMutex};
73  decltype(m_alias)::const_iterator it = m_alias.find(address);
74  return (it != m_alias.end()) ? m_devices.at(it->second) :
75  m_devices.at(address);
76  }
77  catch (const std::out_of_range &e)
78  {
79  throw Exception(ErrorCode::InvalidArguments,
80  "no such device: " + address);
81  }
82 }
83 
84 std::set<DeviceId> DeviceStore::getDeviceList() const
85 {
86  const std::lock_guard<std::mutex> lock(m_devicesMutex);
87  return ccut::keys(m_devices);
88 }
89 
90 std::set<DeviceId> DeviceStore::getDeviceList(DeviceType type) const
91 {
92  std::set<DeviceId> result;
93  const std::lock_guard<std::mutex> lock(m_devicesMutex);
94  for (const decltype(m_devices)::value_type &it : m_devices)
95  {
96  if (type == it.second->type())
97  result.insert(it.first);
98  }
99  return result;
100 }
101 
102 std::set<std::string> DeviceStore::getAliasList() const
103 {
104  const std::lock_guard<std::mutex> lock(m_devicesMutex);
105  return ccut::keys(m_alias);
106 }
107 
108 DeviceId DeviceStore::getAlias(const std::string &alias) const
109 {
110  const std::lock_guard<std::mutex> lock(m_devicesMutex);
111  decltype(m_alias)::const_iterator it = m_alias.find(alias);
112  if (it == m_alias.end())
113  throw Exception(ErrorCode::InvalidArguments, "no such alias");
114  return it->second;
115 }
116 
117 bool DeviceStore::addAlias(const std::string &alias,
118  const DeviceId &deviceId,
119  bool override)
120 {
121  const std::lock_guard<std::mutex> lock(m_devicesMutex);
122  if (override || (m_alias.count(alias) == 0))
123  {
124  m_alias[alias] = deviceId;
125  return true;
126  }
127  return false;
128 }
129 
130 void DeviceStore::removeAlias(const std::string &alias)
131 {
132  const std::lock_guard<std::mutex> lock(m_devicesMutex);
133  m_alias.erase(alias);
134 }
135 
136 void DeviceStore::loadAlias(const ccut::yml::NodeRef &aliasNode,
137  const ccut::yml::Parser *)
138 {
139  try
140  {
141  if (!aliasNode.valid() || !aliasNode.is_map())
142  throw Exception(ErrorCode::InvalidArguments,
143  "alias node must be a map");
144 
145  for (auto it : aliasNode)
146  {
147  std::string key;
148  std::string value;
149  it >> yml::default_to(yml::key(key), "") >>
150  yml::default_to(value, "");
151  if (!addAlias(key, value, false))
152  logger::warning(s_loggerCat)
153  << "not loading alias " << key << " alias: already exist";
154  }
155  }
156  catch (std::exception &ex)
157  {
158  logger::error(s_loggerCat) << "failed to parse alias: " << ex.what();
159  }
160 }
161 
162 } /* namespace internal */
163 } /* namespace smc */
Exception thrown by MotionController in case of issues with command.
Definition: Exception.hpp:61
DeviceId getAlias(const std::string &alias) const
Get the given alias.
DeviceBase::Shared getDevice(const DeviceId &address) const
Get the Device with specified address.
Definition: DeviceStore.cpp:67
void removeAlias(const std::string &alias)
remove an alias
bool addAlias(const std::string &alias, const DeviceId &deviceId, bool override=true)
add an alias
size_t probeDevices(const PlatformBase::Shared &platform)
Get devices generated by platform and store them.
Definition: DeviceStore.cpp:45
std::set< std::string > getAliasList() const
Get current Alias list.
std::set< DeviceId > getDeviceList() const
Get the complete list of existing devices.
Definition: DeviceStore.cpp:84
size_t getDeviceCount() const
Get the number of devices.
Definition: DeviceStore.cpp:61
void loadAlias(const ccut::yml::NodeRef &aliasNode, const ccut::yml::Parser *parser=nullptr)
load alias from yml node
DeviceType
List of possible device types supported.
Definition: DeviceBase.hpp:52
main motion-lib namespace
Definition: Client.cpp:30