コード例 #1
0
    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)
コード例 #2
0
    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)
コード例 #3
0
    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)
コード例 #4
0
    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
コード例 #5
0
 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)
コード例 #6
0
    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)
コード例 #7
0
    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.')
コード例 #8
0
    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)
コード例 #9
0
    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)
コード例 #10
0
    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.')
コード例 #11
0
    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
コード例 #12
0
    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)
コード例 #13
0
    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)
コード例 #14
0
    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)
コード例 #15
0
ファイル: driver.py プロジェクト: petercable/mi-instrument
    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)
コード例 #16
0
    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
コード例 #17
0
    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)
コード例 #18
0
ファイル: driver.py プロジェクト: gxtchen/marine-integrations
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))
コード例 #19
0
ファイル: driver.py プロジェクト: gxtchen/marine-integrations
        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:
コード例 #20
0
    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.')
コード例 #21
0
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))
コード例 #22
0
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))