Exemplo n.º 1
0
    def launcher(stopEvent):
        ca.create_context()

        print('launcher thread libca ctx =', ca.current_context())

        sup.launch_monitors()

        # Keep thread alive until it is time to go
        stopEvent.wait()

        print('(AtIocExit) launcher thread libca ctx =', ca.current_context())
Exemplo n.º 2
0
def setup(logger):
    '''Setup ophyd for use

    Must be called once per session using ophyd
    '''
    # It's important to use the same context in the callback _dispatcher
    # as the main thread, otherwise not-so-savvy users will be very
    # confused
    global _dispatcher

    if _dispatcher is not None:
        logger.debug('ophyd already setup')
        return

    epics.pv.default_pv_class = PyepicsShimPV

    def _cleanup():
        '''Clean up the ophyd session'''
        global _dispatcher
        if _dispatcher is None:
            return
        epics.pv.default_pv_class = epics.PV

        if _dispatcher.is_alive():
            _dispatcher.stop()

        _dispatcher = None

    logger.debug('Installing event dispatcher')
    _dispatcher = EventDispatcher(thread_class=PyepicsCallbackThread,
                                  context=ca.current_context(),
                                  logger=logger)
    atexit.register(_cleanup)
    return _dispatcher
Exemplo n.º 3
0
def build():
    stopEvent = Event()

    sup = bugSupport(name='bug')

    print('pyDevSup thread libca ctx =', ca.current_context())

    # In order to get a fresh context, lets do pyepics
    # stuff in a different thread
    def launcher(stopEvent):
        ca.create_context()

        print('launcher thread libca ctx =', ca.current_context())

        sup.launch_monitors()

        # Keep thread alive until it is time to go
        stopEvent.wait()

        print('(AtIocExit) launcher thread libca ctx =', ca.current_context())

    t = Thread(target=launcher, args=(stopEvent, ))

    def stopLauncher():
        stopEvent.set()
        t.join()

    addHook('AtIocExit', stopLauncher)

    # iocInit somehow messes up contexts, so start the thread
    # after iocInit
    addHook('AfterIocRunning', t.start)

    return sup
Exemplo n.º 4
0
def get_pv(pvname, form='time', connect=False, context=None, timeout=5.0,
           connection_callback=None, access_callback=None, callback=None,
           **kwargs):
    """Get a PV from PV cache or create one if needed.

    Parameters
    ---------
    form : str, optional
        PV form: one of 'native' (default), 'time', 'ctrl'
    connect : bool, optional
        whether to wait for connection (default False)
    context : int, optional
        PV threading context (defaults to current context)
    timeout : float, optional
        connection timeout, in seconds (default 5.0)
    """
    if form not in ('native', 'time', 'ctrl'):
        form = 'native'

    if context is None:
        context = ca.current_context()

    thispv = None

    # TODO: this needs some work.
    # thispv = epics.pv._PVcache_.get((pvname, form, context))
    # if thispv is not None:
    #     if callback is not None:
    #         # wrapping is taken care of by `add_callback`
    #         thispv.add_callback(callback)
    #     if access_callback is not None:
    #         access_callback = wrap_callback(_dispatcher, 'metadata',
    #                                         access_callback)
    #         thispv.access_callbacks.append(access_callback)
    #     if connection_callback is not None:
    #         connection_callback = wrap_callback(_dispatcher, 'metadata',
    #                                             connection_callback)
    #         thispv.connection_callbacks.append(connection_callback)
    #     if thispv.connected:
    #         if connection_callback:
    #             thispv.force_connect()
    #         if access_callback:
    #             thispv.force_read_access_rights()

    if thispv is None:
        thispv = PyepicsShimPV(pvname, form=form, callback=callback,
                               connection_callback=connection_callback,
                               access_callback=access_callback, **kwargs)

    if connect:
        if not thispv.wait_for_connection(timeout=timeout):
            ca.write('cannot connect to %s' % pvname)
    return thispv
