EPICS Channel Access

EPICS CA transport requires fastcs[epicsca] to be installed.

EPICS CA has a maximum length of 40 on parameter descriptions. Set SecopQuirks.max_description_length to 40 to truncate descriptions.

Supported SECoP data types

EPICS CA transport supports the following SECoP data types, using the corresponding EPICS record type:

  • double (ai/ao)

  • scaled (ai/ao)

  • int (longin/longout)

  • bool (bi/bo)

  • enum (mbbi/mbbo)

  • string (lsi/lso)

  • blob (waveform[char])

  • array of double/int/bool/enum* (waveform)

  • matrix, if the ‘matrix’ is 1-dimensional (waveform)

  • command (if arguments and return values are empty or one of the above types)

Other data types can only be read or written in ‘raw’ mode. In particular, structs and tuples will need to be read in raw mode; set SecopQuirks.raw_struct and SecopQuirks.raw_tuple. SecopQuirks.raw_matrix is also recommended, as only 1-D matrices are supported by CA.

Example CA IOC

"""Example CA IOC using :py:obj:`fastcs_secop`."""

import argparse
import asyncio
import logging
import socket

from fastcs.connections import IPConnectionSettings
from fastcs.launch import FastCS
from fastcs.logging import LogLevel, configure_logging

from fastcs_secop import SecopController, SecopQuirks

if __name__ == "__main__":
    from fastcs.transports import EpicsIOCOptions
    from fastcs.transports.epics.ca import EpicsCATransport

    parser = argparse.ArgumentParser(description="Demo PVA ioc")
    parser.add_argument("-i", "--ip", type=str, default="127.0.0.1", help="IP to connect to")
    parser.add_argument("-p", "--port", type=int, help="Port to connect to")
    args = parser.parse_args()

    configure_logging(level=LogLevel.DEBUG)
    logging.basicConfig(level=LogLevel.DEBUG)

    asyncio.get_event_loop().slow_callback_duration = 1000

    epics_options = EpicsIOCOptions(pv_prefix=f"TE:{socket.gethostname().upper()}:SECOP")
    epics_ca = EpicsCATransport(epicsca=epics_options)

    quirks = SecopQuirks(
        raw_tuple=True,
        raw_struct=True,
        raw_matrix=True,
        max_description_length=40,
        raw_accessibles=[
            ("valve_controller", "_domains_to_extract"),
            ("valve_controller", "_terminal_values"),
        ],
    )

    controller = SecopController(
        settings=IPConnectionSettings(ip=args.ip, port=args.port),
        quirks=quirks,
    )

    fastcs = FastCS(
        controller,
        [epics_ca],
    )
    fastcs.run(interactive=True)