def _handler_connected_set_port_over_current_limits(self, *args, **kwargs): """ """ port_id = kwargs.get('port_id', None) if port_id is None: raise InstrumentException( 'set_port_over_current_limits: missing port_id argument') milliamps = kwargs.get('milliamps', None) if milliamps is None: raise InstrumentException( 'set_port_over_current_limits: missing milliamps argument') microseconds = kwargs.get('microseconds', None) if milliamps is None: raise InstrumentException( 'set_port_over_current_limits: missing microseconds argument') src = kwargs.get('src', None) if src is None: raise InstrumentException( 'set_port_over_current_limits: missing src argument') try: result = self.set_overcurrent_limit(port_id, milliamps, microseconds, src) return None, result except PlatformConnectionException as e: return self._connection_lost( RSNPlatformDriverEvent.SET_PORT_OVER_CURRENT_LIMITS, args, kwargs, e)
def _handler_connected_connect_instrument(self, *args, **kwargs): """ """ port_id = kwargs.get('port_id', None) if port_id is None: raise InstrumentException( 'connect_instrument: missing port_id argument') instrument_id = kwargs.get('instrument_id', None) if instrument_id is None: raise InstrumentException( 'connect_instrument: missing instrument_id argument') attributes = kwargs.get('attributes', None) if attributes is None: raise InstrumentException( 'connect_instrument: missing attributes argument') try: result = self.connect_instrument(port_id, instrument_id, attributes) return PlatformDriverState.CONNECTED, result except PlatformConnectionException as e: return self._connection_lost( RSNPlatformDriverEvent.CONNECT_INSTRUMENT, args, kwargs, e)
def _ftp_schedule_file(self): """ Construct a YAML schedule file and ftp the file to the Instrument server """ # Create a temporary file and write the schedule YAML information to the file try: config_file = tempfile.TemporaryFile() log.debug("temporary file created") if config_file is None or not isinstance(config_file, file): raise InstrumentException("config_file is not a temp file!") config_file.write(self._param_dict.get(Parameter.SCHEDULE)) config_file.seek(0) log.debug("finished writing config file:\n%r", self._param_dict.get(Parameter.SCHEDULE)) except Exception as e: log.error("Create schedule YAML file exception: %s", e) raise e # FTP the schedule file to the ZPLSC server host = '' try: log.debug("Create a ftp session") host = self._param_dict.get_config_value(Parameter.FTP_IP_ADDRESS) log.debug("Got host ip address %s", host) ftp_session = ftplib.FTP() ftp_session.connect(host) ftp_session.login(USER_NAME, PASSWORD) log.debug("ftp session was created...") ftp_session.set_pasv(False) ftp_session.cwd("config") ftp_session.storlines('STOR ' + YAML_FILE_NAME, config_file) files = ftp_session.dir() log.debug("*** Config yaml file sent: %s", files) ftp_session.quit() config_file.close() except (ftplib.socket.error, ftplib.socket.gaierror), e: log.error("ERROR: cannot reach FTP Host %s: %s ", host, e) raise InstrumentException("ERROR: cannot reach FTP Host %s " % host)
def _handler_unconfigured_configure(self, driver_config, *args, **kwargs): """ """ if driver_config is None: raise InstrumentException( 'configure: missing driver_config argument') try: result = self._configure(driver_config) next_state = PlatformDriverState.DISCONNECTED except NodeConfigurationFileException as e: next_state = None log.error("Node Configuration File Error " + e.msg) self._driver_event(DriverAsyncEvent.ERROR, "Node Configuration File Error " + e.msg) return next_state, None except PlatformDriverException as e: next_state = None log.error("Error in platform driver configuration" + e.msg) self._driver_event(DriverAsyncEvent.ERROR, "Node Configuration File Error " + e.msg) return next_state, None return next_state, result
def test_exceptions(self, msg): """ Test exception handling in the driver process. @param msg message string to put in a raised exception to be caught in a test. @raises InstrumentExeption always. """ raise InstrumentException(msg)
def _handler_connected_turn_on_port(self, *args, **kwargs): """ """ port_id = kwargs.get('port_id', None) if port_id is None: raise InstrumentException('turn_on_port: missing port_id argument') src = kwargs.get('src', None) if port_id is None: raise InstrumentException('turn_on_port: missing src argument') try: result = self.turn_on_port(port_id, src) return None, result except PlatformConnectionException as e: return self._connection_lost(RSNPlatformDriverEvent.TURN_ON_PORT, args, kwargs, e)
def run(self): """ Listener thread processing loop. Block on receive from port agent. Receive HEADER_SIZE bytes to receive the entire header. From that, get the length of the whole packet (including header); compute the length of the remaining data and read that. """ self.thread_name = threading.current_thread().name log.info('PortAgentClient listener thread: %s started.', self.thread_name) if self.heartbeat: self.start_heartbeat_timer() while not self._done: try: header = self._receive_n_bytes(HEADER_SIZE) pa_packet = PortAgentPacket() pa_packet.unpack_header(header) data_size = pa_packet.get_data_length() data = self._receive_n_bytes(data_size) # Should have complete port agent packet. pa_packet.attach_data(data) self.handle_packet(pa_packet) except Done: pass except (SocketClosed, socket.error) as e: error_string = 'Listener: %s Socket error while receiving from port agent: %r' % ( self.thread_name, e) log.error(error_string) self.error() except Exception as e: if not isinstance(e, InstrumentException): e = InstrumentException(e.message) log.error(e.get_triple()) self.callback(e) log.info('Port_agent_client thread done listening; going away.')
def _handler_connected_start_profiler_mission(self, *args, **kwargs): """ """ profile_mission_name = kwargs.get('profile_mission_name') if profile_mission_name is None: raise InstrumentException( 'start_profiler_mission: missing profile_mission_name argument' ) src = kwargs.get('src', None) if src is None: raise InstrumentException( 'set_port_over_current_limits: missing src argument') try: result = self.start_profiler_mission(profile_mission_name, src) return None, result except PlatformConnectionException as e: return self._connection_lost( RSNPlatformDriverEvent.START_PROFILER_MISSION, args, kwargs, e)
def _handler_connected_stop_profiler_mission(self, *args, **kwargs): """ """ flag = kwargs.get('flag', None) if flag is None: raise InstrumentException( '_handler_connected_stop_profiler_mission: missing flag argument' ) src = kwargs.get('src', None) if src is None: raise InstrumentException( 'set_port_over_current_limits: missing src argument') try: result = self.stop_profiler_mission(flag, src) return None, result except PlatformConnectionException as e: return self._connection_lost( RSNPlatformDriverEvent.STOP_PROFILER_MISSION, args, kwargs, e)
def run(self): """ Listener thread processing loop. Block on receive from port agent. Receive HEADER_SIZE bytes to receive the entire header. From that, get the length of the whole packet (including header); compute the length of the remaining data and read that. """ self.thread_name = threading.current_thread().name log.info('PortAgentClient listener thread: %s started.', self.thread_name) if self.heartbeat: self.start_heartbeat_timer() while not self._done: try: header = self._receive_n_bytes(HEADER_SIZE) pa_packet = PortAgentPacket() pa_packet.unpack_header(header) data_size = pa_packet.get_data_length() data = self._receive_n_bytes(data_size) # Should have complete port agent packet. pa_packet.attach_data(data) self.handle_packet(pa_packet) except Done: pass except (SocketClosed, socket.error) as e: error_string = 'Listener: %s Socket error while receiving from port agent: %r' % (self.thread_name, e) log.error(error_string) self.error() except Exception as e: if not isinstance(e, InstrumentException): e = InstrumentException(e.message) log.error(e.get_triple()) self.callback(e) log.info('Port_agent_client thread done listening; going away.')
def _handler_connected_disconnect_instrument(self, *args, **kwargs): """ """ port_id = kwargs.get('port_id', None) if port_id is None: raise InstrumentException( 'disconnect_instrument: missing port_id argument') instrument_id = kwargs.get('instrument_id', None) if instrument_id is None: raise InstrumentException( 'disconnect_instrument: missing instrument_id argument') try: result = self.disconnect_instrument(port_id, instrument_id) next_state = None except PlatformConnectionException as e: return self._connection_lost( RSNPlatformDriverEvent.DISCONNECT_INSTRUMENT, args, kwargs, e) return next_state, result
def _handler_connected_execute(self, *args, **kwargs): """ """ if len(args) == 0: raise InstrumentException('execute_resource: missing resource_cmd argument') try: result = self.execute(*args, **kwargs) return None, result except PlatformConnectionException as e: return self._connection_lost(PlatformDriverEvent.EXECUTE, args, kwargs, e)
def _handler_connected_set(self, *args, **kwargs): """ """ attrs = kwargs.get('attrs', None) if attrs is None: raise InstrumentException('set_attribute_values: missing attrs argument') try: result = self.set_attribute_values(attrs) return None, result except PlatformConnectionException as e: return self._connection_lost(PlatformDriverEvent.SET, args, kwargs, e)
def _handler_command_autosample(self, *args, **kwargs): """ Start autosample mode """ next_state = ProtocolState.AUTOSAMPLE result = [] # FTP the driver schedule file to the instrument server self._ftp_schedule_file() # Stop the current running schedule file just in case one is running and # load the driver schedule file host = self._param_dict.get(Parameter.FTP_IP_ADDRESS) port = self._param_dict.get_config_value(Parameter.FTP_PORT) log.debug( "_handler_command_autosample: stop the current schedule file") self._url_request(host, port, '/stop_schedule', data={}) log.debug( "_handler_command_autosample: upload driver YAML file to host %s", host) res = self._url_request(host, port, '/load_schedule', data=json.dumps({'filename': YAML_FILE_NAME})) log.debug(" result from load = %s", res) if res.get('result') != 'OK': raise InstrumentException( '_handler_command_autosample: Load Instrument Schedule File Error.' ) res = self._url_request(host, port, '/start_schedule', data={}) if res.get('result') != 'OK': raise InstrumentException( '_handler_command_autosample: Start Schedule File Error.') return next_state, (next_state, result)
def _build_simple_command(self, cmd, *args): """ Build handler for basic THSPH commands. @param cmd the simple ooicore command to format. @retval The command to be sent to the device. """ instrument_series = self._param_dict.get(Parameter.INSTRUMENT_SERIES) if cmd == Command.GET_SAMPLE: instrument_cmd = self.THSPH_COMMANDS[instrument_series][Command.GET_SAMPLE] else: raise InstrumentException('Unknown THSPH driver command %s' % cmd) return "%s%s" % (instrument_cmd, NEWLINE)
def _handler_unconfigured_configure(self, *args, **kwargs): """ """ driver_config = kwargs.get('driver_config', None) if driver_config is None: raise InstrumentException('configure: missing driver_config argument') try: result = self._configure(driver_config) next_state = PlatformDriverState.DISCONNECTED except PlatformDriverException as e: result = None next_state = None log.error("Error in platform driver configuration", e) return next_state, result
def _handler_connected_start_profiler_mission(self, *args, **kwargs): """ """ # profile_mission_name = kwargs.get('profile_mission_name', None) profile_mission_name = kwargs.get('profile_mission_name', 'Test_Profile_Mission_Name') if profile_mission_name is None: raise InstrumentException( 'start_profiler_mission: missing profile_mission_name argument' ) try: result = self.start_profiler_mission(profile_mission_name) return None, result except PlatformConnectionException as e: return self._connection_lost( RSNPlatformDriverEvent.START_PROFILER_MISSION, args, kwargs, e)
class VadcpProtocol(CommandResponseInstrumentProtocol): """ """ def __init__(self, callback=None): CommandResponseInstrumentProtocol.__init__(self, Prompt, EOLN, callback) # TODO probably promote this convenience to super-class? # _timeout: Default timeout value for operations accepting an # optional timeout argument self._timeout = 30 self._last_data_timestamp = None self.eoln = EOLN self._protocol_fsm = InstrumentFSM(ProtocolState, ProtocolEvent, None, None) # UNKNOWN self._protocol_fsm.add_handler(ProtocolState.UNKNOWN, ProtocolEvent.INITIALIZE, self._handler_initialize) # COMMAND_MODE self._protocol_fsm.add_handler(ProtocolState.COMMAND_MODE, ProtocolEvent.GET_LAST_ENSEMBLE, self._handler_command_get_latest_sample) self._protocol_fsm.add_handler(ProtocolState.COMMAND_MODE, ProtocolEvent.GET_METADATA, self._handler_command_get_metadata) self._protocol_fsm.add_handler( ProtocolState.COMMAND_MODE, ProtocolEvent.RUN_RECORDER_TESTS, self._handler_command_run_recorder_tests) self._protocol_fsm.add_handler(ProtocolState.COMMAND_MODE, ProtocolEvent.RUN_ALL_TESTS, self._handler_command_run_all_tests) self._protocol_fsm.add_handler(ProtocolState.COMMAND_MODE, ProtocolEvent.START_AUTOSAMPLE, self._handler_command_autosample) # AUTOSAMPLE_MODE self._protocol_fsm.add_handler(ProtocolState.AUTOSAMPLE_MODE, ProtocolEvent.STOP_AUTOSAMPLE, self._handler_autosample_stop) self._protocol_fsm.start(ProtocolState.UNKNOWN) def execute_init_protocol(self, *args, **kwargs): """ """ return self._protocol_fsm.on_event(ProtocolEvent.INITIALIZE, *args, **kwargs) def execute_get_latest_sample(self, *args, **kwargs): """ """ return self._protocol_fsm.on_event(ProtocolEvent.GET_LAST_ENSEMBLE, *args, **kwargs) def execute_get_metadata(self, *args, **kwargs): """ """ return self._protocol_fsm.on_event(ProtocolEvent.GET_METADATA, *args, **kwargs) def execute_run_recorder_tests(self, *args, **kwargs): """ """ return self._protocol_fsm.on_event(ProtocolEvent.RUN_RECORDER_TESTS, *args, **kwargs) def execute_run_all_tests(self, *args, **kwargs): """ """ return self._protocol_fsm.on_event(ProtocolEvent.RUN_ALL_TESTS, *args, **kwargs) ################ # State handlers ################ def _handler_initialize(self, *args, **kwargs): """ Determines initial protocol state according to instrument's state """ next_state = None result = None # TODO determine the state. For now, assume command mode self._driver_event(DriverAsyncEvent.STATE_CHANGE) next_state = ProtocolState.COMMAND_MODE return (next_state, result) def _handler_command_get_latest_sample(self, *args, **kwargs): """ """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) next_state = self._protocol_fsm.get_current_state() result = None timeout = kwargs.get('timeout', self._timeout) try: result = self._connection.get_latest_sample(timeout) except TimeoutException, e: raise InstrumentTimeoutException(msg=str(e)) except ClientException, e: log.warn("ClientException while get_latest_sample: %s" % str(e)) raise InstrumentException('ClientException: %s' % str(e))
if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) next_state = self._protocol_fsm.get_current_state() result = None timeout = kwargs.get('timeout', self._timeout) sections = kwargs.get('sections', None) try: result = self._connection.get_metadata(sections, timeout) except TimeoutException, e: raise InstrumentTimeoutException(msg=str(e)) except ClientException, e: log.warn("ClientException while get_metadata: %s" % str(e)) raise InstrumentException('ClientException: %s' % str(e)) return (next_state, result) def _handler_command_run_recorder_tests(self, *args, **kwargs): """ """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) next_state = self._protocol_fsm.get_current_state() result = None timeout = kwargs.get('timeout', self._timeout) try:
def run(self): """ Listener thread processing loop. Block on receive from port agent. Receive HEADER_SIZE bytes to receive the entire header. From that, get the length of the whole packet (including header); compute the length of the remaining data and read that. """ self.thread_name = str(threading.current_thread().name) log.info('PortAgentClient listener thread: %s started.', self.thread_name) if self.heartbeat: self.start_heartbeat_timer() while not self._done: try: log.trace('RX NEW PACKET') header = bytearray(HEADER_SIZE) headerview = memoryview(header) bytes_left = HEADER_SIZE while bytes_left and not self._done: try: bytesrx = self.sock.recv_into(headerview[HEADER_SIZE - bytes_left:], bytes_left) log.trace('RX HEADER BYTES %d LEFT %d SOCK %r' % ( bytesrx, bytes_left, self.sock,)) if bytesrx <= 0: raise SocketClosed() bytes_left -= bytesrx except socket.error as e: if e.errno == errno.EWOULDBLOCK: time.sleep(.1) else: raise # Only do this if we've received the whole header, otherwise (ex. during shutdown) # we can have a completely invalid header, resulting in negative count exceptions. if bytes_left == 0: pa_packet = PortAgentPacket() pa_packet.unpack_header(str(header)) data_size = pa_packet.get_data_length() bytes_left = data_size data = bytearray(data_size) dataview = memoryview(data) log.trace('Expecting DATA BYTES %d' % data_size) while bytes_left and not self._done: try: bytesrx = self.sock.recv_into(dataview[data_size - bytes_left:], bytes_left) log.trace('RX DATA BYTES %d LEFT %d SOCK %r' % ( bytesrx, bytes_left, self.sock,)) if bytesrx <= 0: raise SocketClosed() bytes_left -= bytesrx except socket.error as e: if e.errno == errno.EWOULDBLOCK: time.sleep(.1) else: raise if not self._done: # Should have complete port agent packet. pa_packet.attach_data(str(data)) log.trace("HANDLE PACKET") self.handle_packet(pa_packet) except SocketClosed: error_string = 'Listener thread: %s SocketClosed exception from port_agent socket' \ % self.thread_name log.error(error_string) self._invoke_error_callback(self.recovery_attempt, error_string) # This next statement causes the thread to exit. This # thread is done regardless of which condition exists # above; it is the job of the callbacks to restart the # thread self._done = True except socket.error as e: error_string = 'Listener thread: %s Socket error while receiving from port agent: %r' \ % (self.thread_name, e) log.error(error_string) self._invoke_error_callback(self.recovery_attempt, error_string) # This next statement causes the thread to exit. This # thread is done regardless of which condition exists # above; it is the job of the callbacks to restart the # thread self._done = True except Exception as e: if not isinstance(e, InstrumentException): e = InstrumentException(e.message) log.error(e.get_triple()) self.default_callback_error(e) log.info('Port_agent_client thread done listening; going away.')
class VadcpDriver(InstrumentDriver): """ driver """ def __init__(self, evt_callback): """ Constructor. @param evt_callback Driver process event callback. """ InstrumentDriver.__init__(self, evt_callback) self._ensembles_recd = 0 # _client created in configure() self._client = None self._state = DriverState.UNCONFIGURED # TODO probably promote this convenience to super-class? self._timeout = 30 """Default timeout value for operations accepting an optional timeout argument.""" def _assert_state(self, obj): """ Asserts that the current state is either the same as the one given (if not a list) or one of the elements of the given list. @raises InstrumentStateException if the assertion fails """ cs = self.get_current_state() if isinstance(obj, list): if cs in obj: return # OK else: raise InstrumentStateException( msg="current state=%s not one of %s" % (cs, str(obj))) state = obj if cs != state: raise InstrumentStateException("current state=%s, expected=%s" % (cs, state)) def _data_listener(self, pd0): self._ensembles_recd += 1 log.info("_data_listener: received PD0=%s" % prefix(pd0)) self._driver_event(DriverAsyncEvent.SAMPLE, val=pd0) ############################################################# # Device connection interface. ############################################################# def initialize(self, *args, **kwargs): """ Initialize driver connection, bringing communications parameters into unconfigured state (no connection object). @raises InstrumentStateException if command not allowed in current state """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) if self._state == DriverState.UNCONFIGURED: assert self._client is None return if self._client is not None: try: self._client.end() finally: self._client = None self._driver_event(DriverAsyncEvent.STATE_CHANGE) self._state = DriverState.UNCONFIGURED def configure(self, *args, **kwargs): """ Configure the driver for communications with the device via port agent / logger (valid but unconnected connection object). @param config comms config dict. @raises InstrumentStateException if command not allowed in current state @throws InstrumentParameterException if missing comms or invalid config dict. """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) self._assert_state(DriverState.UNCONFIGURED) config = kwargs.get('config', None) if config is None: # raise InstrumentParameterException(msg="'config' parameter required") config = args[0] c4 = config['four_beam'] outfilename = 'vadcp_output_%s_%s.txt' % (c4.host, c4.port) u4_outfile = file(outfilename, 'w') c5 = config['fifth_beam'] outfilename = 'vadcp_output_%s_%s.txt' % (c5.host, c5.port) u5_outfile = file(outfilename, 'w') # Verify dict and construct connection client. log.info("setting VadcpClient with config: %s" % config) try: self._client = VadcpClient(config, u4_outfile, u5_outfile) except (TypeError, KeyError): raise InstrumentParameterException('Invalid comms config dict.' ' config=%s' % config) self._driver_event(DriverAsyncEvent.STATE_CHANGE) self._state = DriverState.DISCONNECTED def connect(self, *args, **kwargs): """ Establish communications with the device via port agent / logger (connected connection object). @raises InstrumentStateException if command not allowed in current state @throws InstrumentConnectionException if the connection failed. """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) self._assert_state(DriverState.DISCONNECTED) self._client.set_data_listener(self._data_listener) self._client.connect() self._driver_event(DriverAsyncEvent.STATE_CHANGE) self._state = DriverState.CONNECTED def disconnect(self, *args, **kwargs): """ Disconnect from device via port agent / logger. @raises InstrumentStateException if command not allowed in current state """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) self._assert_state(DriverState.CONNECTED) self._client.end() self._driver_event(DriverAsyncEvent.STATE_CHANGE) self._state = DriverState.DISCONNECTED def execute_init_protocol(self, *args, **kwargs): # added here as part of the preparation using the general scheme # TODO pass def execute_get_latest_sample(self, *args, **kwargs): if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) self._assert_state(DriverState.CONNECTED) timeout = kwargs.get('timeout', self._timeout) try: result = self._client.get_latest_sample(timeout) return result except TimeoutException, e: raise InstrumentTimeoutException(msg=str(e)) except ClientException, e: log.warn("ClientException while get_latest_sample: %s" % str(e)) raise InstrumentException('ClientException: %s' % str(e))
class TrhphInstrumentDriver(InstrumentDriver): """ TRHPH driver """ def __init__(self, evt_callback): """ Constructor. @param evt_callback Driver process event callback. """ InstrumentDriver.__init__(self, evt_callback) # _trhph_client created in configure() self._trhph_client = None self._state = TrhphDriverState.UNCONFIGURED # TODO probably promote this convenience to super-class? self._timeout = 30 """Default timeout value for operations accepting an optional timeout argument.""" def _assert_state(self, obj): """ Asserts that the current state is either the same as the one given (if not a list) or one of the elements of the given list. @raises InstrumentStateException if the assertion fails """ cs = self.get_current_state() if isinstance(obj, list): if cs in obj: return # OK else: raise InstrumentStateException( msg="current state=%s not one of %s" % (cs, str(obj))) state = obj if cs != state: raise InstrumentStateException("current state=%s, expected=%s" % (cs, state)) ############################################################# # Device connection interface. ############################################################# def initialize(self, *args, **kwargs): """ Initialize driver connection, bringing communications parameters into unconfigured state (no connection object). @raises InstrumentStateException if command not allowed in current state """ # print # print("trhph driver: args=%s kwargs=%s" % (str(args), str(kwargs))) # print("trhph driver: state=%s" % str(self._state)) # print("trhph driver: _trhph_client=%s" % str(self._trhph_client)) # print if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) if self._state == TrhphDriverState.UNCONFIGURED: assert self._trhph_client is None return # assert self._trhph_client is not None # try: # self._trhph_client.end() # finally: # self._trhph_client = None if self._trhph_client is not None: try: self._trhph_client.end() finally: self._trhph_client = None self._state = TrhphDriverState.UNCONFIGURED def configure(self, *args, **kwargs): """ Configure the driver for communications with the device via port agent / logger (valid but unconnected connection object). @param config comms config dict. @raises InstrumentStateException if command not allowed in current state @throws InstrumentParameterException if missing comms or invalid config dict. """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) self._assert_state(TrhphDriverState.UNCONFIGURED) config = kwargs.get('config', None) if config is None: # raise InstrumentParameterException(msg="'config' parameter required") config = args[0] # Verify dict and construct connection client. try: addr = config['addr'] port = config['port'] if isinstance(addr, str) and \ isinstance(port, int) and len(addr) > 0: # self._connection = LoggerClient(addr, port) def _data_listener(sample): log.info("_data_listener: sample = %s" % str(sample)) host = addr outfile = file('trhph_output.txt', 'a') log.info("setting TrhphClient to connect to %s:%s" % (host, port)) self.trhph_client = TrhphClient(host, port, outfile, True) self.trhph_client.set_data_listener(_data_listener) else: raise InstrumentParameterException( msg='Invalid comms config dict') except (TypeError, KeyError): raise InstrumentParameterException( msg='Invalid comms config dict.') self._state = TrhphDriverState.DISCONNECTED def connect(self, *args, **kwargs): """ Establish communications with the device via port agent / logger (connected connection object). @raises InstrumentStateException if command not allowed in current state @throws InstrumentConnectionException if the connection failed. """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) self._assert_state(TrhphDriverState.DISCONNECTED) self.trhph_client.connect() self._state = TrhphDriverState.CONNECTED def disconnect(self, *args, **kwargs): """ Disconnect from device via port agent / logger. @raises InstrumentStateException if command not allowed in current state """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) self._assert_state(TrhphDriverState.CONNECTED) self.trhph_client.end() self._state = TrhphDriverState.DISCONNECTED ############################################################# # Command and control interface. ############################################################# def get_resource(self, *args, **kwargs): """ Retrieve device parameters. @param params DriverParameter.ALL or a list of parameters to retrieve. @param timeout Timeout for each involved instrument interation, self._timeout by default. @retval parameter : value dict. @raises InstrumentParameterException if missing or invalid get parameters. @raises InstrumentStateException if command not allowed in current state """ if log.isEnabledFor(logging.DEBUG): log.debug("args=%s kwargs=%s" % (str(args), str(kwargs))) self._assert_state(TrhphDriverState.CONNECTED) params = kwargs.get('params', None) if params is None: # raise InstrumentParameterException(msg= # "'params' parameter required") params = args[0] if params == DriverParameter.ALL: params = TrhphParameter.list() elif not isinstance(params, (list, tuple)): raise InstrumentParameterException( msg='params must be list or tuple.') timeout = kwargs.get('timeout', self._timeout) # gather data collection params if any of them are requested: data_collec_params = {} if TrhphParameter.TIME_BETWEEN_BURSTS in params or \ TrhphParameter.VERBOSE_MODE in params: seconds, is_data_only = self._get_data_collection_params(timeout) verbose = not is_data_only data_collec_params[TrhphParameter.TIME_BETWEEN_BURSTS] = seconds data_collec_params[TrhphParameter.VERBOSE_MODE] = verbose params = list(set(params)) # remove any duplicates result = {} for param in params: if param == TrhphParameter.TIME_BETWEEN_BURSTS or \ param == TrhphParameter.VERBOSE_MODE: value = data_collec_params[param] else: # value = InstErrorCode.INVALID_PARAMETER raise InstrumentParameterException(msg='invalid parameter %s' % param) result[param] = value return result def _get_data_collection_params(self, timeout): """ Gets the get_data_collection_params. """ try: return self.trhph_client.get_data_collection_params(timeout) except TimeoutException, e: raise InstrumentTimeoutException(msg=str(e)) except TrhphClientException, e: raise InstrumentException(str(e))