Exemplo n.º 5
0
def setup(logger):
    '''Setup ophyd for use

    Must be called once per session using ophyd
    '''
    # It's important to use the same context in the callback _dispatcher
    # as the main thread, otherwise not-so-savvy users will be very
    # confused
    global _dispatcher

    if _dispatcher is not None:
        logger.debug('ophyd already setup')
        return

    epics._get_pv = epics.get_pv
    epics.get_pv = get_pv
    epics.pv.get_pv = get_pv

    def _cleanup():
        '''Clean up the ophyd session'''
        global _dispatcher
        if _dispatcher is None:
            return
        epics.get_pv = epics._get_pv
        epics.pv.get_pv = epics._get_pv

        logger.debug('Performing ophyd cleanup')
        if _dispatcher.is_alive():
            logger.debug('Joining the dispatcher thread')
            _dispatcher.stop()

        _dispatcher = None

    logger.debug('Installing event dispatcher')
    _dispatcher = EventDispatcher(thread_class=PyepicsCallbackThread,
                                  context=ca.current_context(), logger=logger)
    atexit.register(_cleanup)
    return _dispatcher
Exemplo n.º 6
0
def get_pv(pvname,
           form='time',
           connect=False,
           context=None,
           timeout=5.0,
           connection_callback=None,
           access_callback=None,
           callback=None,
           **kwargs):
    """Get a PV from PV cache or create one if needed.

    Parameters
    ---------
    form : str, optional
        PV form: one of 'native' (default), 'time', 'ctrl'
    connect : bool, optional
        whether to wait for connection (default False)
    context : int, optional
        PV threading context (defaults to current context)
    timeout : float, optional
        connection timeout, in seconds (default 5.0)
    """
    if form not in ('native', 'time', 'ctrl'):
        form = 'native'

    if context is None:
        context = ca.current_context()

    thispv = None

    # TODO: this needs some work.
    # thispv = epics.pv._PVcache_.get((pvname, form, context))
    # if thispv is not None:
    #     if callback is not None:
    #         # wrapping is taken care of by `add_callback`
    #         thispv.add_callback(callback)
    #     if access_callback is not None:
    #         access_callback = wrap_callback(_dispatcher, 'metadata',
    #                                         access_callback)
    #         thispv.access_callbacks.append(access_callback)
    #     if connection_callback is not None:
    #         connection_callback = wrap_callback(_dispatcher, 'metadata',
    #                                             connection_callback)
    #         thispv.connection_callbacks.append(connection_callback)
    #     if thispv.connected:
    #         if connection_callback:
    #             thispv.force_connect()
    #         if access_callback:
    #             thispv.force_read_access_rights()

    if thispv is None:
        thispv = PyepicsShimPV(pvname,
                               form=form,
                               callback=callback,
                               connection_callback=connection_callback,
                               access_callback=access_callback,
                               **kwargs)

    if connect:
        if not thispv.wait_for_connection(timeout=timeout):
            ca.write('cannot connect to %s' % pvname)
    return thispv
Exemplo n.º 7
0
 def detach_context(self):
     super().detach_context()
     if ca.current_context() is not None:
         ca.detach_context()
Exemplo n.º 8
0
 def __enter__(self):
     if current_context() != CA_CONTEXT:
         attach_context(CA_CONTEXT)
     return self
Exemplo n.º 9
0
def threads_init():
    if current_context() != CA_CONTEXT:
        attach_context(CA_CONTEXT)
Exemplo n.º 10
0
from datetime import datetime
from contextlib import ContextDecorator
from enum import Enum

import epics
import numpy

from gi.repository import GLib, GObject
from epics.ca import current_context, attach_context

CA_CONTEXT = current_context()


class Alarm(Enum):
    NORMAL, MINOR, MAJOR, INVALID = range(4)


class BasePV(GObject.GObject):
    """
    Process Variable Base Class
    """
    __gsignals__ = {
        'changed': (GObject.SignalFlags.RUN_FIRST, None, (object, )),
        'active': (GObject.SignalFlags.RUN_FIRST, None, (bool, )),
        'alarm': (GObject.SignalFlags.RUN_FIRST, None, (object, )),
        'time': (GObject.SignalFlags.RUN_FIRST, None, (object, )),
    }

    def __init__(self, name, monitor=True):
        """