Tango-way of having devices rely on each other

Hi tangoers,

what is the tango-way of ensuring that one device can only do X if a second device is in state Y?

For example let's assume you have a big laser and a water cooling system and one tango device for each of them. Obviously you want to ensure that the laser can only be turned on if the water is runing. On the other hand if someone turns off the laser the water cooling should be also stopped after grace period.

Now of course I could do the checking and synchronization between the two manually, but this problem sounds too generic in order for me being the first person to encounter it.

Combining both tango device servers into one is not a good solution IMHO.

Thanks,
Thomas
Hi Thomas,

what you described sounds like an interlock to me i.e. prevent A from doing something if B is not in a given state.

You are right this is a common scenario. We have hundreds of interlocks on our accelerator (water, beam position, thermocouple, vacuum) and we need to ensure they are all in a given state in order to turn on an operate the accelerator. Despite this we do not have a generic mechanism for automatically managing this in Tango. All cases to my knowledge are handled using one of the following approaches:

(1) device A reads either via a synchronous call or events the state(s) of B(s) before executing an action

(2) device B sends a hardware interlock to interrupt the beam or prevent it from switching on via device A

(3) device A and B are in the same server and A reads B's state before executing an action

Approach (1) is used for slow (scale of seconds) interlocks. Approach (2) is used for fast (scale of nano to milliseconds) critical interlocks and for switching of the beam without human intervention. Approach (3) is for intermediate speed (milliseconds to seconds) interlocks.

Your question about a generic solution in Tango is very valid. I think it doesn't exist because to date Tango has not been often used as a safety plc. This could be changed e.g. by introducing the possibility to link an action to the state of another device automatically (via the database for example). A bit like forwarded attributes. I heard about a generic Facade device server from MAXIV yesterday which could maybe be adapted to do this. We need their input to know if this can be done easily.

Andy
Hi Thomas,

As Andy said, this device interaction can be understood either as an interlock (one device stopping another one) or as a permit (a device is not allowed to do something if a pre-condition is not matched).

At Alba we normally use PLC's for interlocks; having few exceptions on interlocks triggered by Panic alarms. So the disabling of an ongoing action is always managed by a separate device (Tango or HW).

In the case of permits (e.g. enabling filling or orbit correction), we define a set of panic alarms and then we check the value of the alarm attribute before executing the target action. But this check is normally done at GUI's level or by some intermediate device (Composer or Façade) not in the target device itself.

If I had to implement this "precondition" behavior from scratch in an "standard" way, then I would have followed this approach:

* e.g. we have a device with an OpenValve() command that should be allowed only if a/b/c/Pressure has a valid value

* I would create an OpenValve_allowed property in Jive with the precondition:

  OpenValve_allowed = a/b/c/Pressure

* Then, check it in the is_OpenValve_allowed method of the device:

  def is_OpenValve_allowed(self,req_type):
    permit = AttributeProxy(self.OpenValve_allowed).read()
    if permit.quality != ATTR_VALID: 
      return False 
    else:
      return True

The same approach can be used for enabling/desabling an attribute using the is_{attribute}_allowed method. Using the permit quality for enabling/disabling the action would allow to easily tune the permits from jive, panic or taurus w/out modifying the device code.

If you prefer to do an asynchronous checking of the permit, just replace the AttributeProxy by a TaurusAttribute, CachedAttributeProxy or whatever asynchronous api you prefer.

Sergi Rubio




Keep on dancing,

http://www.tango-controls.org/resources/howto/how-fandango/
Edited 7 years ago
Andy
I heard about a generic Facade device server from MAXIV yesterday which could maybe be adapted to do this.
Andy

Hello Andy,

I have came across two GitHub projects on Facade pattern by MAXIV as below:
    - dev-maxiv-llrffacade (LLRF Facade device server. It's a simple device server with dynamic attributes and some specific syntax to be used.)

Is it the one you were referring to? Or can you help me to point the generic Facade device server which you quoted in the post. I have searched the Device Server Catalogue, but couldn't find it. I am interested in the generic Facade device server and would like to play with it.

Kind regards,
Jyotin

"All the great things are simple, and many can be expressed in a single word: freedom, justice, honor, duty, mercy, hope." - Winston Churchill
Hi Jyotin,

the one I was referring to is the second one you mention i.e. https://github.com/MaxIV-KitsControls/lib-maxiv-facadedevice

The expert is Vincent.

Andy
Andy
Hi Jyotin,

the one I was referring to is the second one you mention i.e. https://github.com/MaxIV-KitsControls/lib-maxiv-facadedevice

The expert is Vincent.

Andy

Thanks Andy. I will contact Vincent, in case I need further help.
Cheers!

Jyotin
Thanks Andy, Sergi and Jyotin for your answers!

My example might not have been the best. We use hardware interlocks for the things related to safety.
The real use case is not safety relevant.

(1) from Andy sounds like my use case. The facade server looks interesting, altough I would have to "adapt" it as the project is C++ only.

While thinking about this some more what I really would need is something like the "Allowed State machine" in pogo, only for multiple devices. Unfortunately this would be overkill to implement for my use case, so I gotta write it manually.

Tanks a lot again!

Thomas
Once you select the state machine in Pogo it will generate the "is_$Command_allowed" and "is_$Attribute_allowed methods", that you can later modify to add a check for an external attribute. It would provide your desired behavior in just 1-2 lines of code.

Using the facade approach is also possible as you can put the interlock logics in a boolean attribute of a python device and just read the boolean attribute from your C++ device.

Another approach is having an "Enable" boolean RW attribute within your C++ device and then having an independent device (facade, alarm, …) checking the conditions and updating the permit. While commissioning, permits and logics may be adjusted and sometimes is useful to have it apart of your device to not have to recompile for each change.

Sergi
Keep on dancing,

http://www.tango-controls.org/resources/howto/how-fandango/
 
Register or login to create to post a reply.