caputRecorder 1.4


caputRecorder_small.adl

Table of Contents

GitHub repository: https://github.com/epics-modules/caputRecorder

Overview

caputRecorder supports the recording and playback of sequences of caputs. It records each caput as a python command, and a sequence 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. caputRecorder communicates with users via an EPICS database, so it allows any EPICS record or channel-access client to record and run python functions, and to wait for them to complete.

caput is short for "Channel Access put". When you press a button, or make a menu selection, in an MEDM (or other display manager) display, you are doing a caput. Any program that writes to EPICS PVs does so by doing caputs.

caputRecorder also supports generalizing recorded macros with arguments. (This requires manual editing of python code.) It provides a user interface through which macro arguments are displayed with default values that can be changed via channel access.

This version of caputRecorder is known to work with python 2.7. It probably will not work with python 3.

caputRecorder is intended to meet the following kinds of needs:

How does this work?

EPICS access security has the ability to call a user function whenever a caput that meets certain criteria 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 macro 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. Here's what a typical command looks like:

epics.caput("xxx:scan1.P1PV","xxx:m2.VAL", wait=True, timeout=1000000.0)
This writes the string "xxx:m2.VAL" to "xxx:scan1.P1PV", and waits ~forever for any EPICS processing that might result from the command to complete.

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

Thus, each IOC is responsible for telling caputRecorder that it received a caput, and one IOC also hosts the database through which the user tells caPutRecorder what to do.

Requirements, configuration

The caputRecorder database uses record types from the synApps busy and calc modules. 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 the database that functions as 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 caputPoster.db

    dbLoadRecords("$(CAPUTRECORDER)/caputRecorderApp/Db/caputPoster.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 this IOC will host caputRecorder's user interface, load the database caputRecorder.db

    dbLoadRecords("$(CAPUTRECORDER)/caputRecorderApp/Db/caputRecorder.db","P=xxx:,N=100")
    
    where N is the length of the comment, users, hosts, and prefixes strings.

    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=100
    
    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. (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.
    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. For the purposes of caputRecorder, 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. The following environment variables must be set before running MEDM (caQtDM, etc.):

    START_PUTRECORDER
    The path to a script that starts caputRecorder.py. This will be used by the "!(re)start recorder" button described below. There is a sample copy of a script that does this for Linux here:
    caputRecorder/example_start_putrecorder
    It is important that only one copy of caputRecorder.py (for a given user-interface database) is running at a time. caputRecorder.py detects the launch of a new copy of itself that uses the same control PVs, and exits.

    MACROS_PY
    The path to the macros file, in which caputs will be recorded. There is an example copy of this file here:
    caputRecorder/caputRecorderApp/op/python/example_macros.py

    EDITOR
    The command that invokes your preferred editor, which will be used for the "edit macros" button described below.

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 to 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

    Record options

    Discussion