Set of questions

Hi all,

I have few questions, so I will list them down, I think it’s better that way then oppening more topics:

  1. read_attribute_hardware is called each time before atrribute(s) has been read, but I don’t quite see its purpose. After it, functions for each attribute I wanted to read are called. What can I write in read_attribute_hardware method which I code in read_NameOfSomeAttribute methods?

  2. When attribute is R/W or W type, I am able to check write hardware at init option, which will set attribute to specific value when starting server. Where I should type that start value?

  3. I am able to execute commands by entering argin value in hex or decimal form. Can I enter them in binary format?

  4. Even though if an attribute is write type, when I open class state maschine I have Attribute(Read) and Attribute(Write) for checking when is attribute allowed. Why is that?

Thank you for your help.

Hi,

As described in the Tango book, on page 20.

When a client tries to read several attributes on your device (using read_attributes method from DeviceProxy class), read_attr_hardware will be invoked first, and then all the individual attributes read_XXX methods.
(Please note that read_attributes is invoked by the Tango polling thread when you have several attributes polled at the same polling period.)
It could be useful in some specific cases to do something in read_attr_hardware method to optimize performances because it will limit the number of accesses to the hardware and could help to get a consistent snapshot of the current state of your hardware.
Let’s take the example of a PLC which could be used to report the state of some hardware devices.
You could read a range of memory/registers from this PLC from the read_attr_hardware method, then stores this into a variable and then use this variable directly to extract the relevant data in the read_XXX methods without having to access to the hardware one more time. All the attributes which are read at the same time will be using the same data taken from the hardware at the same time.
It is not mandatory to implement something into read_attr_hardware method but in some specific cases as I just described, it could be useful.

This is for memorized attributes. The attribute value will be stored in an attribute property named __value every time you write successfully this attribute.
The first time you start your device server, there will not be any __value attribute property defined in the Tango database, so Tango will not write your attribute at init this first time.
You simply need to write this attribute at least once and the next time your device server will be started, it will be able to write your memorized attribute during it’s initialization phase with the memorized value (last successful write on your memorized attribute).

Do you mean from the device panel (Test device on jive)? I don’t think you can enter then in binary format…
What kind of data would you like to pass? An image?

It’s because you can still read this kind of Write Only attributes. In this case, you will basically read the last set value.

Hoping this helps,
Reynald

Hi Reynald,

Thank you for your help and detailed answers, I appreciate your effort.

Does read_XXX immediately access hardware again when it is called, or self.attr_LED_Value_read is necessary to read hardware again? In other words, what should I do so that I avoid accessing hardware again in read_XXX method?

Yeah, I am able to enter arguments in decimal and hexadecimal format, I was wondering if it is possible to enter them in binary format.

When a client read several attributes, using read_attributes() method or when you have several attributes polled at the same polling frequency:

  1. read_attr_hardware() is invoked
  2. read_XXX() is invoked for each XXX attribute which are part of the read_attributes() call.

If a client invokes read_attribute() to read only one attribute named YYY,

  1. read_attr_hardware() is invoked
  2. read_YYY() is invoked

Knowing that, you can put your real hardware accesses where it is more convenient for your specific use case.
I hope it clarifies a bit.

About TestPanel, arguments in binary format are currently not supported.

I have one more question, and that would be all. Situation below is what started confusing me in first place about read_attr_hardware.

I’ve made simple program with two attributes with same polling frequency (1 second).
I edit generated code like below (all counters are initialized at start as 0):


def read_Att1(self, attr):
        ...
        self.counter1 += 1
        print "counter1 = %d" % self.counter1
        ...

def read_Att2(self, attr):
        ...
        self.counter2 += 1
        print "counter2 = %d" % self.counter2
        ...

def read_attr_hardware(self, data):
        ...
        self.counterH += 1
        print "counterH = %d" % self.counterH
        ...

We have three counters, end each is increased by 1 when specific method is called.
I was expecting that output will be something like:

counterH = 1
counter1 = 1
counter2 = 1
counterH = 2
counter1 = 2
counter2 = 2

Which is also expected from your post:

[quote]when you have several attributes polled at the same polling frequency:

read_attr_hardware() is invoked
read_XXX() is invoked for each XXX attribute which are part of the read_attributes() call.[/quote]

Instead, this is what I get

counterH = 1
counter2 = 1
counterH = 2
counter1 = 1
counterH = 3
counter2 = 2
counterH = 4
counter1 = 2

Why is output like this, it means that read_attr_hardware is called twice, one time for every read_Att method?

Thank you for your patience. :slight_smile:

Hi,

I just tried with a recent version of PyTango/Tango and I got the expected output.
Maybe you are using an old version of PyTango which was using Tango 8.
The polling is using read_attributes only since Tango 9.

