[Question] HL DS synchronized with another DS
hayg25 opened this issue · 7 comments
Dear All,
I would like to create a DS (DS1) with 2 attributes (Att11, Att12).
This DS should be build from another existing DS (DS0) with 2 Attributes (Att01, Att02)
like : `
- Att11 = K1*Att01
- Att12 = K2*Att02
K1 and K2 are some scaling factors in this case but the arithmetic operation for Att11, Att12, could be more complicated (polynomial, ... etc)
I would like to do it for each event.
Do you have an example showing how to do this using PyTango.
Many thanks in advance
@hayg25 this looks very close to what has been implemented in the Facade device at MaxIV. Vincent Michel, one of the authors, gave a great talk on this topic at ICALEPCS 2017: https://accelconf.web.cern.ch/icalepcs2017/talks/mobpl06_talk.pdf
There are links in there to the code. Hopefully someone from MaxIV can help you try it out.
Cheers
this looks very close to what has been implemented in the Facade device at MaxIV.
Exactly! :)
Here's a link to the documentation:
https://tango-facadedevice.readthedocs.io/en/latest/
Dear @andygotz, dear @vxgmichel ,
thanks a lot for the solution, that's exactly what I need.
I tried using a DS I created for testing :
from tango import DispLevel, AttrWriteType
from tango.server import run
from tango.server import Device, DeviceMeta
from tango.server import attribute, command
from tango import DevState
from numpy.random import random_sample
class DS_TEST(Device):
__metaclass__ = DeviceMeta
# List of high level variables
def init_device(self):
Device.init_device(self)
self._amplitude = 0
self._delay = 0
self.set_state(DevState.ON)
amplitude = attribute(label="Amplitude", dtype=float, access = AttrWriteType.READ_WRITE)
delay = attribute(label="Delay", dtype=float, access = AttrWriteType.READ_WRITE)
def read_amplitude(self):
return self._amplitude
def write_amplitude(self,amplitude):
self._amplitude = amplitude
def read_delay(self):
return self._delay
def write_delay(self,delay):
self._delay = delay
if __name__ == "__main__":
run((DS_TEST,))
and I modified the example you gave :
from facadedevice import Facade, proxy_attribute, logical_attribute
from tango.server import run
class DS_REC(Facade):
Width = proxy_attribute(
dtype=float,
property_name='WidthAttribute')
Height = proxy_attribute(
dtype=float,
property_name='HeightAttribute')
@logical_attribute(
bind=['Width', 'Height'])
def Sum(width, height):
return width + height
if __name__ == '__main__':
DS_REC.run_server()
so I set the properties for the new DS_REC.
And when I start the device,
- It stays in Unknown state
- none of the value is updated ...
Thanks
Hello @hayg25
It missing self
in Sum
arguments:
@logical_attribute(
bind=['Width', 'Height'])
def Sum(self, width, height):
return width + height
The two attributes Width
and else Height
are bind to the attribute defined in the properties:
WidthAttribute
WidthAttribute
This attribute can be set a tango attribute like domain/family/member/attribute
(The tango attribute change/periodic event channel has to be enabled) or to a raw value.
The device state has to be managed manually (like a standard tango device). The state can also be bind to some facade attribute (https://tango-facadedevice.readthedocs.io/en/latest/tutorial.html#state-attribute)
You can always use the command GetInfo
to get more details about the device.
Hi @AntoineDupre ,
thanks for your help, indeed I missed the self argument !
It Works now. But still the DS status is in unknown mode : any idea ?
The device state and status are not changed to ON automatically, UNKNOWN will stay until you change it.
In normal Tango devices, I just use self.set_state()
and self.set_status()
in the appropriate places (e.g. at the end of init_device()
or after some action failed inside a command). Remember to always update both (*) to keep them in sync.
I'm not familiar with this facadedevice
, but the tutorial Antoine linked shows you how to do it easily with @state_attribute
. Also, the section Adding extra logic at initialization shows how to add something similar to init_device()
if you want to set the state there.
(*) If you only want to update state and keep status as the default "The device is in [STATE] state", you need to set_status
to empty or 'Not initialised'
I believe, since that is the default value and Tango will insert the right STATE always.
Hi @hayg25
As Idoyle mention, the state needs to be managed manually. It can be set in the safe_init_device
function (function called after facade initialization):
More documentation there: https://tango-facadedevice.readthedocs.io/en/latest/tutorial.html#adding-extra-logic-at-initialization