def waitChannelUpdate(self, chanName, waitValue=None, timeout=None): """Wait for a channel update Arguments: chanName -- channel name waitValue -- particular value to wait (defaults to None, meaning any value) timeout -- optional timeout (defaults to None) """ connection = self.connection() if connection is not None: self.channelWasUnregistered = False channel = connection.getChannel(chanName) if not channel.registered: self.channelWasUnregistered = True connection.registerChannel( chanName, self.channelUpdated) #channel.register() else: SpecEventsDispatcher.connect(channel, 'valueChanged', self.channelUpdated) self.wait(waitValue=waitValue, timeout=timeout) if self.channelWasUnregistered: connection.unregisterChannel(chanName) #channel.unregister()
def run(self): """Override Thread.run() ; define behaviour for the connections manager thread For each SpecConnection object in the connections dictionary, try to make a connection. If the connection is already established, nothing occurs. Poll the asyncore dispatchers for processing socket events. """ self.__started = True while not self.stopEvent.isSet(): self.lock.acquire() try: connection_dispatcher_keys = self.connectionDispatchers.keys() for k in connection_dispatcher_keys: connection = self.connectionDispatchers.get(k) if connection is not None: connection.makeConnection() if self.stopEvent.isSet(): break finally: self.lock.release() if len(self.connectionDispatchers) > 0: asyncore.loop(0.01, False, None, 1) if self.doEventsDispatching: SpecEventsDispatcher.dispatch() else: time.sleep(0.01) asyncore.loop(0.01, False, None, 1)
def connectToSpec(self, varName, specVersion, dispatchMode = UPDATEVALUE, prefix=True): """Connect to a remote Spec Connect to Spec and register channel for monitoring variable Arguments: varName -- name of the variable specVersion -- 'host:port' string representing a Spec server to connect to """ self.varName = varName self.specVersion = specVersion if prefix: self.channelName = 'var/%s' % varName else: self.channelName = varName self.connection = SpecConnectionsManager.SpecConnectionsManager().getConnection(specVersion) SpecEventsDispatcher.connect(self.connection, 'connected', self._connected) SpecEventsDispatcher.connect(self.connection, 'disconnected', self._disconnected) # # register channel # self.connection.registerChannel(self.channelName, self.update, dispatchMode = dispatchMode) cb = self.__callbacks.get("update") if cb is not None: cb = cb() self.connection.registerChannel(self.channelName, cb, dispatchMode = dispatchMode) if self.connection.isSpecConnected(): self.connected()
def registerChannel(self, chanName, receiverSlot, registrationFlag = SpecChannel.DOREG, dispatchMode = SpecEventsDispatcher.UPDATEVALUE): """Register a channel Tell the remote Spec we are interested in receiving channel update events. If the channel is not already registered, create a new SpecChannel object, and connect the channel 'valueChanged' signal to the receiver slot. If the channel is already registered, simply add a connection to the receiver slot. Arguments: chanName -- a string representing the channel name, i.e. 'var/toto' receiverSlot -- any callable object in Python Keywords arguments: registrationFlag -- internal flag dispatchMode -- can be SpecEventsDispatcher.UPDATEVALUE (default) or SpecEventsDispatcher.FIREEVENT, depending on how the receiver slot will be called. UPDATEVALUE means we don't mind skipping some channel update events as long as we got the last one (for example, a motor position). FIREEVENT means we want to call the receiver slot for every event. """ if dispatchMode is None: return chanName = str(chanName) if not chanName in self.registeredChannels: newChannel = SpecChannel.SpecChannel(self, chanName, registrationFlag) self.registeredChannels[chanName] = newChannel SpecEventsDispatcher.connect(self.registeredChannels[chanName], 'valueChanged', receiverSlot, dispatchMode) channelValue = self.registeredChannels[chanName].value if channelValue is not None: # we received a value, so emit an update signal self.registeredChannels[chanName].update(channelValue)
def waitChannelUpdate(self, chanName, waitValue = None, timeout = None): """Wait for a channel update Arguments: chanName -- channel name waitValue -- particular value to wait (defaults to None, meaning any value) timeout -- optional timeout (defaults to None) """ with gevent.Timeout(timeout, SpecClientTimeoutError): self.waitConnection() connection = self.connection() if connection is not None: self.channelWasUnregistered = False channel = connection.getChannel(chanName) self.channel_updated_event.clear() if not channel.registered: self.channelWasUnregistered = True connection.registerChannel(chanName, self.channelUpdated) #channel.register() else: SpecEventsDispatcher.connect(channel, 'valueChanged', self.channelUpdated) if waitValue is None: try: self.channel_updated_event.wait(timeout) except: raise SpecClientTimeoutError else: while waitValue != self.value: self.channel_updated_event.wait(timeout) if self.channelWasUnregistered: connection.unregisterChannel(chanName) #channel.unregister()
def __init__(self, conn, command, callbacks = {}, timeout=5): self.command = command self._conn = conn self.timeout = timeout self.reply_pending = False self.retvalue = None self.specapp = self._conn.get_specname() # save callbacks self.__callback = None self.__error_callback = None self.__callbacks = { 'connected': None, 'disconnected': None, 'statusChanged': None, } for cb_name in iter(self.__callbacks.keys()): if callable(callbacks.get(cb_name)): self.__callbacks[cb_name] = SpecEventsDispatcher.callableObjectRef(callbacks[cb_name]) if self.synchronous: self._conn.wait_connected() else: SpecEventsDispatcher.connect(self._conn, 'connected', self._connected) SpecEventsDispatcher.connect(self._conn, 'disconnected', self._disconnected) if self._conn.is_connected(): self._connected()
def connectToSpec(self, varName, specVersion, dispatchMode=UPDATEVALUE, prefix=True): """Connect to a remote Spec Connect to Spec and register channel for monitoring variable Arguments: varName -- name of the variable specVersion -- 'host:port' string representing a Spec server to connect to """ self.varName = varName self.specVersion = specVersion if prefix: self.channelName = 'var/%s' % varName else: self.channelName = varName self.connection = SpecConnectionsManager.SpecConnectionsManager( ).getConnection(specVersion) SpecEventsDispatcher.connect(self.connection, 'connected', self._connected) SpecEventsDispatcher.connect(self.connection, 'disconnected', self._disconnected) self.dispatchMode = dispatchMode if self.connection.isSpecConnected(): self._connected()
def update(self, data, error, error_code): """Emit the 'replyFromSpec' signal.""" self.data = data self.error = error self.error_code = error_code SpecEventsDispatcher.emit(self, "replyFromSpec", (self,))
def connectToSpec(self, specName, specVersion): """Connect to a remote Spec Connect to Spec and register channels of interest for the specified motor Arguments: specName -- name of the motor in Spec specVersion -- 'host:port' string representing a Spec server to connect to """ self.specName = specName self.specVersion = specVersion self.chanNamePrefix = 'motor/%s/%%s' % specName self.connection = SpecConnectionsManager.SpecConnectionsManager().getConnection(specVersion) SpecEventsDispatcher.connect(self.connection, 'connected', self.__connected) SpecEventsDispatcher.connect(self.connection, 'disconnected', self.__disconnected) # # register channels # self.connection.registerChannel(self.chanNamePrefix % 'low_limit', self._motorLimitsChanged) self.connection.registerChannel(self.chanNamePrefix % 'high_limit', self._motorLimitsChanged) self.connection.registerChannel(self.chanNamePrefix % 'position', self.__motorPositionChanged, dispatchMode=SpecEventsDispatcher.FIREEVENT) self.connection.registerChannel(self.chanNamePrefix % 'move_done', self.motorMoveDone, dispatchMode = SpecEventsDispatcher.FIREEVENT) self.connection.registerChannel(self.chanNamePrefix % 'high_lim_hit', self.__motorLimitHit) self.connection.registerChannel(self.chanNamePrefix % 'low_lim_hit', self.__motorLimitHit) self.connection.registerChannel(self.chanNamePrefix % 'sync_check', self.__syncQuestion) self.connection.registerChannel(self.chanNamePrefix % 'unusable', self.__motorUnusable) self.connection.registerChannel(self.chanNamePrefix % 'offset', self.motorOffsetChanged) self.connection.registerChannel(self.chanNamePrefix % 'sign', self.signChanged) #self.connection.registerChannel(self.chanNamePrefix % 'dial_position', self.dialPositionChanged) if self.connection.isSpecConnected(): self.__connected()
def update(self, data, error, error_code): """Emit the 'replyFromSpec' signal.""" self.data = data self.error = error self.error_code = error_code SpecEventsDispatcher.emit(self, 'replyFromSpec', (self, ))
def specConnected(self): """Emit the 'connected' signal when the remote Spec version is connected.""" old_state = self.state self.state = CONNECTED if old_state != CONNECTED: logging.getLogger('SpecClient').info('Connected to %s:%s', self.host, (self.scanport and self.scanname) or self.port) SpecEventsDispatcher.emit(self, 'connected', ())
def wait(self): start_wait = time.time() while self.reply_pending: elapsed = time.time() - start_wait if elapsed > self.timeout: raise SpecClientTimeoutError("timeout waiting for command execution") SpecEventsDispatcher.dispatch() time.sleep(0.02)
def register(self, chan_name, receiver_slot, registrationFlag=SpecChannel.DOREG, dispatchMode=UPDATEVALUE): """Register a channel Tell the remote Spec we are interested in receiving channel update events. If the channel is not already registered, create a new SpecChannel object, and connect the channel 'valueChanged' signal to the receiver slot. If the channel is already registered, simply add a connection to the receiver slot. Arguments: chan_name -- a string representing the channel name, i.e. 'var/toto' receiver_slot -- any callable object in Python Keywords arguments: registrationFlag -- internal flag dispatchMode -- can be SpecEventsDispatcher.UPDATEVALUE (default) or SpecEventsDispatcher.FIREEVENT, depending on how the receiver slot will be called. UPDATEVALUE means we don't mind skipping some channel update events as long as we got the last one (for example, a motor position). FIREEVENT means we want to call the receiver slot for every event. """ if dispatchMode is None: return chan_name = str(chan_name) try: if not chan_name in self.reg_channels: channel = SpecChannel.SpecChannel(self, chan_name, registrationFlag) self.reg_channels[chan_name] = channel if channel.spec_chan_name != chan_name: # for assoc array elements channel.registered = True def valueChanged(value, chan_name=chan_name): channel = self.reg_channels[chan_name] channel.update(value) self.aliasedChannels[chan_name] = valueChanged self.registerChannel(channel.spec_chan_name, valueChanged, registrationFlag, dispatchMode) else: channel = self.reg_channels[chan_name] SpecEventsDispatcher.connect(channel, 'valueChanged', receiver_slot, dispatchMode) channelValue = self.reg_channels[channel.spec_chan_name].value if channelValue is not None: # we received a value, so emit an update signal channel.update(channelValue, force=True) except Exception: traceback.print_exc()
def _set_callbacks(self, callback, error_callback): if callable(callback): self.__callback = SpecEventsDispatcher.callableObjectRef(callback) else: self.__callback = None if callable(error_callback): self.__error_callback = SpecEventsDispatcher.callableObjectRef(error_callback) else: self.__error_callback = None
def poll(self, timeout=0.01): """Poll the asynchronous socket connections and dispatch incomming events""" fd = self.getFdDispatchersDict() if -1 not in fd: asyncore.loop(timeout, False, fd, 1) else: pass SpecEventsDispatcher.dispatch()
def specConnected(self): """Emit the 'connected' signal when the remote Spec version is connected.""" old_state = self.state self.state = CONNECTED if old_state != CONNECTED: logging.getLogger('SpecClient').info( 'Connected to %s:%s', self.host, (self.scanport and self.scanname) or self.port) SpecEventsDispatcher.emit(self, 'connected', ())
def specConnected(self): """Emit the 'connected' signal when the remote Spec version is connected.""" old_state = self.state self.state = CONNECTED if old_state != CONNECTED: log.log( 1, 'Connected to %s:%s' % (self.host, (self.scanport and self.scanname) or self.port)) SpecEventsDispatcher.emit(self, 'connected', ())
def specDisconnected(self): """Emit the 'disconnected' signal when the remote Spec version is disconnected.""" old_state = self.state self.state = DISCONNECTED if old_state == CONNECTED: logging.getLogger('SpecClient').info('Disconnected from %s:%s', self.host, (self.scanport and self.scanname) or self.port) SpecEventsDispatcher.emit(self, 'disconnected', ()) self.connected_event.clear()
def spec_disconnected(self): """Emit the 'disconnected' signal when the remote Spec version is disconnected.""" # SpecEventsDispatcher.dispatch() old_state = self.state self.state = DISCONNECTED if old_state == CONNECTED: log.log( 1, 'disconnected from %s:%s' % (self.host, self.specname or self.port)) SpecEventsDispatcher.emit(self, 'disconnected', ())
def update(self, data, error, error_code): """Emit the 'replyFromSpec' signal.""" self.data = data self.error = error self.error_code = error_code self.pending = False log.log(2, "emitting replyArrived") SpecEventsDispatcher.emit(self, 'replyArrived', (self, ))
def specDisconnected(self): """Emit the 'disconnected' signal when the remote Spec version is disconnected.""" SpecEventsDispatcher.dispatch() old_state = self.state self.state = DISCONNECTED if old_state == CONNECTED: log.info('Disconnected from %s:%s', self.host, (self.scanport and self.scanname) or self.port) SpecEventsDispatcher.emit(self, 'disconnected', ())
def connectToSpec(self, specVersion): self.connection = SpecConnectionsManager().getConnection(specVersion) self.__specVersion = specVersion SpecEventsDispatcher.connect(self.connection, 'connected', self.__connected) SpecEventsDispatcher.connect(self.connection, 'disconnected', self.__disconnected) if self.connection.isSpecConnected(): self.__connected()
def specConnected(self): """Emit the 'connected' signal when the remote Spec version is connected.""" old_state = self.state self.state = CONNECTED if old_state != CONNECTED: logging.getLogger("SpecClient").info( "Connected to %s:%s", self.host, (self.scanport and self.scanname) or self.port ) self.connected_event.set() SpecEventsDispatcher.emit(self, "connected", ())
def specDisconnected(self): """Emit the 'disconnected' signal when the remote Spec version is disconnected.""" old_state = self.state self.state = DISCONNECTED if old_state == CONNECTED: logging.getLogger('SpecClient').info( 'Disconnected from %s:%s', self.host, (self.scanport and self.scanname) or self.port) SpecEventsDispatcher.emit(self, 'disconnected', ()) self.connected_event.clear()
def waitFunc(timeout): """Waiting function Arguments: timeout -- waiting time in milliseconds """ try: P = getattr(SpecConnectionsManager.SpecConnectionsManager(), "poll") except AttributeError: time.sleep(timeout / 1000.0) SpecEventsDispatcher.dispatch() else: P(timeout / 1000.0)
def __init__(self, specName=None, specVersion=None, callbacks=None, timeout=None): """Constructor Keyword arguments: specName -- the name of the counter in Spec (defaults to None) specVersion -- 'host:port' string representing a Spec server to connect to (defaults to None) callbacks -- dict of callbacks. key is callback name; value is a python callable allowed keys: connected, disconnected, counterStateChanged, counterValueChanged timeout -- optional timeout for connection (defaults to None) """ self.counterState = NOTINITIALIZED self.chanNamePrefix = "" self.connection = None self.type = UNKNOWN self.__old_value = None self.__callbacks = { "counterStateChanged": None, "counterValueChanged": None, "connected": None, "disconnected": None, } if callbacks is None: callbacks = {} for cb_name in self.__callbacks.iterkeys(): if callable(callbacks.get(cb_name)): self.__callbacks[cb_name] = SpecEventsDispatcher.callableObjectRef(callbacks[cb_name]) if specName is not None and specVersion is not None: self.connectToSpec(specName, specVersion, timeout) else: self.specName = None self.specVersion = None
def unregister(self, chan_name, receiver_slot=None): """Unregister a channel Arguments: chan_name -- a string representing the channel to unregister, i.e. 'var/toto' """ chan_name = str(chan_name) if chan_name in self.reg_channels: channel = self.reg_channels[chan_name] if receiver_slot: SpecEventsDispatcher.disconnect(channel, 'valueChanged', receiver_slot) else: self.reg_channels[chan_name].unregister() del self.reg_channels[chan_name]
def __init__(self, specName=None, specVersion=None, callbacks={}): """Constructor Keyword arguments: specName -- name of the motor in Spec (defaults to None) specVersion -- 'host:port' string representing a Spec server to connect to (defaults to None) """ self.motorState = NOTINITIALIZED self.limit = NOLIMIT self.limits = (None, None) self.chanNamePrefix = '' self.connection = None self.__old_position = None # the callbacks listed below can be set directly using the 'callbacks' keyword argument ; # when the event occurs, the corresponding callback will be called automatically self.__callbacks = { 'connected': None, 'disconnected': None, 'motorLimitsChanged': None, 'motorPositionChanged': None, 'motorStateChanged': None } for cb_name in iter(self.__callbacks.keys()): if callable(callbacks.get(cb_name)): self.__callbacks[ cb_name] = SpecEventsDispatcher.callableObjectRef( callbacks[cb_name]) if specName is not None and specVersion is not None: self.connectToSpec(specName, specVersion) else: self.specName = None self.specVersion = None
def __init__(self, varName = None, specVersion = None, dispatchMode = UPDATEVALUE, prefix=True, callbacks={}): """Constructor Keyword arguments: varName -- name of the variable to monitor (defaults to None) specVersion -- 'host:port' string representing a Spec server to connect to (defaults to None) """ self.connection = None self.dispatchMode = UPDATEVALUE self.channelName = '' self.__callbacks = { 'connected': None, 'disconnected': None, 'update': None, } for cb_name in iter(self.__callbacks.keys()): if callable(callbacks.get(cb_name)): self.__callbacks[cb_name] = SpecEventsDispatcher.callableObjectRef(callbacks[cb_name]) if varName is not None and specVersion is not None: self.connectToSpec(varName, specVersion, dispatchMode = dispatchMode, prefix=prefix) else: self.varName = None self.specVersion = None
def __init__(self, specName = None, specVersion = None, callbacks={}): """Constructor Keyword arguments: specName -- name of the motor in Spec (defaults to None) specVersion -- 'host:port' string representing a Spec server to connect to (defaults to None) """ self.motorState = NOTINITIALIZED self.limit = NOLIMIT self.limits = (None, None) self.chanNamePrefix = '' self.connection = None self.__old_position = None # the callbacks listed below can be set directly using the 'callbacks' keyword argument ; # when the event occurs, the corresponding callback will be called automatically self.__callbacks = { 'connected': None, 'disconnected': None, 'motorLimitsChanged': None, 'motorPositionChanged': None, 'motorStateChanged': None } for cb_name in self.__callbacks.iterkeys(): if callable(callbacks.get(cb_name)): self.__callbacks[cb_name] = SpecEventsDispatcher.callableObjectRef(callbacks[cb_name]) if specName is not None and specVersion is not None: self.connectToSpec(specName, specVersion) else: self.specName = None self.specVersion = None
def __init__(self, conn, varname, dispatchMode=UPDATEVALUE, callbacks={}): """Constructor Keyword arguments: varname -- name of the variable to monitor (defaults to None) specapp -- 'host:port' string representing a Spec server to connect to (defaults to None) """ self.__callbacks = { 'connected': None, 'disconnected': None, 'update': None, } for cb_name in iter(self.__callbacks.keys()): if callable(callbacks.get(cb_name)): self.__callbacks[ cb_name] = SpecEventsDispatcher.callableObjectRef( callbacks[cb_name]) super(SpecVariableA, self).__init__(conn, varname) self._conn.connect_event('connected', self._connected) self._conn.connect_event('disconnected', self._disconnected) self.dispatchMode = dispatchMode if self._conn.is_connected(): self._connected()
def __init__(self, connection): """Constructor Arguments: connection -- a SpecConnection object """ self.connection = weakref.ref(connection) self.isdisconnected = True self.channelWasUnregistered = False self.value = None SpecEventsDispatcher.connect(connection, 'connected', self.connected) SpecEventsDispatcher.connect(connection, 'disconnected', self.disconnected) if connection.isSpecConnected(): self.connected()
def __init__(self, varName = None, specVersion = None, dispatchMode = UPDATEVALUE, prefix=True, callbacks={}, timeout=None): """Constructor Keyword arguments: varName -- name of the variable to monitor (defaults to None) specVersion -- 'host:port' string representing a Spec server to connect to (defaults to None) """ self.connection = None self.timeout = timeout self.dispatchMode = UPDATEVALUE self.channelName = '' self.__callbacks = { 'connected': None, 'disconnected': None, 'update': None, } for cb_name in self.__callbacks.iterkeys(): if callable(callbacks.get(cb_name)): self.__callbacks[cb_name] = SpecEventsDispatcher.callableObjectRef(callbacks[cb_name]) if varName is not None and specVersion is not None: self.connectToSpec(varName, specVersion, dispatchMode = dispatchMode, prefix=prefix) else: self.varName = None self.specVersion = None
def __init__(self, connection, channelName, registrationFlag = DOREG): """Constructor Arguments: connection -- a SpecConnection object channelName -- string representing a channel name, i.e. 'var/toto' Keyword arguments: registrationFlag -- defines how the channel is registered, possible values are : SpecChannel.DOREG (default), SpecChannel.DONTREG (do not register), SpecChannel.WAITREG (delayed registration until Spec is reconnected) """ self.connection = weakref.ref(connection) self.name = channelName if channelName.startswith("var/") and '/' in channelName[4:]: l = channelName.split('/') self.spec_chan_name = "/".join((l[0], l[1])) if self.spec_chan_name in SpecChannel.channel_aliases: SpecChannel.channel_aliases[self.spec_chan_name].append(self.name) else: SpecChannel.channel_aliases[self.spec_chan_name] = [self.name] if len(l)==3: self.access1=l[2] self.access2=None else: self.access1=l[2] self.access2=l[3] else: self.spec_chan_name = self.name if not self.spec_chan_name in SpecChannel.channel_aliases: SpecChannel.channel_aliases[self.spec_chan_name]=[self.name] self.access1=None self.access2=None self.registrationFlag = registrationFlag self.isdisconnected = True self.registered = False self.value = None SpecEventsDispatcher.connect(connection, 'connected', self.connected) SpecEventsDispatcher.connect(connection, 'disconnected', self.disconnected) if connection.isSpecConnected(): self.connected()
def connectToSpec(self, specName, specVersion, timeout=None): """Connect to a remote Spec Connect to Spec and register channels of interest for the specified motor Arguments: specName -- name of the motor in Spec specVersion -- 'host:port' string representing a Spec server to connect to """ self.specName = specName self.specVersion = specVersion self.chanNamePrefix = 'motor/%s/%%s' % specName self.connection = SpecConnectionsManager.SpecConnectionsManager().getConnection(specVersion) SpecEventsDispatcher.connect(self.connection, 'connected', self._connected) SpecEventsDispatcher.connect(self.connection, 'disconnected', self._disconnected) if self.connection.isSpecConnected(): self._connected()
def connectToSpec(self, specVersion, timeout=200): if self.connection is not None: SpecEventsDispatcher.disconnect(self.connection, 'connected', self._connected) SpecEventsDispatcher.disconnect(self.connection, 'disconnected', self._disconnected) self.connection = SpecConnectionsManager().getConnection(specVersion) self.specVersion = specVersion SpecEventsDispatcher.connect(self.connection, 'connected', self._connected) SpecEventsDispatcher.connect(self.connection, 'disconnected', self._disconnected) if self.connection.isSpecConnected(): self._connected() else: try: waitConnection(self.connection, timeout) except SpecClientTimeoutError: pass SpecEventsDispatcher.dispatch()
def __init__(self, conn, chan_name, registrationFlag = DOREG): """Constructor Arguments: * conn -- a SpecConnection object * chan_name -- string representing a channel name, i.e. 'var/toto' Keyword arguments: * registrationFlag -- defines how the channel is registered, possible values are : SpecChannel.DOREG (default), SpecChannel.DONTREG (do not register), SpecChannel.WAITREG (delayed registration until Spec is reconnected) """ self.conn = weakref.ref(conn) self.name = chan_name if chan_name.startswith("var/") and '/' in chan_name[4:]: l = chan_name.split('/') self.spec_chan_name = "/".join((l[0], l[1])) if len(l)==3: self.access1=l[2] self.access2=None else: self.access1=l[2] self.access2=l[3] else: self.spec_chan_name = self.name self.access1=None self.access2=None self.registrationFlag = registrationFlag self._connected = False self.registered = False self.value = None SpecEventsDispatcher.connect(conn, 'connected', self.connected) SpecEventsDispatcher.connect(conn, 'disconnected', self.disconnected) if conn.is_connected(): self.connected()
def connectToSpec(self, specVersion, timeout=None): if self.connection is not None: SpecEventsDispatcher.disconnect(self.connection, "connected", self._connected) SpecEventsDispatcher.disconnect(self.connection, "disconnected", self._disconnected) self.connection = SpecConnectionsManager.SpecConnectionsManager().getConnection(specVersion) self.specVersion = specVersion SpecEventsDispatcher.connect(self.connection, "connected", self._connected) SpecEventsDispatcher.connect(self.connection, "disconnected", self._disconnected) if self.connection.isSpecConnected(): self._connected()
def connectToSpec(self, specName, specVersion, timeout=None): """Connect to a remote Spec Connect to Spec Arguments: specName -- name of the counter in Spec specVersion -- 'host:port' string representing a Spec server to connect to timeout -- optional timeout for connection (defaults to None) """ self.specName = specName self.specVersion = specVersion self.chanNamePrefix = "scaler/%s/%%s" % specName self.connection = SpecConnectionsManager.SpecConnectionsManager().getConnection(specVersion) SpecEventsDispatcher.connect(self.connection, "connected", self._connected) SpecEventsDispatcher.connect(self.connection, "disconnected", self._disconnected) if self.connection.isSpecConnected(): self._connected()
def connectToSpec(self, specVersion, timeout=None): if self.connection is not None: SpecEventsDispatcher.disconnect(self.connection, 'connected', self._connected) SpecEventsDispatcher.disconnect(self.connection, 'disconnected', self._disconnected) self.connection = SpecConnectionsManager.SpecConnectionsManager().getConnection(specVersion) self.specVersion = specVersion SpecEventsDispatcher.connect(self.connection, 'connected', self._connected) SpecEventsDispatcher.connect(self.connection, 'disconnected', self._disconnected) if self.connection.isSpecConnected(): self._connected()
def poll(self, timeout=0.01): """Poll the asynchronous socket connections and dispatch incomming events""" connection_dispatcher_keys = self.connectionDispatchers.keys() for k in connection_dispatcher_keys: connection = self.connectionDispatchers.get(k) if connection is not None: connection.makeConnection() connection_dispatchers = {} for condis in self.connectionDispatchers.itervalues(): if condis.socket is not None: try: connection_dispatchers[condis.socket.fileno()]=condis except: # BAD FILE DESCRIPTOR? continue asyncore.loop(timeout, False, connection_dispatchers, 1) SpecEventsDispatcher.dispatch()
def __send_msg_with_reply(self, reply, message, replyReceiverObject = None): """Send a message to the remote Spec, and return the reply id. The reply object is added to the registeredReplies dictionary, with its reply id as the key. The reply id permits then to register for the reply using the 'registerReply' method. Arguments: reply -- SpecReply object which will receive the reply message -- SpecMessage object defining the message to send """ replyID = reply.id self.registeredReplies[replyID] = reply if hasattr(replyReceiverObject, 'replyArrived'): SpecEventsDispatcher.connect(reply, 'replyFromSpec', replyReceiverObject.replyArrived) self.sendq.insert(0, message) return replyID
def __init__(self, *args, **kwargs): self._reply_arrived_event = Event() self._last_reply = None self.__callback = None self.__error_callback = None self.__callbacks = {"connected": None, "disconnected": None, "statusChanged": None} callbacks = kwargs.get("callbacks", {}) for cb_name in self.__callbacks.iterkeys(): if callable(callbacks.get(cb_name)): self.__callbacks[cb_name] = SpecEventsDispatcher.callableObjectRef(callbacks[cb_name]) BaseSpecCommand.__init__(self, *args, **kwargs)
def unregisterChannel(self, chanName, receiverSlot=None): """Unregister a channel Arguments: chanName -- a string representing the channel to unregister, i.e. 'var/toto' """ chanName = str(chanName) if chanName in self.registeredChannels: channel = self.registeredChannels[chanName] if receiverSlot: SpecEventsDispatcher.disconnect(channel, 'valueChanged', receiverSlot) else: self.registeredChannels[chanName].unregister() del self.registeredChannels[chanName] listreg = [ ky for ky in self.registeredChannels.keys() if not ky.startswith('motor') ]
def __send_msg_with_reply(self, reply, message, replyReceiverObject=None): """Send a message to the remote Spec, and return the reply id. The reply object is added to the registeredReplies dictionary, with its reply id as the key. The reply id permits then to register for the reply using the 'registerReply' method. Arguments: reply -- SpecReply object which will receive the reply message -- SpecMessage object defining the message to send """ replyID = reply.id self.registeredReplies[replyID] = reply if hasattr(replyReceiverObject, 'replyArrived'): SpecEventsDispatcher.connect(reply, 'replyFromSpec', replyReceiverObject.replyArrived) self.sendq.insert(0, message) return replyID
def connectToSpec(self, specName, specVersion): """Connect to a remote Spec Connect to Spec and register channels of interest for the specified motor Arguments: specName -- name of the motor in Spec specVersion -- 'host:port' string representing a Spec server to connect to """ self.specName = specName self.specVersion = specVersion self.chanNamePrefix = 'motor/%s/%%s' % specName self.connection = SpecConnectionsManager.SpecConnectionsManager( ).getConnection(specVersion) SpecEventsDispatcher.connect(self.connection, 'connected', self.__connected) SpecEventsDispatcher.connect(self.connection, 'disconnected', self.__disconnected) if self.connection.isSpecConnected(): self.__connected()
def __init__(self, *args): """Constructor""" self.dispatcher = SpecConnectionDispatcher(*args) SpecEventsDispatcher.connect(self.dispatcher, 'connected', self.connected) SpecEventsDispatcher.connect(self.dispatcher, 'disconnected', self.disconnected) #SpecEventsDispatcher.connect(self.dispatcher, 'replyFromSpec', self.replyFromSpec) SpecEventsDispatcher.connect(self.dispatcher, 'error', self.error)
def waitConnection(self, timeout = None): """Wait for the connection to Spec being established Arguments: timeout -- optional timeout (defaults to None) Exceptions: timeout -- raise a timeout exception on timeout """ connection = self.connection() if connection is not None: t = 0 while self.isdisconnected: SpecEventsDispatcher.dispatch() t0 = time.time() waitFunc(10) t += (time.time() - t0)*1000 if timeout is not None and t >= timeout: raise SpecClientTimeoutError
def __init__(self, *args, **kwargs): self.__callback = None self.__error_callback = None self.__callbacks = { 'connected': None, 'disconnected': None, 'statusChanged': None, } callbacks = kwargs.get("callbacks", {}) for cb_name in self.__callbacks.iterkeys(): if callable(callbacks.get(cb_name)): self.__callbacks[cb_name] = SpecEventsDispatcher.callableObjectRef(callbacks[cb_name]) BaseSpecCommand.__init__(self, *args, **kwargs)
def wait(self, waitValue = None, timeout = None): """Block until the object's internal value gets updated Arguments: waitValue -- particular value to wait (defaults to None, meaning any value) timeout -- optional timeout (defaults to None) Exceptions: timeout -- raise a timeout exception on timeout """ t = 0 while not self.isdisconnected: SpecEventsDispatcher.dispatch() if self.value is not None: if waitValue is None: return if waitValue == self.value: return else: self.value = None if self.value is None: t0 = time.time() waitFunc(10) # 10 ms. t += (time.time() - t0)*1000 if timeout is not None and t >= timeout: raise SpecClientTimeoutError try: P = getattr(SpecConnectionsManager.SpecConnectionsManager(), "poll") except AttributeError: pass else: P()
def waitChannelUpdate(self, chanName, waitValue = None, timeout = None): """Wait for a channel update Arguments: chanName -- channel name waitValue -- particular value to wait (defaults to None, meaning any value) timeout -- optional timeout (defaults to None) """ connection = self.connection() if connection is not None: self.channelWasUnregistered = False channel = connection.getChannel(chanName) if not channel.registered: self.channelWasUnregistered = True connection.registerChannel(chanName, self.channelUpdated) #channel.register() else: SpecEventsDispatcher.connect(channel, 'valueChanged', self.channelUpdated) self.wait(waitValue = waitValue, timeout = timeout) if self.channelWasUnregistered: connection.unregisterChannel(chanName) #channel.unregister()
def error(self, error): """Propagate 'error' event""" SpecEventsDispatcher.emit(self, 'error', (error, ))
def disconnected(self): """Propagate 'disconnection' event""" SpecEventsDispatcher.emit(self, 'disconnected', ())
def error(self, error): """Emit the 'error' signal when the remote Spec version signals an error.""" logging.getLogger("SpecClient").error("Error from Spec: %s", error) SpecEventsDispatcher.emit(self, "error", (error,))
def update(self, channelValue, deleted = False): """Update channel's value and emit the 'valueChanged' signal.""" if type(channelValue) == types.DictType and self.access1 is not None: if self.access1 in channelValue: if deleted: SpecEventsDispatcher.emit(self, 'valueChanged', (None, self.name, )) else: if self.access2 is None: if self.value is None or self.value != channelValue[self.access1]: self.value = channelValue[self.access1] SpecEventsDispatcher.emit(self, 'valueChanged', (self.value, self.name, )) else: if self.access2 in channelValue[self.access1]: if deleted: SpecEventsDispatcher.emit(self, 'valueChanged', (None, self.name, )) else: if self.value is None or self.value != channelValue[self.access1][self.access2]: self.value = channelValue[self.access1][self.access2] SpecEventsDispatcher.emit(self, 'valueChanged', (self.value, self.name, )) return if type(self.value) == types.DictType and type(channelValue) == types.DictType: # update dictionary if deleted: for key,val in channelValue.iteritems(): if type(val) == types.DictType: for k in val: try: del self.value[key][k] except KeyError: pass if len(self.value[key])==1 and None in self.value[key]: self.value[key]=self.value[key][None] else: try: del self.value[key] except KeyError: pass else: for k1,v1 in channelValue.iteritems(): if type(v1)==types.DictType: try: self.value[k1].update(v1) except KeyError: self.value[k1]=v1 except AttributeError: self.value[k1]={None: self.value[k1]} self.value[k1].update(v1) else: if self.value.has_key(k1) and type(self.value[k1]) == types.DictType: self.value[k1][None] = v1 else: self.value[k1] = v1 value2emit=self.value.copy() else: if deleted: self.value = None else: self.value = channelValue value2emit=self.value SpecEventsDispatcher.emit(self, 'valueChanged', (value2emit, self.name, ))