EPICS Home

Experimental Physics and Industrial Control System


 
1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <20172018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <20172018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: help - writing a table column from OPI BOY to PV
From: "Kasemir, Kay" <[email protected]>
To: Tomasz Brys <[email protected]>
Cc: "[email protected]" <[email protected]>
Date: Wed, 12 Jul 2017 15:04:01 +0000
Hi:

You say 'commands run in different order' and show what's printed, but that script doesn't print anything.
So I assume you're printing somewhere on the receiving end?

When your script performs
    pvs[10].setValue(1)                      # set output on
    pvs[12].setValue('LIST')                 # set output mode list
then the script is indeed first writing to pvs[10] and then pvs[12].
But what that means: It asks the Channel Access client library to send those values out to the network.
When they're received by the IOC, and in case of different IOCs, in what order, is out of your control.
Even if pvs[10] is received first by the IOC, you have no idea if the IOC has even started to think about doing anything about it.

If you really want to control things, and assert that they happen step-by-step, you need to use the Channel Access put-callback.
Put-callback writes a value and then notifies you when it's done, meaning it was received by the IOC, and the motor has been moved, the temperature controller actually reached the desired temperature, the power supply actually settled on the desired voltage etc.

In a BOY script you can't wait until things are done. If your underlying PV library is the PVManager, you just can't perform a put-callback, period. If you select the vtype.pv library, you could, but you must not wait inside a BOY script, because then you'd block the whole UI, so the script API doesn't even offer that.

If you want to perform control, you really need to do that on an IOC.
You can use a normal IOC with calcout, seq, .. records, and/or the the SNL sequencer.
Alternatively, use a "python IOC" with pcaspy and pyepics.

In any case, your IOC would serve the PVs that you use to configure the operation and "start" it, and the IOC then performs the steps in order:
put-callback to the first PV, wait until that's done, then the next step etc.
The user interface (CSS, EDM, ..) can only show you the configuration PVs, allow you to enter values and then push the "Go" button.
The user interface cannot and should not perform any control.

-Kay


________________________________________
From: Tomasz Brys <[email protected]>
Sent: Wednesday, July 12, 2017 10:31 AM
To: Kasemir, Kay
Cc: [email protected]
Subject: Re: help - writing a table column from OPI BOY to PV

Hi Kay,
The solution which you gave to me, writing column to PV, worked fine. However, there is another problem.
My script is not only to write a one column but there is a little more logic and commands.
And commands run in different order than I expect.

This is my script:
##################################################
from org.csstudio.opibuilder.scriptUtil import PVUtil
from array import array

if PVUtil.getLong(pvs[0]) > 0:
    # Get the table content
    table = widget.getTable()
    content = table.getContent()


    # print content
    # Get table's column 1,2 (counting from 0) into val,dwel
    val =  [float(r[1]) for r in content]
    dwel = [float(r[2]) for r in content]

    pvs[6].setValue(1)                         # Reset
    pvs[10].setValue(0)                      # Output off  -- this line makes problem
    pvs[7].setValue(1)                         # clear all lists

    if PVUtil.getString(pvs[11]) == 'VOLT':
       pvs[4].setValue(5)                    # set current limit
       pvs[1].setValue(array('d', val))      # write voltage list to device
       pvs[3].setValue(array('d', dwel))     # set steps
    elif PVUtil.getString(pvs[11]) == 'CURR':
       pvs[5].setValue(5)                    # set voltage limit
       pvs[2].setValue(array('d', val))      # write current list to device
       pvs[3].setValue(array('d', dwel))     # set steps


    pvs[8].setValue(1)                       # set count
    pvs[9].setValue(1)                       # set direction
    pvs[10].setValue(1)                      # set output on
    pvs[12].setValue('LIST')                 # set output mode list
##################################################

