84 const std::string& updateCache,
const std::string& dataConsistencyRealmName)
86 if(cacheFileExists() && isCachingEnabled()) {
89 _catalogueFromCache =
true;
92 if(updateCache ==
"1") {
93 std::thread(fetchCatalogue, serverAddress, cacheFile, _cancelFlag.get_future()).detach();
99 std::async(std::launch::async, fetchCatalogue, serverAddress, cacheFile, _cancelFlag.get_future());
105 doocs::zmq_set_subscription_timeout(10);
107 _dataConsistencyRealm = async::DataConsistencyRealmStore::getInstance().getRealm(dataConsistencyRealmName);
145 std::string address, std::map<std::string, std::string> parameters) {
147 if(address.empty()) {
148 RegisterPath serverAddress;
149 serverAddress /= parameters[
"facility"];
150 serverAddress /= parameters[
"device"];
151 serverAddress /= parameters[
"location"];
152 address = std::string(serverAddress).substr(1);
154 std::string cacheFile{};
155 std::string updateCache{
"0"};
157 cacheFile = parameters.at(
"cacheFile");
158 updateCache = parameters.at(
"updateCache");
160 catch(std::out_of_range&) {
165 std::string dataConsistencyRealmName{
"doocsEventId"};
166 if(parameters.find(
"dataConsistencyRealmName") != parameters.end()) {
167 dataConsistencyRealmName = parameters.at(
"dataConsistencyRealmName");
171 return boost::shared_ptr<DeviceBackend>(
172 new DoocsBackend(address, cacheFile, updateCache, dataConsistencyRealmName));
178 std::unique_lock<std::mutex> lk(_mxRecovery);
179 if(lastFailedAddress !=
"") {
182 ea.adr(lastFailedAddress);
184 doocs::EqData src, dst;
185 int rc = eq.get(&ea, &src, &dst);
189 auto message = std::string(
"Cannot read from DOOCS property: ") + dst.get_string();
190 setException(message);
191 throw ChimeraTK::runtime_error(message);
193 lastFailedAddress =
"";
196 setOpenedAndClearException();
200 if(!_catalogueFromCache && !_catalogueFuture.valid() && !catalogue.
isComplete()) {
201 _cancelFlag = std::promise<void>{};
203 std::async(std::launch::async, fetchCatalogue,
_serverAddress, _cacheFile, _cancelFlag.get_future());
270 const RegisterPath& registerPathName,
size_t numberOfWords,
size_t wordOffsetInRegister, AccessModeFlags flags) {
271 boost::shared_ptr<NDRegisterAccessor<UserType>> p;
275 bool hasExtraLevel =
false;
276 if(!boost::starts_with(path,
"doocs://") && !boost::starts_with(path,
"epics://")) {
277 size_t nSlashes = std::count(path.begin(), path.end(),
'/');
279 hasExtraLevel =
true;
281 else if(nSlashes < 3 || nSlashes > 4) {
282 throw ChimeraTK::logic_error(std::string(
"DOOCS address has an illegal format: ") + path);
285 else if(boost::starts_with(path,
"doocs://")) {
286 size_t nSlashes = std::count(path.begin(), path.end(),
'/');
288 if(nSlashes == 4 + 3) {
289 hasExtraLevel =
true;
291 else if(nSlashes < 3 + 3 || nSlashes > 4 + 3) {
292 throw ChimeraTK::logic_error(std::string(
"DOOCS address has an illegal format: ") + path);
299 field = path.substr(path.find_last_of(
'/') + 1);
300 path = path.substr(0, path.find_last_of(
'/'));
304 int doocsTypeId = DATA_NULL;
308 doocs::EqData src, dst;
310 int rc = eq.get(&ea, &src, &dst);
312 if(rc == eq_errors::ill_property || rc == eq_errors::ill_location ||
313 rc == eq_errors::ill_address) {
314 throw ChimeraTK::logic_error(
"Property does not exist: " + path +
"': " + dst.get_string());
319 doocsTypeId = dst.type();
324 if(doocsTypeId == DATA_NULL) {
326 doocsTypeId = reg.doocsTypeId;
330 bool extraLevelUsed =
false;
331 auto sharedThis = boost::static_pointer_cast<DoocsBackend>(shared_from_this());
333 if(field ==
"eventId") {
334 extraLevelUsed =
true;
337 else if(field ==
"timeStamp") {
338 extraLevelUsed =
true;
342 switch(doocsTypeId) {
364 sharedThis, path, registerPathName, numberOfWords, wordOffsetInRegister, flags));
369 sharedThis, path, registerPathName, numberOfWords, wordOffsetInRegister, flags));
374 throw ChimeraTK::logic_error(
"DOOCS property of IFFF type '" +
_serverAddress + registerPathName +
375 "' cannot be accessed as a whole.");
377 extraLevelUsed =
true;
379 sharedThis, path, field, registerPathName, numberOfWords, wordOffsetInRegister, flags));
385 sharedThis, path, registerPathName, numberOfWords, wordOffsetInRegister, flags));
390 sharedThis, path, registerPathName, numberOfWords, wordOffsetInRegister, flags);
391 if constexpr(std::is_same_v<UserType, std::uint8_t>) {
395 boost::shared_ptr<NDRegisterAccessor<std::uint8_t>> pImpl(accImpl);
397 boost::shared_ptr<NDRegisterAccessor<UserType>> accDecorated(
398 new TypeChangingRangeCheckingDecorator<UserType, std::uint8_t>(
399 boost::dynamic_pointer_cast<ChimeraTK::NDRegisterAccessor<std::uint8_t>>(pImpl)));
406 throw ChimeraTK::logic_error(
"Unsupported DOOCS data type " +
407 std::string(doocs::EqData().type_string(doocsTypeId)) +
" of property '" +
_serverAddress +
408 registerPathName +
"'");
413 if(hasExtraLevel && !extraLevelUsed) {
414 throw ChimeraTK::logic_error(
"Specifiaction of field name is not supported for the DOOCS data type " +
415 std::string(doocs::EqData().type_string(doocsTypeId)) +
": " +
_serverAddress + registerPathName);
418 p->setExceptionBackend(shared_from_this());