diff --git a/doc/recipes/DynamicDS_and_Simulators.rst b/doc/recipes/DynamicDS_and_Simulators.rst index 36505a422..8ccc6622e 100644 --- a/doc/recipes/DynamicDS_and_Simulators.rst +++ b/doc/recipes/DynamicDS_and_Simulators.rst @@ -17,6 +17,13 @@ DynamicDS device formulas are declared using four properties: - DynamicCommands - DynamicStates - DynamicQualities + +Devices implementing DynamicAttributes +-------------------------------------- + +The best example of DynamicAttributes is SimulatorDS: https://github.com/tango-controls/SimulatorDS + +Other devices implementing this API are PyStateComposer, PyAttributeProcessor, PyPLC, CopyCatDS, CSVReader, RFFacade, ... What DynamicAttributes / DynamicDS allow ---------------------------------------- @@ -33,45 +40,6 @@ It's also possible to write READ/WRITE attributes:: SETPOINT = DevDouble(READ and SerialCommand('SP?') or WRITE and SerialCommand('SP=%s'%VALUE)) -Add DynamicAttributes to a Tango Device Class ---------------------------------------------- - -Modify the following lines of your device:: - -Declaration of your device, replace DevImpl by DynamicDS:: - - from fandango.dynamic import * - class GaugeController(fandango.DynamicDS): - -Class creator, initialize DynamicDS instead of DevImpl; methods added to _locals dictionary will be available in attributes formulas:: - - def __init__(self,cl, name): - ... - fandango.DynamicDS.__init__(self,cl,name,_locals={'SerialCommand':self.SerialCommand}) - GaugeController.init_device(self) - -Init() method of device, replace get_device_properties():: - - def init_device(self): - ... - self.get_DynDS_properties() - ... - -Add always executed hook for evaluating states:: - - def always_executed_hook(self): - print "In ", self.get_name(), "::always_excuted_hook()" - fandango.DynamicDS.always_executed_hook(self) - -In the Tango class declaration, replace PyTango.DeviceClass:: - - class GaugeControllerClass(fandango.DynamicDSClass): #<--- Declaration of Class - ... - -Finally, go to Jive and create the DynamicAttributes property and put there your attributes formulas.:: - - SETPOINT=type(READ and SerialComm('SP?') or WRITE and SerialComm('SP=%s'%VALUE)) - ---- Usage of Dynamic Attributes @@ -491,6 +459,46 @@ ChekDependencies (True by default) will force a check of which attributes are accessed in other's formulas, creating an index for each attribute with its pre-requisites for evaluation (which will be automatically assigned to be kept). At each read_dyn_attr execution the dependency values will be added to _locals, and a read_dyn_attr(dependency) may be forced if its values are older than KeepTime. +Add DynamicAttributes to a Tango Device Class +--------------------------------------------- + +Modify the following lines of your device:: + +Declaration of your device, replace DevImpl by DynamicDS:: + + from fandango.dynamic import * + class GaugeController(fandango.DynamicDS): + +Class creator, initialize DynamicDS instead of DevImpl; methods added to _locals dictionary will be available in attributes formulas:: + + def __init__(self,cl, name): + ... + fandango.DynamicDS.__init__(self,cl,name,_locals={'SerialCommand':self.SerialCommand}) + GaugeController.init_device(self) + +Init() method of device, replace get_device_properties():: + + def init_device(self): + ... + self.get_DynDS_properties() + ... + +Add always executed hook for evaluating states:: + + def always_executed_hook(self): + print "In ", self.get_name(), "::always_excuted_hook()" + fandango.DynamicDS.always_executed_hook(self) + +In the Tango class declaration, replace PyTango.DeviceClass:: + + class GaugeControllerClass(fandango.DynamicDSClass): #<--- Declaration of Class + ... + +Finally, go to Jive and create the DynamicAttributes property and put there your attributes formulas.:: + + SETPOINT=type(READ and SerialComm('SP?') or WRITE and SerialComm('SP=%s'%VALUE)) + + ---- Tango Events diff --git a/doc/recipes/TangoRecipes.rst b/doc/recipes/TangoRecipes.rst index 228eb8777..12d9366ac 100644 --- a/doc/recipes/TangoRecipes.rst +++ b/doc/recipes/TangoRecipes.rst @@ -18,16 +18,21 @@ The fandango api provides helper commands to create devices and assign propertie fn.tango.put_device_property('your/device/name','Property','Value') -You can also call them from shell:: +You can also call them from shell (use fandango.sh in <12.6 releases):: - > fandango.sh add_new_device Server/Instance Class your/device/name - > fandango.sh put_device_property your/device/name Property Value + > fandango add_new_device Server/Instance Class your/device/name + > fandango put_device_property your/device/name Property Value To start it on any host managed by Starter:: - > tango_servers yourhost start Server/Instance + > tango_servers "yourhostname" start "YourServer/YourInstance" + +Visualize its state:: + > tango_servers state "YourServer/YourInstance" + + > fandango check_device your/device/name Get devices or attributes matching a regular expression @@ -45,7 +50,26 @@ Using fandango.tango.get_matching_devices or get_matching_attributes: 'SR01/VC/VGCT-01A08-01', 'SR01/VC/VGCT-02A01-01', 'SR02/VC/IPCT-02A02-01', - + + tango.get_matching_attributes('bo01*corv*/current') + ['bo01/pc/corv-01/Current', + 'bo01/pc/corv-03/Current', + 'bo01/pc/corv-05/Current', + 'bo01/pc/corv-06/Current', + 'bo01/pc/corv-07/Current', + 'bo01/pc/corv-09/Current', + 'bo01/pc/corv-11/Current'] + + import fandango as fn + fn.kmap(tango.read_attribute,tango.get_matching_attributes('bo01*corv*/current')) + [('bo01/pc/corv-01/Current', 0.090130000000000002), + ('bo01/pc/corv-03/Current', 0.084650000000000003), + ('bo01/pc/corv-05/Current', 0.099900000000000003), + ('bo01/pc/corv-06/Current', -0.054309999999999997), + ('bo01/pc/corv-07/Current', 0.0099299999999999996), + ('bo01/pc/corv-09/Current', 0.052699999999999997), + ('bo01/pc/corv-11/Current', 0.081900000000000001)] + Search for device attribute/properties matching a regular expression: .. code:: python @@ -54,6 +78,8 @@ Search for device attribute/properties matching a regular expression: {'S01/VC/IPCT-01': {'SerialLine': 'S01/VC/SERIAL-01'}, 'S01/VC/IPCT-02': {'SerialLine': 'S01/VC/SERIAL-02'}, 'S01/VC/VGCT-01': {'SerialLine': 'S01/VC/SERIAL-10'}} + + Obtain all information from a device ==================================== @@ -87,6 +113,32 @@ if you just want to see if things are effectively running or not:: astor.states() + +Example: Fast property update +============================= + +This example will collect all running instances of PyAlarm and will replace its properties + +.. code:: python + + import fandango as fn + servers = fandango.Astor('PyAlarm/*') + # Get running servers + running = [s for for s,v in servers.states().items() if v is not None] + # Get the list of devices + devs = fn.chain(*[servers[s].get_device_list() for s in running]) + + for d in devs: + if not d.startswith('dserver'): + prop = servers.proxies[d].get_property(['AlarmReceivers'])['AlarmReceivers'] + # Modify property values + prop = [s.replace('%SRUBIO','%DFERNANDEZ') for s in prop] + servers.proxies[d].put_property({'AlarmReceivers':prop}) + + # Reload the devices properties + for d in devs: + servers.proxies[d].Init() + Use TangoEval to evaluate strings containing Tango Attributes ============================================================= @@ -100,9 +152,12 @@ The result of each evaluation is stored in te.result. [Out]: TangoEval: result = 7.2e-10 +Other tools/classes +=================== + Use CSVArray to turn a .csv into a dictionary -============================================= +--------------------------------------------- :: @@ -117,21 +172,8 @@ Use CSVArray to turn a .csv into a dictionary csv.getAsTree(lastbranch=1) Out[18]: {'A': {'B': ['2'], 'C': ['3']}} -Fast property update -==================== - -.. code:: python - - import fandango.functional as fun - servers = fandango.Astor('PyAlarm/*') - 8 : devs = [d for d in fun.chain(*[servers[s].get_device_list() for s,v in servers.states().items() if v is not None]) if not d.startswith('dserver')] - for d in devs: - prop = servers.proxies[d].get_property(['AlarmReceivers'])['AlarmReceivers'] - servers.proxies[d].put_property({'AlarmReceivers':[s.replace('%SRUBIO','%DFERNANDEZ') for s in prop]}) - for d in devs: servers.proxies[d].ReloadFromDB() - ReversibleDict -============== +-------------- .. code:: python @@ -160,7 +202,7 @@ ReversibleDict Out[139]: set([0]) ThreadDict -========== +---------- from PyPLC: @@ -208,7 +250,7 @@ Reading: val = self.threadDict[key] Piped, iPiped, zPiped interfaces -================================ +-------------------------------- Fandango has a set of operators to use regular-or operator ('|') like a linux pipe between operators (inspired by Maxim Krikun [ http://code.activestate.com/recipes/276960-shell-like-data-processing/?in=user-1085177]). diff --git a/doc/recipes/fandango_shell.rst b/doc/recipes/fandango_shell.rst index 87ce4b749..c1a7f7321 100644 --- a/doc/recipes/fandango_shell.rst +++ b/doc/recipes/fandango_shell.rst @@ -1,22 +1,81 @@ -Fandango shell examples -======================= +Using Fandango from the Linux Shell +=================================== -Most fandango methods can be launched from Unix shell:: +The tango_servers script allows to start/stop/check devices:: - # fandango.sh get_tango_host + > tango_servers stop "PyPLC/plctest*" + + > tango_servers start "PyPLC/plctest*" + + > tango_servers status "*/*otr*" + + Loading */*otr* devices + + ds_imggrabber/bo01_fsotr01: ON + bo01/di/fsotr-01-ccd: OPEN + bo01/di/fsotr-01-iba: RUNNING + dserver/ds_imggrabber/bo01_fsotr01: ON + + ds_imggrabber/bo02_fsotr01: ON + bo02/di/fsotr-01-ccd: OPEN + bo02/di/fsotr-01-iba: RUNNING + dserver/ds_imggrabber/bo02_fsotr01: ON + + ds_imggrabber/bo03_fsotr01: ON + bo03/di/fsotr-01-ccd: OPEN + bo03/di/fsotr-01-iba: RUNNING + dserver/ds_imggrabber/bo03_fsotr01: ON + +You can also start devices on an specific host:: + + > tango_servers stop PyPLC/plctest12 + + > tango_servers ctlabserver start PyPLC/plctest12 + + +Most fandango methods can be launched from Unix shell (the launcher was called fandango.sh in previous versions):: + + > fandango --help # will return the list of commands available + + > fandango --help [command] # will return the command help + + > fandango get_tango_host localhost:10000 - # fandango.sh findModule fandango + > fandango findModule fandango /usr/lib/python2.7/site-packages/fandango - # fandango.sh get_matching_attributes "mach/ct/composer/*" + > fandango get_matching_attributes "mach/ct/composer/*" mach/ct/composer/averagepressure mach/ct/composer/averagecurrent - # fandango.sh read_attribute mach/ct/composer/averagecurrent + > fandango read_attribute mach/ct/composer/averagecurrent 119.1 + + > fandango get_matching_device_properties sr04/vc/eps-plc-01 "*" + + DynamicQualities,(*)_VAL=ATTR_ALARM if ATTR('$_ALRM') else ATTR_VALID + (*)_CONFIG_Status=ATTR_ALARM if ATTR('$_CONFIG_ALRM') else ATTR_VALID + DynamicStates, + KeepAttributes,CPUStatus + TestMode + * + KeepTime,1500 + Mapping,DigitalsREAD=0,+240 + AnalogIntsREAD=835,+280 + AnalogRealsREAD=2135,+350 + AnalogIntsWRITE=1155,+280 + AnalogRealsWRITE=2455,+350 + AnalogIntsDeltaREAD=5000,+252 + AnalogIntsDeltaWRITE=6000,+42 + MappingUnused,DigitalsWRITE=390,+240 + ModbusCacheConfig,0 + ModbusTimeWait,200 + Modbus_name,SR04/VC/EPS-PLC-01-MBUS + +