Kind regards,
Reynald

I am using Tango 9.2.5a, and PyTango 9.2.1.
Can you attach your code y?ou have used for testing?

Hi,
Here is the code I used.
Please note that I am clearly no pyTango expert.

How did you install PyTango?

Again I have that counterH is twice as big as other two counters.

I installed by running script:

sudo apt install libboost1.58-dev libboost-python1.58-dev
sudo -H pip install -U setuptools
sudo -H pip install python_dateutil pytz cycler pyparsing Sphinx futures gevent numpy
sudo -H pip install pytango fandango

Also, from terminal I am getting this:

python -c "import tango; print tango.Release.version"
9.2.1

Can there be some other reasons why read_attr_hardware is called like this?

P.S Did you generate code with Pogo? Because my generated code is a bit different.

Right you are…
I generated the code from Pogo with PythonHL option.
Then I realized that there was no read_attr_hardware method generated!! Why is that? That’s a good question! Maybe a PyTango expert knows the answer?
So I generated another version of the code for Python instead of PythonHL. With the Python option, read_attr_hardware method was generated. So I copied it into the code which was generated with PythonHL.

Right now, I cannot explain why you have a different behaviour than what I’m seeing…
How did you install tango9.2.5a?
What is your operating system?

Do you have several tango library versions installed on your computer?

I just executed the same commands you used to install pytango on an Ubuntu 16.04.2 LTS virtual machine where tango9.2.5a was installed from the source distribution tar file.
I executed the code I attached in a previous post and I still get the expected result.

So I could see several explanations to the behaviour you are observing:

  1. You have several tango libraries installed on your system and pytango is using an old one where the polling was used differently?
  2. Your 2 attributes are not configured with the same polling period?
  3. You have an external client reading your attributes individually with SOURCE=DEVICE?
  4. The answer D! :wink:
  5. You have set polling_before_9 property to true on your admin device (very unlikely since this is an advanced feature and requires an action on your side)?
  6. The other explanation we didn’t think about yet

Hi Reynald,

I’ve installed Tango using source code. Also, I have Ubuntu 16.04 LTS.
I think that there is a chance about several tango libraries (explanation A).
I will try later this day to reinstall ubuntu, and start again from clean installation. I’ll let you know if there is some improvement.
One question, do you think it’s better that I install pytango and itango in virtual environment, or there shouldn’t be difference whether I use virtual environment or not?

Cheers

Jelena,

Could you send the code of both the server and the client?

I suspect it does not matter which version of PyTango/Tango you are using. This is a very core feature. I don’t think we ever had a report of any tango version being buggy at this level.

Are you sure you are using read_attributes (notice the s in the end) ?

I think it is a question for a Pogo PyTango expert 8-).
IMHO and just to answer Reynald question (I am getting of topic), pogo should not generate code which is not used by the developer. Instead I would say there is a missing feature in
pogo to “generate read_attr_hardware” (BTW, there should be another one called “generate always executed_hook”).
I always see pogo as a tool for prototyping and for newcomers to tango. If it generates lot of boiler plate code by default, newcomers wonder if they are supposed to do something there.

[quote=“TCoutinho”][quote=“Reynald”]
I generated the code from Pogo with PythonHL option.
Then I realized that there was no read_attr_hardware method generated!! Why is that? That’s a good question! Maybe a PyTango expert knows the answer?
[/quote]
I think it is a question for a Pogo PyTango expert 8-).
IMHO and just to answer Reynald question (I am getting of topic), pogo should not generate code which is not used by the developer. Instead I would say there is a missing feature in
pogo to “generate read_attr_hardware” (BTW, there should be another one called “generate always executed_hook”).
I always see pogo as a tool for prototyping and for newcomers to tango. If it generates lot of boiler plate code by default, newcomers wonder if they are supposed to do something there.
[/quote]
Hi,

That’s exactly the reason why the generated code is without these methods. And also to keep it very simple for a simple case.
But we can imagine having an option to generate them or not like Tiago suggested.

For me, we maybe have to see it like for dev_state and dev_status, which can be generated only if you want to override them.

Need some talks with P.Verdier for the gui parts, but it’s definitely doable and have to be accessible, so just a matter of time before it’s get integrated.

[quote=“SGara_Nexeya”]
That’s exactly the reason why the generated code is without these methods. And also to keep it very simple for a simple case.
But we can imagine having an option to generate them or not like Tiago suggested.

For me, we maybe have to see it like for dev_state and dev_status, which can be generated only if you want to override them.

Need some talks with P.Verdier for the gui parts, but it’s definitely doable and have to be accessible, so just a matter of time before it’s get integrated.[/quote]

Thanks for the explanations. I think it would be nice to have this option, indeed. :slight_smile: