Skip to content
This repository has been archived by the owner on Apr 7, 2022. It is now read-only.

How to work with dev_enum attribute #188

Closed
cmft opened this issue Apr 19, 2018 · 4 comments
Closed

How to work with dev_enum attribute #188

cmft opened this issue Apr 19, 2018 · 4 comments

Comments

@cmft
Copy link

cmft commented Apr 19, 2018

Dear PyTango experts,
I created a dummy DS with a enum scalar attribute using pogo + manual fixes.

When I use PyTango to read the attribute, I got an int value instead an enumeration. When I read the attribute using jive. It returns the Enumeration string ('B') instead of Enumeration index (1).

What I doing wrong? It is something bad defined in the DS .

import PyTango
dp = PyTango.DeviceProxy('testds/test/1')
dp.read_attribute('enum_scalar')
Out[2]: DeviceAttribute(data_format = tango._tango.AttrDataFormat.SCALAR, dim_x = 1, dim_y = 0, has_failed = False, is_empty = False, name = 'enum_scalar', nb_read = 1, nb_written = 0, quality = tango._tango.AttrQuality.ATTR_VALID, r_dimension = AttributeDimension(dim_x = 1, dim_y = 0), time = TimeVal(tv_nsec = 0, tv_sec = 1524131144, tv_usec = 387732), type = tango._tango.CmdArgType.DevEnum, value = 1, w_dim_x = 0, w_dim_y = 0, w_dimension = AttributeDimension(dim_x = 0, dim_y = 0), w_value = None)
type(dp.read_attribute('enum_scalar').value)
Out[4]: int

How should I check the valid values? Assuming consecutive values and comparing with the number of enum labels?

dp.get_attribute_config_ex('enum_scalar')
Out[4]: [AttributeInfoEx(alarms = AttributeAlarmInfo(delta_t = 'Not specified', delta_val = 'Not specified', extensions = [], max_alarm = 'Not specified', max_warning = 'Not specified', min_alarm = 'Not specified', min_warning = 'Not specified'), data_format = tango._tango.AttrDataFormat.SCALAR, data_type = tango._tango.CmdArgType.DevEnum, description = 'No description', disp_level = tango._tango.DispLevel.OPERATOR, display_unit = 'No display unit', enum_labels = ['A', 'B', 'C'], events = AttributeEventInfo(arch_event = ArchiveEventInfo(archive_abs_change = 'Not specified', archive_period = 'Not specified', archive_rel_change = 'Not specified', extensions = []), ch_event = ChangeEventInfo(abs_change = 'Not specified', extensions = [], rel_change = 'Not specified'), per_event = PeriodicEventInfo(extensions = [], period = '1000')), extensions = [], format = '%s', label = 'enum_scalar', max_alarm = 'Not specified', max_dim_x = 1, max_dim_y = 0, max_value = 'Not specified', memorized = tango._tango.AttrMemorizedType.NONE, min_alarm = 'Not specified', min_value = 'Not specified', name = 'enum_scalar', root_attr_name = 'Not specified', standard_unit = 'No standard unit', sys_extensions = [], unit = '', writable = tango._tango.AttrWriteType.WT_UNKNOWN, writable_attr_name = 'enum_scalar')]

By the way I could not find DEV_ENUM type documentation in http://pytango.readthedocs.io/en/stable/data_types.html

Thanks in advance,
Carlos

@vxgmichel
Copy link
Contributor

Hi @cmft, thanks for the report.

When I read the attribute using jive it returns the Enumeration string ('B').

That's the expected behavior right?

You were expecting db.enum_scalar to return 'B'? I think this feature has not been implemented yet.

I don't have time to work on it at the moment, but feel free to submit a PR!

@cmft
Copy link
Author

cmft commented Apr 19, 2018

Hi @vxgmichel ,
Thank for the quick answer!

That's the expected behavior right?

I think so.

You were expecting db.enum_scalar to return 'B'? I think this feature has not been implemented yet.

O even something more, such as an intEnum e.g. tango_enum.B which .value == 1 and .name == 'B'
But I don't know what should be right write value. According to jive should be 'A','B' or 'C'

What do you think?

@vxgmichel
Copy link
Contributor

vxgmichel commented Apr 19, 2018

Or even something more, such as an intEnum e.g. tango_enum.B which .value == 1 and .name == 'B'
But I don't know what should be right write value. According to jive should be 'A','B' or 'C'

I agree, IntEnum seems to be the best candidate, since it's implicitly converted to int when needed. Then the write value could be converted using:

int(MyEnum.__members__.get(value, value))

The following values should then all work: MyEnum.A, 1 or A.

ajoubertza added a commit to ajoubertza/pytango that referenced this issue Jun 15, 2018
TANGO implements DevEnum attributes as an integer value combined
with a list label strings.  The current PyTango implementation
requires the user to fetch the labels separately from the values,
and match them up manually.  This makes it difficult to use.  This new
implementation combines the information to create proper enumerated
types.

#### Client-side changes
When the DeviceProxy reads a DevEnum attribute, a Python
`enum.IntEnum` object is returned instead of just an integer.  This
object can be compared to integers directly, so minimal changes are
expected for old code.  The benefit is that new code using the
enumerations directly will be more readable.

#### Server-side changes
Not much was required here.  Added a utility function that extracts the
labels from an `enum.Enum` class and verifies that the values will work
with the core TANGO implementation.

#### Warning
The `DeviceProxy` maintains a cache of the attributes, which
includes the Enumeration class.  If the device server changes the
enum_labels for an attribute that the DeviceProxy has already cached,
then the DeviceProxy will not know about it.  A new instance of the
DeviceProxy will have to be created after any significant interface
change on the server.

Addresses issue tango-controls#188
@vxgmichel
Copy link
Contributor

Implemented in PR #194, will be available in v9.2.4. Thanks for the report!

tiagocoutinho pushed a commit to tiagocoutinho/pytango that referenced this issue Apr 21, 2019
TANGO implements DevEnum attributes as an integer value combined
with a list label strings.  The current PyTango implementation
requires the user to fetch the labels separately from the values,
and match them up manually.  This makes it difficult to use.  This new
implementation combines the information to create proper enumerated
types.

#### Client-side changes
When the DeviceProxy reads a DevEnum attribute, a Python
`enum.IntEnum` object is returned instead of just an integer.  This
object can be compared to integers directly, so minimal changes are
expected for old code.  The benefit is that new code using the
enumerations directly will be more readable.

#### Server-side changes
Not much was required here.  Added a utility function that extracts the
labels from an `enum.Enum` class and verifies that the values will work
with the core TANGO implementation.

#### Warning
The `DeviceProxy` maintains a cache of the attributes, which
includes the Enumeration class.  If the device server changes the
enum_labels for an attribute that the DeviceProxy has already cached,
then the DeviceProxy will not know about it.  A new instance of the
DeviceProxy will have to be created after any significant interface
change on the server.

Addresses issue tango-controls#188
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants