subscribe_event Method without initial execution of callback

Dear Tango Community,

I am new to Tango Controls and try to get familiar with the general methods of Tango Controls, so I apologise in advance in case I missed something fundamental.

I use the method
subscribe_event('my_attribute', tango.EventType.ARCHIVE_EVENT, my_callback)
to save data, camera images to be specific. I noticed that the process of subscribing to events (executing the subscribe_event method) triggers the callback once. Is there a way to disable this initial call?

The desired behaviour would be to run
subscribe_event('my_attribute', tango.EventType.ARCHIVE_EVENT, my_callback)
without executing the "my_callback" function.
First execution of "my_callback" should be the first time the event is pushed.

I use PyTango 9.3.3 with Tango 9.3.4 on a Win10 PC.

Thanks,
Dominik
Hi Dominik,

Welcome to the Tango Community! smile

Indeed, the callback is triggered once during the subscription phase because there is a synchronous read_attribute call which is done during this subscription phase. The goal is to inform the client of the current value of the attribute at the time of the subscription.
There is currently no way to disable this behaviour with the current cppTango versions.

There is already an existing issue on this topic in TangoTickets: https://gitlab.com/tango-controls/TangoTickets/-/issues/13
Please do not hesitate to comment there to give more focus on this issue if you think it should be fixed faster.

Season's Greetings
Reynald

PS: I will be on leave until at least 4th January so don't be surprised if I'm not responsive in the mean time (but I'm not the only in the Tango community smile )
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.
Hi again Dominik,

If all your clients are only interested in pushed events and you have no client interested in reading the attribute value directly with a read_attribute call, you could decide to always throw exceptions in your read_myAttr method (An exception like "this attribute is not designed to be read without using the events") and to push the archive events in a separate thread or from somewhere else in your code.

Your callback would still be called during the subscription phase but my_event->err would be true in this use case (my_event being the EventData * passed to MyEventCallBack::push_event method) so you could distinguish this event from the good events.

I remember seeing a device server doing something like this once in our facility.
It's quite unusual and a bit strange but it might be enough for your needs while waiting for https://gitlab.com/tango-controls/TangoTickets/-/issues/13 to be implemented.

Hoping this helps,
Reynald
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.
Hi Reynald,

Thank you for your swift response.

My clients need the attribute value, so throwing an exception is not ideal.

My small test setup consists of only 4 device servers (Laser, Archiver, Camera, Motor) to get familiar with Tango Controls. I develop it for our laser facility where the data is organized in single shots. I created a "Laser" device server with an attribute "shot number". This server can push "shot events" (currently implemented as archive events). On "shot events", I want to save all attributes from all servers. This is currently handled by an "Archiver" device server, which simply pulls all attributes from "Camera" and "Motor" and organizes it properly. "Archiver" subscribes to archive events from Laser with attribute shot_number. The issue now is that on every subscribe_event call, which happens prior to each shot, it runs through the full saving routine. (and runs into timeouts since cameras wait for triggers etc.)

I can imagine several workarounds and will find one for sure while I get familiar with the general Tango methods and principles.

Best Regards,
Dominik
Hi Dominik,

welcome to the Tango community :)

Why are you subscribing the callback once per shot? I would assume you are rather trying to subscribe once in e.g. `init_device()` and then have the same callback called every shot.

Either way, you can maybe work around the first call by remembering the last shot that was saved and comparing to the event data value inside `my_callback` to identify if this event is actually a new shot or can be ignored.

Greetings from Munich, Lenny
Hi Lenny,

Nice to talk to you on the Tango forum.
The deeper meaning behind the subscription on single shot basis was to use a general "arm for shot" command prior to each shot, where cameras are set to trigger, EMP sensitive electronics are switched off etc.

A click on a "shot" button would then be a sequence of three commands, something like "do before shot" –> "fire shot" –> "do after shot", where "do before shot" would arm cameras, read + save + switch off motor controlers and so on. Essentially make everything "wait" for the shot to come. It felt reasonable to me to use Tango Events for this. The call "do after shot" would be something like save images, turn electronics back on etc.

Thank you for your help Lenny and Reynald.

Cheers,
Dominik
 
Register or login to create to post a reply.