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())
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
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
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
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
def detach_context(self): super().detach_context() if ca.current_context() is not None: ca.detach_context()
def __enter__(self): if current_context() != CA_CONTEXT: attach_context(CA_CONTEXT) return self
def threads_init(): if current_context() != CA_CONTEXT: attach_context(CA_CONTEXT)
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): """