def _start_pagent(self): """ Construct and start the port agent. """ # Create port agent object. this_pid = os.getpid() self._pagent = EthernetDeviceLogger.launch_process( self.device_address, self.device_port, WORK_DIR, DELIM, this_pid ) # Get the pid and port agent server port number. pid = self._pagent.get_pid() while not pid: gevent.sleep(0.1) pid = self._pagent.get_pid() port = self._pagent.get_port() while not port: gevent.sleep(0.1) port = self._pagent.get_port() # Configure driver to use port agent port number. DVR_CONFIG["comms_config"] = {"addr": "localhost", "port": port} # Report. log.info("Started port agent pid %d listening at port %d.", pid, port)
def _start_pagent(self): """ Construct and start the port agent. """ # Create port agent object. this_pid = os.getpid() self._pagent = EthernetDeviceLogger.launch_process(DEV_ADDR, DEV_PORT, WORK_DIR, DELIM, this_pid) pid = self._pagent.get_pid() while not pid: gevent.sleep(.1) pid = self._pagent.get_pid() port = self._pagent.get_port() while not port: gevent.sleep(.1) port = self._pagent.get_port() COMMS_CONFIG['port'] = port mi_logger.info('Started port agent pid %d listening at port %d', pid, port)
def configure(self, config, *args, **kwargs): """ """ mi_logger.info('Configuring for device comms.') method = config['method'] if method == 'ethernet': device_addr = config['device_addr'] device_port = config['device_port'] server_addr = config['server_addr'] server_port = config['server_port'] self._logger = EthernetDeviceLogger(device_addr, device_port, server_port) self._logger_client = LoggerClient(server_addr, server_port) elif method == 'serial': # The config dict does not have a valid connection method. raise InstrumentConnectionException() else: # The config dict does not have a valid connection method. raise InstrumentConnectionException()
def start_pagent(self): """ Construct and start the port agent. @retval port Port that was used for connection to agent """ # Create port agent object. this_pid = os.getpid() self._pagent = EthernetDeviceLogger.launch_process(self.device_addr, self.device_port, self.work_dir, self.delim, this_pid) pid = self._pagent.get_pid() while not pid: gevent.sleep(.1) pid = self._pagent.get_pid() port = self._pagent.get_port() while not port: gevent.sleep(.1) port = self._pagent.get_port() mi_logger.info('Started port agent pid %d listening at port %d', pid, port) return port
class InstrumentProtocol(object): """The base class for an instrument protocol The classes derived from this class will carry out the specific interactions between a specific device and the instrument driver. At this layer of interaction, there are no conflicts or transactions as that is handled at the layer above this. Think of this as encapsulating the transport layer of the communications. """ implements(IInstrumentConnection) def __init__(self, evt_callback=None): """Set instrument connect at creation @param connection An InstrumetnConnection object """ self._logger = None self._logger_client = None self._logger_popen = None self._fsm = None self.send_event = evt_callback """The driver callback where we an publish events. Should be a link to a function. Currently a dict with keys in EventKey enum.""" ######################################################################## # Protocol connection interface. ######################################################################## """ @todo Move this into the driver state machine? """ def initialize(self, *args, **kwargs): """ """ mi_logger.info('Initializing device comms.') self._logger = None self._logger_client = None def configure(self, config, *args, **kwargs): """ """ mi_logger.info('Configuring for device comms.') method = config['method'] if method == 'ethernet': device_addr = config['device_addr'] device_port = config['device_port'] server_addr = config['server_addr'] server_port = config['server_port'] self._logger = EthernetDeviceLogger(device_addr, device_port, server_port) self._logger_client = LoggerClient(server_addr, server_port) elif method == 'serial': # The config dict does not have a valid connection method. raise InstrumentConnectionException() else: # The config dict does not have a valid connection method. raise InstrumentConnectionException() def connect(self, *args, **kwargs): """Connect via the instrument connection object @param args connection arguments @throws InstrumentConnectionException """ mi_logger.info('Connecting to device.') logger_pid = self._logger.get_pid() mi_logger.info('Found logger pid: %s.', str(logger_pid)) if not logger_pid: self._logger_popen = self._logger.launch_process() time.sleep(0.2) try: retval = os.wait() mi_logger.debug('os.wait returned %s' % str(retval)) except Exception as e: mi_logger.debug('os.wait() threw %s: %s' % (e.__class__.__name__, str(e))) mi_logger.debug('popen wait returned %s', str(self._logger_popen.wait())) time.sleep(1) self.attach() else: # There was a pidfile for the device. raise InstrumentConnectionException() return logger_pid def disconnect(self, *args, **kwargs): """Disconnect via the instrument connection object @throws InstrumentConnectionException """ mi_logger.info('Disconnecting from device.') self.detach() self._logger.stop() def attach(self, *args, **kwargs): """ """ mi_logger.info('Attaching to device.') self._logger_client.init_comms(self._got_data) def detach(self, *args, **kwargs): """ """ mi_logger.info('Detaching from device.') self._logger_client.stop_comms() def reset(self, *args, **kwargs): """Reset via the instrument connection object""" # Call logger reset here. pass ######################################################################## # Protocol command interface. ######################################################################## def get(self, *args, **kwargs): """Get some parameters @param params A list of parameters to fetch. These must be in the fetchable parameter list @retval results A dict of the parameters that were queried @throws InstrumentProtocolException Confusion dealing with the physical device @throws InstrumentStateException Unable to handle current or future state properly @throws InstrumentTimeoutException Timeout """ pass def set(self, *args, **kwargs): """Get some parameters @throws InstrumentProtocolException Confusion dealing with the physical device @throws InstrumentStateException Unable to handle current or future state properly @throws InstrumentTimeoutException Timeout """ pass def execute(self, *args, **kwargs): """Execute a command @param command A single command as a list with the command ID followed by the parameters for that command @throws InstrumentProtocolException Confusion dealing with the physical device @throws InstrumentStateException Unable to handle current or future state properly @throws InstrumentTimeoutException Timeout """ pass def execute_direct(self, *args, **kwargs): """ """ pass ######################################################################## # TBD. ######################################################################## def get_capabilities(self): """ """ pass ######################################################################## # Helper methods ######################################################################## def _got_data(self, data): """ Called by the logger whenever there is data available """ pass def announce_to_driver(self, type, error_code=None, msg=None): """ Announce an event to the driver via the callback @param type The DriverAnnouncement enum type of the event @param args Any arguments involved @param msg A message to be included @todo Clean this up, promote to InstrumentProtocol? """ assert type != None event = {EventKey:type} if error_code: event.update({EventKey.ERROR_CODE:error_code}) if msg: event.update({EventKey.MESSAGE:msg}) self.send_event(event)