When I comment the line pvs[10].setValue(0) then everything is OK.
Otherwise, the last command “set output mode list” is before “set output on”.
This is what is printed:
1. Reset
2. Set output off
3. Clear list
4. (assuming ‘volt’) set current limit
5. write voltage list
6. write step list
7. write count
8. set direction
9. set output mode list (missing set output on)
10. (get output)  - this I think is RBV from command 2
11. set output on
12. (get current limit) RBV
13. (get output) RBV

Why is that and what would be the best solution to run it in the proper sequence?

I have to first “set output on” and then “set output mode list” which is actually executing all.
It does not make sense to execute, when output is off….

Regards
--
Tomasz Brys
Integrated Control System
European Spallation Source ERIC


On 05/07/17:27 17:44, "Kasemir, Kay" <[email protected]> wrote:

    Hi:

    > Michael Davidsaver <[email protected]>
    >http://www.aps.anl.gov/epics/tech-talk/2016/msg01173.php
    >Is this what you're looking for?  To write eg. an array of double?

    Michael already linked to the basics of writing an array.
    The other missing piece might be constructing the plain array in the Jython code.
    In your example, you never fetched any column from the table, you just kept writing "i", the scalar loop index, to a PV.
    Plus PVUtil.writePV("$(PREFIX):ListVo...) would perform the potentially slow PV connection in the script, i.e. on the UI thread.

    Try this:

    # Have this script with two PVs attached to the table widget
    #
    # pvs[0]: Something like loc://do_write_the_column(0), triggering the script execution
    # pvs[1]: That array PV to which you want to write the column, NOT triggering the script
    from org.csstudio.opibuilder.scriptUtil import PVUtil
    from array import array

    if PVUtil.getInt(pvs[0]) > 0:
        # Get the table content
        table = widget.getTable()
        content = table.getContent()

        # Get table's column 2 (counting from 0) into col
        col = []
        for row in content:
            col.append(row[2])

        # Write that column as a double[] array to the array PV
        pvs[1].setValue(array(col), 'd')


    Now have your button write 1 to loc://do_write_the_column(0)
    Note that only the first PV must trigger the script execution, not the second one, because otherwise the script writing to the array PV would trigger the script which writes the array PV which triggers the script to write the array PV etc.

    -Kay

    On 07/05/2017 04:14 PM, Tomasz Brys wrote:
    > Hi,
    > I need help.
    > I have an OPI BOY. I created a table Nx3, (Nrows, 3 columns), N can be from 1 to 200.
    > User can modify the table and when is ready press the button to write the whole column of the table to PV
    > The PV is type of aao , size 200. Of course, the table can have less than 200 elements.
    > What would be the easiest way to do this?
    > I tried something like that, create an Action Button and as an action I execute such a script:
    >
    > from org.csstudio.opibuilder.scriptUtil import PVUtil
    > from array import array
    >
    > tab = display.getWidget("Table")
    >
    > row = tab.getTable().getRowCount()
    > for i in range(1, row):
    >    PVUtil.writePV("$(PREFIX):ListVolt", i)  # - this works but write always one element [0]
    >    print i
    >
    > My question:
    > How I can write one column of a table to PV which is type of aao?
    > Is it possible to write the whole column at once? Or I have to do it element by element?
    > Any help will be appreciated.
    >
    > Regards
    > --
    > Tomasz Brys
    > Integrated Control System
    > European Spallation Source - ERIC
    >
    >
    >




References:
help - writing a table column from OPI BOY to PV Tomasz Brys
Re: help - writing a table column from OPI BOY to PV Michael Davidsaver
Re: help - writing a table column from OPI BOY to PV Kasemir, Kay
Re: help - writing a table column from OPI BOY to PV Tomasz Brys

Navigate by Date:
Prev: Re: CA gateway with systemd Florian Feldbauer
Next: Re: CA gateway with systemd Wesley Moore
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <20172018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: help - writing a table column from OPI BOY to PV Tomasz Brys
Next: Re: help - writing a table column from OPI BOY to PV Michael Davidsaver
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  <20172018  2019  2020  2021  2022  2023  2024