is_allowed definition and how it works

Hello.

I have a device which has multiple sensors. If any sensor is not connected, "read value" is set to 0 and "error value" is set to True for it in the device.

So I have two types of attributes - "values" and "errors".
Attributes are inited dynamically and "fisallowed" function is assigned to value type, global for all attributes. (in PyTango)
I want to dissalow attribute read if error value for sensor is True.

But in "fisallowed" I can't find out which attribute is currently checked and can't choose which error value to use in the condition.

I've tried to not set value for attribute in the read_attr method (which has info about the attribute) and got event with error:
errors = (DevError(desc = 'Read value for attribute value_1 has not been updated', origin = 'Device_3Impl::read_attributes_no_except', reason = 'API_AttrValueNotSet', severity = tango._tango.ErrSeverity.ERR),)

which is what I actually need.
But I suppose it's not the way Tango was designed.

How can I get attribute name/object in the "is_allowed" method? And what is the difference between "API_AttrNotAllowed" and "API_AttrValueNotSet" errors in this case?
Hi Diego,
not sure I understand your device design, but in principle you may want to map each sensor to a dedicated attribute, which will guarantee that Tango provides a dedicated is_xxx_allowed method. Thus, when a sensor is not connected you can just change the quality…
Edited 3 years ago
I know there is a dedicated method for each attribute, but I don't want to declare it by writing almost the same code multiple times.
What I would like to have in 'fisallowed' can be:
def deny_if_error(self, attr):
if attr.get_name() == 'attr_1':
if self.err_1 == True:
return False
else:
return True
if attr.get_name() == 'attr_2':
if self.err_2 == True:
return False
else:
return True


if attr.get_name() == 'attr_n':
if self.err_n == True:
return False
else:
return True


Or in short form:
def deny_if_error(self, attr):
attr_id = int(attr.get_name().split('_')[1]) # get number from attr name
if getattr(self, f'err_{attr_id}') == True:
return False
else:
return True
Diego
I've tried to not set value for attribute in the read_attr method (which has info about the attribute) and got event with error:
errors = (DevError(desc = 'Read value for attribute value_1 has not been updated', origin = 'Device_3Impl::read_attributes_no_except', reason = 'API_AttrValueNotSet', severity = tango._tango.ErrSeverity.ERR),)

which is what I actually need.
But I suppose it's not the way Tango was designed.

If I were you, I would simply throw an exception directly from your read_attr method or set the value attribute quality factor to INVALID when your sensor is not connected.

Diego
How can I get attribute name/object in the "is_allowed" method?

If I understood correctly, you are creating your attributes values and errors dynamically.
I don't know how pytango works in this case.

Diego
And what is the difference between "API_AttrNotAllowed" and "API_AttrValueNotSet" errors in this case?

I think API_AttrNotAllowed exception is thrown by the Tango library when the corresponding is_allowed method is returning false.
As you have noticed, API_AttrValueNotSet exception is thrown by the Tango library when the attribute value has not been set in the read_attr method using attr.set_value().
I personally consider this as a Device Server Programmer error so I consider this as a bad practice to not call attr.set_value in the read_attr method, except if you throw an exception yourself in this method.
Rosenberg's Law: Software is easy to make, except when you want it to do something new.
Corollary: The only software that's worth making is software that does something new.
Diego
But in "fisallowed" I can't find out which attribute is currently checked and can't choose which error value to use in the condition.

I actually don't think you can get the attribute name from this is_allowed method.
The method is normally there to help for the implementation of the State Machine.
In the case of dynamic attributes, the same is_allowed method is invoked for all the similar dynamic attributes.
The goal of this method is originally to look at the current device state and to allow or deny reading of the dynamic attributes of that kind depending on the current state.
The attribute name is not passed to this method. The attr parameter is actually a parameter of Tango::AttReqType type and has nothing to do with the attr parameter passed to the read_attr method which is of type Tango::Attribute.
Rosenberg's Law: Software is easy to make, except when you want it to do something new.
Corollary: The only software that's worth making is software that does something new.
Edited 3 years ago
Reynald
If I were you, I would simply throw an exception directly from your read_attr method or set the value attribute quality factor to INVALID when your sensor is not connected.

Thanks Reynald, I've tried these options and both work as I need to for that device.
Exceptions are useful if I want more detailed info about what happened.
If it doesn't really matter, INVALID quality is enough.
 
Register or login to create to post a reply.