caputRecorder

caputRecorder supports the recording and playback of a series of caputs (e.g., mouse clicks and typing into an MEDM window). It records each caput as a python command, and a series of caputs as a python function - also called here a macro. caputRecorder can also serve as a simple user interface for delivering canned python functions to end users.

How does this work?

EPICS access security has the ability to call a user function whenever a caput that meets certain requirements is received by an IOC. The function is called an access-security trap listener, and caputRecorder provides one which writes a caput-notification string of the form "pvname,value,user@host" to an EPICS PV whenever an eligible caput is received by the IOC.

caputRecorder provides an EPICS database that contains the EPICS PV mentioned above, and other PVs that function as caputRecorder's user interface. The user-interface PVs are monitored by the python program caputRecorder.py, and direct its operation. When caputRecorder.py is given a function name and told to record, it begins monitoring the caput-notification PVs of specified IOCs, and writes python commands corresponding to each notification into the python program file macros.py.

caputRecorder.py also inspects the file macros.py and writes the names of functions in the file to a set of EPICS menus (that is, to mbbo records). A user can select a function name from those menus, and tell caputRecorder to execute that function.

Thus, each IOC is responsible for telling caputRecorder that it received a caput, and one IOC also tells caPutRecorder what to do.

Requirements, configuration

The workstation on which caputRecorder.py runs must have python with the PyEpics module installed.

EPICS IOCs that participate in caputRecorder, either by posting the caputs they receive, or by hosting caputRecorder's user interface, must be prepared as follows. (These are excerpts from the synApps xxx module, release R5-8, which is already configured to use caputRecorder.)

  1. Add CAPUTRECORDER to the IOC's RELEASE file

  2. Include caputRecorder.dbd in the IOC's .dbd file.

  3. Link the IOC's code against the caputRecorder library.

  4. Load the database caputRecorder.db, for example with this excerpt from st.cmd:

    dbLoadRecords("$(CAPUTRECORDER)/caputRecorderApp/Db/caputRecorder.db","P=xxx:,N=300")
    
    where N is the length of the longest caput-notification string ("pvname,value,user@host") that will be sent to the recorder.
  5. If you're using autosave, you'll probably also want to include caputRecorder_settings.req in the IOC's auto_settings.req file:

    file caputRecorder_settings.req P=xxx:,N=300
    
    If you do this, you must also add the following line to save_restore.cmd:
    set_requestfile_path("$(CAPUTRECORDER)", "caputRecorderApp/Db")
    
  6. Register caputRecorder's access-security trap listener, for example with the following excerpt from st.cmd. (Note that this command must be executed after iocInit.)
    registerCaputRecorderTrapListener('xxx:caputRecorderCommand')
    
    where xxx:caputRecorderCommand is the name of the PV to which caput-notification strings will be written.
  7. Run EPICS access security with an access-security file that specifies TRAPWRITE for the desired users and hosts. Here is a sample excerpt from st.cmd:
    iocsh
    asSetFilename("$(TOP)/iocBoot/accessSecurity.acf")
    exit
    
    where the file accessSecurity.acf might have the following content:
    HAG(workstation) {mooneylinux.aps.anl.gov}
    UAG(user) {mooney}
    ASG(DEFAULT) {
    	RULE(1,READ)
    	RULE(1,WRITE,TRAPWRITE) {
    		HAG(workstation)
    		UAG(user)
    	}
    	RULE(1,WRITE)
    }
    

    This file grants write permission to anybody on any host, and specifies that TRAPWRITE is in effect only for user mooney on workstation mooneylinux. You probably don't want TRAPWRITE in effect for caputs from an IOC, but do want it for caputs from channel-access clients, such as MEDM, that aren't in an IOC.

    Note that the order in which rules occur in the file matters for TRAPWRITE. If RULE(1,WRITE) were encountered before RULE(1,WRITE,TRAPWRITE), TRAPWRITE would not be in effect for anybody, because everybody is covered by RULE(1,WRITE).

    If you can't or don't want to select users and hosts using access-security rules, you can specify TRAPWRITE for all, and select users and hosts with caputRecorder's user interface. The simplest possible access-security file that will work for caputRecorder is the following:

    ASG(DEFAULT) {
    	RULE(1,WRITE,TRAPWRITE)
    }
    
  8. One IOC from which caputs are to be recorded will have its caputRecorder.db database displayed to the user via MEDM (or caQtDM, or CSS-BOY). The Python program caputRecorder.py will also monitor and write to this database.

  9. The workstation on which this display is running must have the file start_putrecorder in its top-level directory (which I'll call xxx), and the file macros.py in xxx/xxxApp/op/python. An example copy of start_putrecorder (from the synApps xxx module) is available as caputRecorder/example_start_putrecorder. An example copy of macros.py is available as caputRecorder/caputRecorderApp/op/python/example_macros.py.

  10. Set the environment variable EDITOR to your preferred text editor, so that the button labelled "!edit macros.py" above will work.

How to use


caputRecorder.adl
Referring to the caputRecorder.adl display above, from top to bottom:

Selecting what gets recorded

You probably don't want to record all caputs that happen among your IOCs and clients, but only those done by users. One way of filtering was shown above, in "Requirements, configuration". User-specified filtering is easier, and can be done at run time with caputRecorder's user interface.
  1. You can choose which users' caputs will be recorded by specifying usernames to caputRecorderUsers. (See "Record caputs from whom?" in the figure below.) To disable recording from a specific user, put a minus sign in front of the username.

  2. You can choose which hosts' caputs will be recorded by specifying hostnames to caputRecorderHosts. (See "Record caputs from whom?" in the figure below.) Only the first element of a host name need be specified. (For example, "mooneylinux.aps.anl.gov" is used as "mooneylinux".)

  3. You can choose which IOCs caputRecorder monitors, by specifying prefixes to caputRecorderPrefixes. (See "Record caputs received by which IOCs?" in the figure below.) Unlike user and host choices, this choice does not take effect while a macro is being recorded. Also unlike user and host choices, this choice is not about the sender of a caput, but about the recipient.

    On startup, caputRecorder monitors the iocs whose prefixes are specified on the command line. If caputRecorderPrefixes is not empty, it will override the initial list of iocs.

  4. Caputs within an IOC will never be recorded, because they don't go through access security.


    caputRecorderConfigure.adl

    Discussion