Problems with device dynamic attributes and wrong error messages
Hi,
After migrating from (py)tango 9.3 to 10.0 we have noticed problems with reading dynamic attributes when we create three or more devices with different dynamic attributes of the same class. The issue was noticed in sardana sardana-org/sardana#2027
It looks like they are two problems
- starting from tango 9.5 in some cases dynamic attributes cannot be read. This issue is not related to tango server side, i.e. the reading on some dynamic attributes returns has_failed=True (to cure it one needs to remove other devices of the same class). The issue is connected to cppTango#814 but it looks like tango 9.3 is working much better than 9.5 and 10.0 (in this case)
- the error messages are messed up e.g. when I try to read EnergyThreshold attribute the error message is related to CountTime
In [1]: import tango
In [2]: dp = tango.DeviceProxy("expchan/lambdalambdactrl/1")
In [3]: dp.EnergyThreshold
---------------------------------------------------------------------------
DevFailed Traceback (most recent call last)
Cell In [3], line 1
----> 1 dp.EnergyThreshold
File /usr/lib/python3/dist-packages/tango/device_proxy.py:485, in __DeviceProxy__getattr(self, name)
483 attr_info = self.__get_attr_cache().get(name_l)
484 if attr_info:
--> 485 return __get_attribute_value(self, attr_info, name)
487 try:
488 self.__refresh_pipe_cache()
File /usr/lib/python3/dist-packages/tango/device_proxy.py:400, in __get_attribute_value(self, attr_info, name)
398 return __async_get_attribute_value(self, attr_info, name)
399 else:
--> 400 return __sync_get_attribute_value(self, attr_info, name)
File /usr/lib/python3/dist-packages/tango/device_proxy.py:392, in __sync_get_attribute_value(self, attr_info, name)
391 def __sync_get_attribute_value(self, attr_info, name):
--> 392 attr_value = self.read_attribute(name).value
393 return __update_enum_values(attr_info, attr_value)
File /usr/lib/python3/dist-packages/tango/green.py:226, in green.<locals>.decorator.<locals>.greener(obj, *args, **kwargs)
224 green_mode = access("green_mode", None)
225 executor = get_object_executor(obj, green_mode)
--> 226 return executor.run(fn, args, kwargs, wait=wait, timeout=timeout)
File /usr/lib/python3/dist-packages/tango/green.py:116, in AbstractExecutor.run(self, fn, args, kwargs, wait, timeout)
114 # Synchronous (no delegation)
115 if not self.asynchronous or not self.in_executor_context():
--> 116 return fn(*args, **kwargs)
117 # Asynchronous delegation
118 accessor = self.delegate(fn, *args, **kwargs)
File /usr/lib/python3/dist-packages/tango/device_proxy.py:594, in __DeviceProxy__read_attribute(self, value, extract_as)
593 def __DeviceProxy__read_attribute(self, value, extract_as=ExtractAs.Numpy):
--> 594 return __check_read_attribute(self._read_attribute(value, extract_as))
File /usr/lib/python3/dist-packages/tango/device_proxy.py:160, in __check_read_attribute(dev_attr)
158 def __check_read_attribute(dev_attr):
159 if dev_attr.has_failed:
--> 160 raise DevFailed(*dev_attr.get_err_stack())
161 return dev_attr
DevFailed: DevFailed[
DevError[
desc = __wrapped_read_CountTime__read_DynamicAttribute__ method not found for EnergyThreshold
origin = PyTango::Attr::read
reason = PyTango_ReadAttributeMethodNotFound
severity = ERR]
DevError[
desc = Failed to read_attribute on device expchan/lambdalambdactrl/1, attribute EnergyThreshold
origin = virtual Tango::DeviceAttribute Tango::DeviceProxy::read_attribute(const std::string&) at (./lib/cpp/src/client/devapi_base.cpp:5673)
reason = API_AttributeFailed
severity = ERR]
]
In [4]: dp._read_attribute("EnergyThreshold")
Out[4]: DeviceAttribute(data_format = tango._tango.AttrDataFormat.FMT_UNKNOWN, dim_x = 0, dim_y = 0, has_failed = True, is_empty = True, name = 'EnergyThreshold', nb_read = 0, nb_written = 0, quality = tango._tango.AttrQuality.ATTR_INVALID, r_dimension = AttributeDimension(dim_x = 0, dim_y = 0), time = TimeVal(tv_nsec = 0, tv_sec = 0, tv_usec = 0), type = tango._tango.CmdArgType(100), value = None, w_dim_x = 0, w_dim_y = 0, w_dimension = AttributeDimension(dim_x = 0, dim_y = 0), w_value = None)
In [5]: dp.read_attribute("EnergyThreshold")
---------------------------------------------------------------------------
DevFailed Traceback (most recent call last)
Cell In [5], line 1
----> 1 dp.read_attribute("EnergyThreshold")
File /usr/lib/python3/dist-packages/tango/green.py:226, in green.<locals>.decorator.<locals>.greener(obj, *args, **kwargs)
224 green_mode = access("green_mode", None)
225 executor = get_object_executor(obj, green_mode)
--> 226 return executor.run(fn, args, kwargs, wait=wait, timeout=timeout)
File /usr/lib/python3/dist-packages/tango/green.py:116, in AbstractExecutor.run(self, fn, args, kwargs, wait, timeout)
114 # Synchronous (no delegation)
115 if not self.asynchronous or not self.in_executor_context():
--> 116 return fn(*args, **kwargs)
117 # Asynchronous delegation
118 accessor = self.delegate(fn, *args, **kwargs)
File /usr/lib/python3/dist-packages/tango/device_proxy.py:594, in __DeviceProxy__read_attribute(self, value, extract_as)
593 def __DeviceProxy__read_attribute(self, value, extract_as=ExtractAs.Numpy):
--> 594 return __check_read_attribute(self._read_attribute(value, extract_as))
File /usr/lib/python3/dist-packages/tango/device_proxy.py:160, in __check_read_attribute(dev_attr)
158 def __check_read_attribute(dev_attr):
159 if dev_attr.has_failed:
--> 160 raise DevFailed(*dev_attr.get_err_stack())
161 return dev_attr
DevFailed: DevFailed[
DevError[
desc = __wrapped_read_CountTime__read_DynamicAttribute__ method not found for EnergyThreshold
origin = PyTango::Attr::read
reason = PyTango_ReadAttributeMethodNotFound
severity = ERR]
DevError[
desc = Failed to read_attribute on device expchan/lambdalambdactrl/1, attribute EnergyThreshold
origin = virtual Tango::DeviceAttribute Tango::DeviceProxy::read_attribute(const std::string&) at (./lib/cpp/src/client/devapi_base.cpp:5673)
reason = API_AttributeFailed
severity = ERR]
]
In [6]: dp._read_attribute("EnergyThreshold")
Out[6]: DeviceAttribute(data_format = tango._tango.AttrDataFormat.FMT_UNKNOWN, dim_x = 0, dim_y = 0, has_failed = True, is_empty = True, name = 'EnergyThreshold', nb_read = 0, nb_written = 0, quality = tango._tango.AttrQuality.ATTR_INVALID, r_dimension = AttributeDimension(dim_x = 0, dim_y = 0), time = TimeVal(tv_nsec = 0, tv_sec = 0, tv_usec = 0), type = tango._tango.CmdArgType(100), value = None, w_dim_x = 0, w_dim_y = 0, w_dimension = AttributeDimension(dim_x = 0, dim_y = 0), w_value = None)
i.e. dev_attr.get_err_stack() provides a wrong error message.
The behavior is quite random so I would call it a bug (not a feature).
We have noticed this problems for tango servers (Pool, Pilc2-dev) written in python but probably the issue is related to changes cpptango (between 9.3 and 9.5).
Best, Jan
Edited by Jan Kotanski