def init_driver_process_client(self): """ @brief Launch the driver process and driver client @retval return driver process and driver client object """ self.log.info("Startup Driver Process") self.log.debug("Server Command Port: %d" % self.server_command_port()) self.log.debug("Server Event Port: %d" % self.server_event_port()) self.log.debug("Driver Module: %s" % self.driver_module()) self.log.debug("Driver Class: %s" % self.driver_class()) # Spawn the driver subprocess driver_process = ZmqDriverProcess.launch_process(self.server_command_port(), self.server_event_port(), self.driver_module(), self.driver_class()) self._driver_process = driver_process self.log.info("Startup Driver Client") self.log.debug("Server Address: %s" % self.server_address()) self.log.debug("Server Command Port: %d" % self.server_command_port()) self.log.debug("Server Event Port: %d" % self.server_event_port()) # Create client and start messaging. driver_client = ZmqDriverClient(self.server_address(), self.server_command_port(), self.server_event_port()) self._driver_client = driver_client self.clear_events() driver_client.start_messaging(self.event_received) return driver_process, driver_client
def test_connect(self): """ Test to establish device comms and transition to command state. """ # Launch driver process. driver_process = ZmqDriverProcess.launch_process(self.cmd_port, self.evt_port, self.dvr_mod, self.dvr_cls) # Create client and start messaging. driver_client = ZmqDriverClient(self.server_addr, self.cmd_port, self.evt_port) driver_client.start_messaging() time.sleep(2) # Configure driver for comms and transition to disconnected. reply = driver_client.cmd_dvr('configure', self.comms_config) time.sleep(2) # Establish device comms and transition to command. reply = driver_client.cmd_dvr('connect') time.sleep(2) # Disconnect devcie comms and transition to disconnected. reply = driver_client.cmd_dvr('disconnect') time.sleep(2) # Initialize driver and transition to unconfigured. reply = driver_client.cmd_dvr('initialize') time.sleep(2) # Terminate driver process and stop client messaging. driver_client.done() driver_process.wait()
def start_driver(self): """ Start the driver process. """ # Launch driver process based on test config. this_pid = os.getpid() (dvr_proc, cmd_port, evt_port) = ZmqDriverProcess.launch_process(self.driver_module, self.driver_class, self.work_dir, this_pid) self._dvr_proc = dvr_proc mi_logger.info('Started driver process for %d %d %s %s', cmd_port, evt_port, self.driver_module, self.driver_class) mi_logger.info('Driver process pid %d', self._dvr_proc.pid) # Create driver client. self._dvr_client = ZmqDriverClient('localhost', cmd_port, evt_port) mi_logger.info('Created driver client for %d %d %s %s', cmd_port, evt_port, self.driver_module, self.driver_class) # Start client messaging. self._dvr_client.start_messaging(self.evt_recd) mi_logger.info('Driver messaging started.') gevent.sleep(.5)
def _start_driver(self, dvr_config): """ Start the driver process and driver client. @param dvr_config The driver configuration. @param comms_config The driver communications configuration. @retval None or error. """ try: cmd_port = dvr_config['cmd_port'] evt_port = dvr_config['evt_port'] dvr_mod = dvr_config['dvr_mod'] dvr_cls = dvr_config['dvr_cls'] svr_addr = dvr_config['svr_addr'] except (TypeError, KeyError): # Not a dict. or missing required parameter. log.error('Insturment agent %s missing required parameter in start_driver.', self._proc_name) return InstErrorCode.REQUIRED_PARAMETER # Launch driver process. self._dvr_proc = ZmqDriverProcess.launch_process(cmd_port, evt_port, dvr_mod, dvr_cls) self._dvr_proc.poll() if self._dvr_proc.returncode: # Error proc didn't start. log.error('Insturment agent %s driver process did not launch.', self._proc_name) return InstErrorCode.AGENT_INIT_FAILED log.info('Insturment agent %s launched driver process.', self._proc_name) # Create client and start messaging. self._dvr_client = ZmqDriverClient(svr_addr, cmd_port, evt_port) self._dvr_client.start_messaging(self.evt_recv) log.info('Insturment agent %s driver process client started.', self._proc_name) time.sleep(1) try: retval = self._dvr_client.cmd_dvr('process_echo', 'Test.') log.info('Insturment agent %s driver process echo test: %s.', self._proc_name, str(retval)) except Exception: self._dvr_proc.terminate() self._dvr_proc.wait() self._dvr_proc = None self._dvr_client = None log.error('Insturment agent %s error commanding driver process.', self._proc_name) return InstErrorCode.AGENT_INIT_FAILED else: log.info('Insturment agent %s started its driver.', self._proc_name) self._construct_packet_factories()
def test_process(self): """ Test for correct launch of driver process and communications, including asynchronous driver events. """ # Launch driver process. driver_process = ZmqDriverProcess.launch_process(self.cmd_port, self.evt_port, self.dvr_mod, self.dvr_cls) # Create client and start messaging. driver_client = ZmqDriverClient(self.server_addr, self.cmd_port, self.evt_port) self.clear_events() driver_client.start_messaging(self.evt_recd) time.sleep(2) # Add test to verify process exists. # Send a test message to the process interface, confirm result. msg = 'I am a ZMQ message going to the process.' reply = driver_client.cmd_dvr('process_echo', msg) self.assertEqual(reply,'process_echo: '+msg) # Send a test message to the driver interface, confirm result. msg = 'I am a ZMQ message going to the driver.' reply = driver_client.cmd_dvr('driver_echo', msg) self.assertEqual(reply, 'driver_echo: '+msg) # Test the event thread publishes and client side picks up events. events = [ 'I am important event #1!', 'And I am important event #2!' ] reply = driver_client.cmd_dvr('test_events', events=events) time.sleep(2) # Confirm the events received are as expected. self.assertEqual(self.events, events) # Terminate driver process and stop client messaging. driver_client.done() driver_process.wait()
def setUp(self): super(BarsDriverTest, self).setUp() # Zmq parameters used by driver process and client. self.server_addr = 'localhost' self.cmd_port = 5556 self.evt_port = 5557 # Driver module parameters. self.dvr_mod = 'ion.services.mi.drivers.uw_bars.driver' self.dvr_cls = 'BarsInstrumentDriver' self._driver_process = ZmqDriverProcess.launch_process(self.cmd_port, self.evt_port, self.dvr_mod, self.dvr_cls) self._driver_client = ZmqDriverClient(self.server_addr, self.cmd_port, self.evt_port) self._driver_client.start_messaging() time.sleep(1) self.addCleanup(self._clean_up)
class CiLogger(object): """ ResourceAgent derived class for the CI Logger. This class interfaces CG components to driver resources in the ION system. It provides support for the CG DCL_Control and Data_Mgr interfaces and translates/forwards these on to the CI driver and CG_Logger. """ def __init__(self): log.debug("CiLogger.__init__:") # start driver driver_config = {'svr_addr': 'localhost', 'cmd_port': 5556, 'evt_port': 5557, 'dvr_mod': 'ion.services.mi.drivers.sbe37_driver', 'dvr_cls': 'SBE37Driver'} result = self._start_driver(driver_config) if not isinstance(result, int): log.error("CiLogger.__init__: " + result[1]) return log.info("CiLogger.__init__: started driver with process id of " + str(result)) # configure driver and have it start the port agent comms_config = {SBE37Channel.CTD: {'method':'ethernet', 'device_addr': 'sbe37-simulator.oceanobservatories.org', 'device_port': 4001, 'server_addr': 'localhost', 'server_port': 8888} } cfg_result = self._dvr_client.cmd_dvr('configure', comms_config) channels = [key for (key, val) in cfg_result.iteritems() if not InstErrorCode.is_error(val)] con_result = self._dvr_client.cmd_dvr('connect', channels) result = cfg_result.copy() try: for (key, val) in con_result.iteritems(): result[key] = val except: log.error("CiLogger.__init__: driver connection failure - " + str(con_result)) return self._active_channels = self._dvr_client.cmd_dvr('get_active_channels') if len(self._active_channels) <= 0: log.error("CiLogger.__init__: driver connection failure - no active channels") return log.info("CiLogger.__init__: driver connected to instrument " + comms_config[SBE37Channel.CTD]['device_addr']) def start_streaming(self): log.info("CiLogger.start_streaming():") return CgMsgTypes.ACK, "Instrument started" ############################################################################### # Event callback and handling. ############################################################################### def evt_recv(self, evt): """ Callback to receive asynchronous driver events. @param evt The driver event received. """ log.info('CiLogger.evt_recv(): received driver event %s', str(evt)) # TODO: send 'sample' events to the CG_Logger ############################################################################### # Private helpers. ############################################################################### def _go_inactive(self, *args, **kwargs): """ Handler for go_inactive agent command in idle state. Attempt to disconnect and initialize all active driver channels. Swtich to inactive state if successful. """ channels = self._dvr_client.cmd_dvr('get_active_channels') dis_result = self._dvr_client.cmd_dvr('disconnect', channels) [key for (key, val) in dis_result.iteritems() if not InstErrorCode.is_error(val)] self._stop_driver() def _go_streaming(self, *args, **kwargs): """ Handler for go_streaming agent command in observatory state. Send start autosample command to driver and switch to streaming state if successful. """ result = self._dvr_client.cmd_dvr('start_autosample', *args, **kwargs) if isinstance(result, dict): if any([val == None for val in result.values()]): next_state = InstrumentAgentState.STREAMING def _go_observatory(self, *args, **kwargs): """ Handler for go_observatory agent command within streaming state. Command driver to stop autosampling, and switch to observatory mode if successful. """ result = self._dvr_client.cmd_dvr('stop_autosample', *args, **kwargs) if isinstance(result, dict): if all([val == None for val in result.values()]): next_state = InstrumentAgentState.OBSERVATORY def _start_driver(self, dvr_config): """ Start the driver process and driver client. @param dvr_config The driver configuration. @param comms_config The driver communications configuration. @retval None or error. """ try: cmd_port = dvr_config['cmd_port'] evt_port = dvr_config['evt_port'] dvr_mod = dvr_config['dvr_mod'] dvr_cls = dvr_config['dvr_cls'] svr_addr = dvr_config['svr_addr'] except (TypeError, KeyError): # Not a dict. or missing required parameter. log.error('CiLogger._start_driver(): missing required parameter in start_driver.') return InstErrorCode.REQUIRED_PARAMETER # Launch driver process. self._dvr_proc = ZmqDriverProcess.launch_process(cmd_port, evt_port, dvr_mod, dvr_cls) self._dvr_proc.poll() if self._dvr_proc.returncode: # Error proc didn't start. log.error('CiLogger._start_driver(): driver process did not launch.') return InstErrorCode.AGENT_INIT_FAILED log.info('CiLogger._start_driver(): launched driver process.') # Create client and start messaging. self._dvr_client = ZmqDriverClient(svr_addr, cmd_port, evt_port) self._dvr_client.start_messaging(self.evt_recv) log.info('CiLogger._start_driver(): driver process client started.') time.sleep(1) try: retval = self._dvr_client.cmd_dvr('process_echo', 'Test.') log.info('CiLogger._start_driver(): driver process echo test: %s.' %str(retval)) except Exception: self._dvr_proc.terminate() self._dvr_proc.wait() self._dvr_proc = None self._dvr_client = None log.error('CiLogger._start_driver(): error commanding driver process.') return InstErrorCode.AGENT_INIT_FAILED else: log.info('CiLogger._start_driver(): started its driver.') return self._dvr_proc.pid def _stop_driver(self): """ Stop the driver process and driver client. @retval None. """ if self._dvr_client: self._dvr_client.done() self._dvr_proc.wait() self._dvr_proc = None self._dvr_client = None log.info('CiLogger._stop_driver(): stopped its driver.') time.sleep(1)
class DriverIntegrationTestSupport(object): """ Common functionality helpful for driver integration testing. """ def __init__(self, driver_module, driver_class, device_addr, device_port, delim=None, work_dir='/tmp/'): """ @param driver_module @param driver_class @param device_addr @param device_port @param delim 2-element delimiter to indicate traffic from the driver in the logfile. See EthernetDeviceLogger.launch_process for default value. @param work_dir by default, '/tmp/' """ object.__init__(self) self.driver_module = driver_module self.driver_class = driver_class self.device_addr = device_addr self.device_port = device_port self.delim = delim self.work_dir = work_dir # Should clear this in setup self._events = [] self._dvr_client = None 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 def stop_pagent(self): """ Stop the port agent. """ if self._pagent: pid = self._pagent.get_pid() if pid: mi_logger.info('Stopping pagent pid %i', pid) self._pagent.stop() else: mi_logger.info('No port agent running.') def start_driver(self): """ Start the driver process. """ # Launch driver process based on test config. this_pid = os.getpid() (dvr_proc, cmd_port, evt_port) = ZmqDriverProcess.launch_process(self.driver_module, self.driver_class, self.work_dir, this_pid) self._dvr_proc = dvr_proc mi_logger.info('Started driver process for %d %d %s %s', cmd_port, evt_port, self.driver_module, self.driver_class) mi_logger.info('Driver process pid %d', self._dvr_proc.pid) # Create driver client. self._dvr_client = ZmqDriverClient('localhost', cmd_port, evt_port) mi_logger.info('Created driver client for %d %d %s %s', cmd_port, evt_port, self.driver_module, self.driver_class) # Start client messaging. self._dvr_client.start_messaging(self.evt_recd) mi_logger.info('Driver messaging started.') gevent.sleep(.5) def stop_driver(self): """ Method to shut down the driver process. Attempt normal shutdown, and kill the process if unsuccessful. """ if self._dvr_proc: mi_logger.info('Stopping driver process pid %d', self._dvr_proc.pid) if self._dvr_client: self._dvr_client.done() self._dvr_proc.wait() self._dvr_client = None else: try: mi_logger.info('Killing driver process.') self._dvr_proc.kill() except OSError: pass self._dvr_proc = None def evt_recd(self, evt): """ Simple callback to catch events from the driver for verification. """ self._events.append(evt)
class InstrumentAgent(ResourceAgent): """ ResourceAgent derived class for the instrument agent. This class logically abstracts instruments as taskable resources in the ION system. It directly provides common functionality (common state model, common resource interface, point of publication) and creates a driver process to specialize for particular hardware. """ def __init__(self, initial_state=InstrumentAgentState.UNINITIALIZED): """ Initialize instrument agent prior to pyon process initialization. Define state machine, initialize member variables. """ ResourceAgent.__init__(self) # Instrument agent state machine. self._fsm = InstrumentFSM(InstrumentAgentState, InstrumentAgentEvent, InstrumentAgentEvent.ENTER, InstrumentAgentEvent.EXIT, InstErrorCode.UNHANDLED_EVENT) # Populate state machine for all state-events. self._fsm.add_handler(InstrumentAgentState.POWERED_DOWN, InstrumentAgentEvent.ENTER, self._handler_powered_down_enter) self._fsm.add_handler(InstrumentAgentState.POWERED_DOWN, InstrumentAgentEvent.EXIT, self._handler_powered_down_exit) self._fsm.add_handler(InstrumentAgentState.UNINITIALIZED, InstrumentAgentEvent.ENTER, self._handler_uninitialized_enter) self._fsm.add_handler(InstrumentAgentState.UNINITIALIZED, InstrumentAgentEvent.EXIT, self._handler_uninitialized_exit) self._fsm.add_handler(InstrumentAgentState.UNINITIALIZED, InstrumentAgentEvent.POWER_DOWN, self._handler_uninitialized_power_down) self._fsm.add_handler(InstrumentAgentState.UNINITIALIZED, InstrumentAgentEvent.INITIALIZE, self._handler_uninitialized_initialize) self._fsm.add_handler(InstrumentAgentState.UNINITIALIZED, InstrumentAgentEvent.RESET, self._handler_uninitialized_reset) self._fsm.add_handler(InstrumentAgentState.INACTIVE, InstrumentAgentEvent.ENTER, self._handler_inactive_enter) self._fsm.add_handler(InstrumentAgentState.INACTIVE, InstrumentAgentEvent.EXIT, self._handler_inactive_exit) self._fsm.add_handler(InstrumentAgentState.INACTIVE, InstrumentAgentEvent.INITIALIZE, self._handler_inactive_initialize) self._fsm.add_handler(InstrumentAgentState.INACTIVE, InstrumentAgentEvent.RESET, self._handler_inactive_reset) self._fsm.add_handler(InstrumentAgentState.INACTIVE, InstrumentAgentEvent.GO_ACTIVE, self._handler_inactive_go_active) self._fsm.add_handler(InstrumentAgentState.INACTIVE, InstrumentAgentEvent.GET_RESOURCE_COMMANDS, self._handler_get_resource_commands) self._fsm.add_handler(InstrumentAgentState.INACTIVE, InstrumentAgentEvent.GET_RESOURCE_PARAMS, self._handler_get_resource_params) self._fsm.add_handler(InstrumentAgentState.IDLE, InstrumentAgentEvent.ENTER, self._handler_idle_enter) self._fsm.add_handler(InstrumentAgentState.IDLE, InstrumentAgentEvent.EXIT, self._handler_idle_exit) self._fsm.add_handler(InstrumentAgentState.IDLE, InstrumentAgentEvent.GO_INACTIVE, self._handler_idle_go_inactive) self._fsm.add_handler(InstrumentAgentState.IDLE, InstrumentAgentEvent.RESET, self._handler_idle_reset) self._fsm.add_handler(InstrumentAgentState.IDLE, InstrumentAgentEvent.RUN, self._handler_idle_run) self._fsm.add_handler(InstrumentAgentState.IDLE, InstrumentAgentEvent.GET_RESOURCE_COMMANDS, self._handler_get_resource_commands) self._fsm.add_handler(InstrumentAgentState.IDLE, InstrumentAgentEvent.GET_RESOURCE_PARAMS, self._handler_get_resource_params) self._fsm.add_handler(InstrumentAgentState.STOPPED, InstrumentAgentEvent.ENTER, self._handler_stopped_enter) self._fsm.add_handler(InstrumentAgentState.STOPPED, InstrumentAgentEvent.EXIT, self._handler_stopped_exit) self._fsm.add_handler(InstrumentAgentState.STOPPED, InstrumentAgentEvent.GO_INACTIVE, self._handler_stopped_go_inactive) self._fsm.add_handler(InstrumentAgentState.STOPPED, InstrumentAgentEvent.RESET, self._handler_stopped_reset) self._fsm.add_handler(InstrumentAgentState.STOPPED, InstrumentAgentEvent.CLEAR, self._handler_stopped_clear) self._fsm.add_handler(InstrumentAgentState.STOPPED, InstrumentAgentEvent.RESUME, self._handler_stopped_resume) self._fsm.add_handler(InstrumentAgentState.STOPPED, InstrumentAgentEvent.GET_RESOURCE_COMMANDS, self._handler_get_resource_commands) self._fsm.add_handler(InstrumentAgentState.STOPPED, InstrumentAgentEvent.GET_RESOURCE_PARAMS, self._handler_get_resource_params) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.ENTER, self._handler_observatory_enter) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.EXIT, self._handler_observatory_exit) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.GO_INACTIVE, self._handler_observatory_go_inactive) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.RESET, self._handler_observatory_reset) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.CLEAR, self._handler_observatory_clear) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.PAUSE, self._handler_observatory_pause) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.GO_STREAMING, self._handler_observatory_go_streaming) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.GO_DIRECT_ACCESS, self._handler_observatory_go_direct_access) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.GET_RESOURCE_COMMANDS, self._handler_get_resource_commands) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.GET_RESOURCE_PARAMS, self._handler_get_resource_params) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.GET_PARAMS, self._handler_get_params) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.SET_PARAMS, self._handler_observatory_set_params) self._fsm.add_handler(InstrumentAgentState.OBSERVATORY, InstrumentAgentEvent.EXECUTE_RESOURCE, self._handler_observatory_execute_resource) self._fsm.add_handler(InstrumentAgentState.STREAMING, InstrumentAgentEvent.ENTER, self._handler_streaming_enter) self._fsm.add_handler(InstrumentAgentState.STREAMING, InstrumentAgentEvent.EXIT, self._handler_streaming_exit) self._fsm.add_handler(InstrumentAgentState.STREAMING, InstrumentAgentEvent.GO_INACTIVE, self._handler_streaming_go_inactive) self._fsm.add_handler(InstrumentAgentState.STREAMING, InstrumentAgentEvent.RESET, self._handler_streaming_reset) self._fsm.add_handler(InstrumentAgentState.STREAMING, InstrumentAgentEvent.GO_OBSERVATORY, self._handler_streaming_go_observatory) self._fsm.add_handler(InstrumentAgentState.STREAMING, InstrumentAgentEvent.GET_RESOURCE_COMMANDS, self._handler_get_resource_commands) self._fsm.add_handler(InstrumentAgentState.STREAMING, InstrumentAgentEvent.GET_RESOURCE_PARAMS, self._handler_get_resource_params) self._fsm.add_handler(InstrumentAgentState.STREAMING, InstrumentAgentEvent.GET_PARAMS, self._handler_get_params) self._fsm.add_handler(InstrumentAgentState.DIRECT_ACCESS, InstrumentAgentEvent.ENTER, self._handler_direct_access_enter) self._fsm.add_handler(InstrumentAgentState.DIRECT_ACCESS, InstrumentAgentEvent.EXIT, self._handler_direct_access_exit) self._fsm.add_handler(InstrumentAgentState.DIRECT_ACCESS, InstrumentAgentEvent.GO_OBSERVATORY, self._handler_direct_access_go_observatory) self._fsm.add_handler(InstrumentAgentState.DIRECT_ACCESS, InstrumentAgentEvent.GET_RESOURCE_COMMANDS, self._handler_get_resource_commands) self._fsm.add_handler(InstrumentAgentState.DIRECT_ACCESS, InstrumentAgentEvent.GET_RESOURCE_PARAMS, self._handler_get_resource_params) ############################################################################### # Instrument agent internal parameters. ############################################################################### # State machine start state, defaults to unconfigured. self._initial_state = initial_state # Driver configuration. Passed as part of the spawn configuration # or with an initialize command. Sets driver specific # context. self._dvr_config = None # Process ID of the driver process. Useful to identify and signal # the process if necessary. Set by transition to inactive. self._dvr_pid = None # The driver process popen object. To terminate, signal, wait on, # or otherwise interact with the driver process via subprocess. # Set by transition to inactive. self._dvr_proc = None # The driver client for communicating to the driver process in # request-response or event publication. Set by transition to # inactive. self._dvr_client = None # UUID of the current transaction. self.transaction_id = None # List of pending transactions. self._pending_transactions = [] # Dictionary of data stream IDs for data publishing. Constructed # by stream_config agent config member during process on_init. self._data_streams = {} # Dictionary of data stream publishers. Constructed by # stream_config agent config member during process on_init. self._data_publishers = {} # Factories for stream packets. Constructed by driver # configuration information on transition to inactive. self._packet_factories = {} # Stream registrar to create publishers. Used to create # stream publishers, set during process on_init. self._stream_registrar = None # Latitude value. Set by subscription to platform. Used to # append data packets prior to publication. self._lat = 0 # Longitude value. Set by subscription to platform. Used to # append data packets prior to publication. self._lon = 0 ############################################################################### # Instrument agent parameter capabilities. ############################################################################### self.aparam_ia_param = None def on_init(self): """ Instrument agent pyon process initialization. Init objects that depend on the container services and start state machine. """ # The registrar to create publishers. self._stream_registrar = StreamPublisherRegistrar(process=self, node=self.container.node) # Set the driver config from the agent config if present. self._dvr_config = self.CFG.get('driver_config', None) # Construct stream publishers. self._construct_data_publishers() # Start state machine. self._fsm.start(self._initial_state) ############################################################################### # Event callback and handling. ############################################################################### def evt_recv(self, evt): """ Callback to receive asynchronous driver events. @param evt The driver event received. """ log.info('Instrument agent %s received driver event %s', self._proc_name, str(evt)) try: if evt['type'] == 'sample': name = evt['name'] value = evt['value'] value['lat'] = [self._lat] value['lon'] = [self._lon] value['stream_id'] = self._data_streams[name] if isinstance(value, dict): packet = self._packet_factories[name](**value) self._data_publishers[name].publish(packet) log.info('Instrument agent %s published data packet.', self._proc_name) except (KeyError, TypeError) as e: pass except Exception as e: log.info('Instrument agent %s error %s', self._proc_name, str(e)) ############################################################################### # Instrument agent state transition interface. # All the following commands are forwarded as a eponymous event to # the agent state machine and return the state handler result. ############################################################################### def acmd_power_up(self, *args, **kwargs): """ Agent power_up command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.POWER_UP, *args, **kwargs) def acmd_power_down(self, *args, **kwargs): """ Agent power_down command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.POWER_DOWN, *args, **kwargs) def acmd_initialize(self, *args, **kwargs): """ Agent initialize command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.INITIALIZE, *args, **kwargs) def acmd_reset(self, *args, **kwargs): """ Agent reset command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.RESET, *args, **kwargs) def acmd_go_active(self, *args, **kwargs): """ Agent go_active command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.GO_ACTIVE, *args, **kwargs) def acmd_go_inactive(self, *args, **kwargs): """ Agent go_inactive command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.GO_INACTIVE, *args, **kwargs) def acmd_run(self, *args, **kwargs): """ Agent run command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.RUN, *args, **kwargs) def acmd_clear(self, *args, **kwargs): """ Agent clear command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.CLEAR, *args, **kwargs) def acmd_pause(self, *args, **kwargs): """ Agent pause command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.PAUSE, *args, **kwargs) def acmd_resume(self, *args, **kwargs): """ Agent resume command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.RESUME, *args, **kwargs) def acmd_go_streaming(self, *args, **kwargs): """ Agent go_streaming command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.GO_STREAMING, *args, **kwargs) def acmd_go_direct_access(self, *args, **kwargs): """ Agent go_direct_access command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.GO_DIRECT_ACCESS, *args, **kwargs) def acmd_go_observatory(self, *args, **kwargs): """ Agent go_observatory command. Forward with args to state machine. """ return self._fsm.on_event(InstrumentAgentEvent.GO_OBSERVATORY, *args, **kwargs) ############################################################################### # Misc instrument agent command interface. ############################################################################### def acmd_get_current_state(self, *args, **kwargs): """ Query the agent current state. """ return self._fsm.get_current_state() ############################################################################### # Instrument agent capabilities interface. These functions override base # class helper functinos for specialized instrument agent behavior. ############################################################################### def _get_resource_commands(self): """ Get driver resource commands. Send event to state machine and return response or empty list if none. """ return self._fsm.on_event(InstrumentAgentEvent.GET_RESOURCE_COMMANDS) or [] def _get_resource_params(self): """ Get driver resource parameters. Send event to state machine and return response or empty list if none. """ return self._fsm.on_event(InstrumentAgentEvent.GET_RESOURCE_PARAMS) or [] ############################################################################### # Instrument agent resource interface. These functions override ResourceAgent # base class functions to specialize behavior for instrument driver resources. ############################################################################### def get_param(self, resource_id="", name=''): """ Get driver resource parameters. Send get_params event and args to agent state machine to handle request. NOTE: Need to adjust the ResourceAgent class and client for instrument interface needs. @param resource_id @param name A list of (channel, name) tuples of driver parameter to retrieve @retval Dict of (channel, name) : value parameter values if handled. """ params = name return self._fsm.on_event(InstrumentAgentEvent.GET_PARAMS, params) or {} def set_param(self, resource_id="", name='', value=''): """ Set driver resource parameters. Send set_params event and args to agent state machine to handle set driver resource parameters request. NOTE: Need to adjust the ResourceAgent class and client for instrument interface needs. @param resource_id @param name a Dict of (channel, name) : value for driver parameters to be set. @retval Dict of (channel, name) : None or Error if handled. """ params = name return self._fsm.on_event(InstrumentAgentEvent.SET_PARAMS, params) or {} def execute(self, resource_id="", command=None): """ Execute driver resource command. Send execute_resource event and args to agent state machine to handle resource execute request. @param resource_id @param command agent command object containing the driver command to execute @retval Resrouce agent command response object if handled. """ return self._fsm.on_event(InstrumentAgentEvent.EXECUTE_RESOURCE, command) ############################################################################### # Instrument agent transaction interface. ############################################################################### def acmd_start_transaction(self): """ """ pass def acmd_end_transaction(self): """ """ pass ############################################################################### # Powered down state handlers. # TBD. This state requires clarification of use. ############################################################################### def _handler_powered_down_enter(self, *args, **kwargs): """ Handler upon entry to powered_down state. """ log.info('Instrument agent entered state %s', self._fsm.get_current_state()) def _handler_powered_down_exit(self, *args, **kwargs): """ Handler upon exit from powered_down state. """ log.info('Instrument agent left state %s', self._fsm.get_current_state()) ############################################################################### # Uninitialized state handlers. # Default start state. The driver has not been configured or started. ############################################################################### def _handler_uninitialized_enter(self, *args, **kwargs): """ Handler upon entry to uninitialized state. """ log.info('Instrument agent entered state %s', self._fsm.get_current_state()) def _handler_uninitialized_exit(self, *args, **kwargs): """ Handler upon exit from uninitialized state. """ log.info('Instrument agent left state %s', self._fsm.get_current_state()) def _handler_uninitialized_power_down(self, *args, **kwargs): """ Handler for power_down agent command in uninitialized state. """ result = InstErrorCode.NOT_IMPLEMENTED next_state = None return (next_state, result) def _handler_uninitialized_initialize(self, dvr_config=None, *args, **kwargs): """ Handler for initialize agent command in uninitialized state. Attempt to start driver process with driver config supplied as argument or in agent configuration. Switch to inactive state if successful. """ result = None next_state = None self._dvr_config = dvr_config or self._dvr_config result = self._start_driver(self._dvr_config) if not result: next_state = InstrumentAgentState.INACTIVE return (next_state, result) def _handler_uninitialized_reset(self, *args, **kwargs): """ Handler for reset agent command in uninitialized state. Exit and reenter uninitializeds state. """ result = None next_state = InstrumentAgentState.UNINITIALIZED return (next_state, result) ############################################################################### # Inactive state handlers. # The driver is configured and started, but not connected. ############################################################################### def _handler_inactive_enter(self, *args, **kwargs): """ Handler upon entry to inactive state. """ log.info('Instrument agent entered state %s', self._fsm.get_current_state()) def _handler_inactive_exit(self, *args, **kwargs): """ Handler upon exit from inactive state. """ log.info('Instrument agent left state %s', self._fsm.get_current_state()) def _handler_inactive_initialize(self, dvr_config=None, *args, **kwargs): """ Handler for initialize command in inactive state. Stop and restart driver process using new driver config if supplied. """ result = None next_state = None result = self._stop_driver() if result: return (next_state, result) self._dvr_config = dvr_config or self._dvr_config result = self._start_driver(self._dvr_config) if not result: next_state = InstrumentAgentState.INACTIVE return (next_state, result) def _handler_inactive_reset(self, *args, **kwargs): """ Handler for reset agent command in inactive state. Stop the driver process and switch to unitinitalized state if successful. """ result = None next_state = None result = self._stop_driver() if not result: next_state = InstrumentAgentState.UNINITIALIZED return (next_state, result) def _handler_inactive_go_active(self, dvr_comms=None, *args, **kwargs): """ Handler for go_active agent command in inactive state. Attempt to establsih communications with all device channels. Switch to active state if any channels activated. """ result = None next_state = None if not dvr_comms: dvr_comms = self._dvr_config.get('comms_config', None) cfg_result = self._dvr_client.cmd_dvr('configure', dvr_comms) channels = [key for (key, val) in cfg_result.iteritems() if not InstErrorCode.is_error(val)] con_result = self._dvr_client.cmd_dvr('connect', channels) result = cfg_result.copy() for (key, val) in con_result.iteritems(): result[key] = val self._active_channels = self._dvr_client.cmd_dvr('get_active_channels') if len(self._active_channels)>0: next_state = InstrumentAgentState.IDLE return (next_state, result) ############################################################################### # Idle state handlers. ############################################################################### def _handler_idle_enter(self, *args, **kwargs): """ Handler upon entry to idle state. """ log.info('Instrument agent entered state %s', self._fsm.get_current_state()) def _handler_idle_exit(self, *args, **kwargs): """ Handler upon exit from idle state. """ log.info('Instrument agent left state %s', self._fsm.get_current_state()) def _handler_idle_go_inactive(self, *args, **kwargs): """ Handler for go_inactive agent command in idle state. Attempt to disconnect and initialize all active driver channels. Swtich to inactive state if successful. """ result = None next_state = None channels = self._dvr_client.cmd_dvr('get_active_channels') dis_result = self._dvr_client.cmd_dvr('disconnect', channels) [key for (key, val) in dis_result.iteritems() if not InstErrorCode.is_error(val)] init_result = self._dvr_client.cmd_dvr('initialize', channels) result = dis_result.copy() for (key, val) in init_result.iteritems(): result[key] = val self._active_channels = self._dvr_client.cmd_dvr('get_active_channels') if len(self._active_channels)==0: next_state = InstrumentAgentState.INACTIVE return (next_state, result) def _handler_idle_reset(self, *args, **kwargs): """ Handler for reset agent command in idle state. """ result = None next_state = None return (next_state, result) def _handler_idle_run(self, *args, **kwargs): """ Handler for run agent command in idle state. Switch to observatory state. """ result = None next_state = InstrumentAgentState.OBSERVATORY return (next_state, result) ############################################################################### # Stopped state handlers. ############################################################################### def _handler_stopped_enter(self, *args, **kwargs): """ Handler for entry into stopped state. """ log.info('Instrument agent entered state %s', self._fsm.get_current_state()) def _handler_stopped_exit(self, *args, **kwargs): """ Handler for exit from stopped state. """ log.info('Instrument agent left state %s', self._fsm.get_current_state()) def _handler_stopped_go_inactive(self, *args, **kwargs): """ Handler for go_inactive agent command in stopped state. """ result = None next_state = None return (next_state, result) def _handler_stopped_reset(self, *args, **kwargs): """ Handler for reset agent command in stopped state. """ result = None next_state = None return (next_state, result) def _handler_stopped_clear(self, *args, **kwargs): """ Handler for clear agent command in stopped state. """ result = None next_state = None return (next_state, result) def _handler_stopped_resume(self, *args, **kwargs): """ Handler for resume agent command in stopped state. """ result = None next_state = None return (next_state, result) ############################################################################### # Observatory state handlers. ############################################################################### def _handler_observatory_enter(self, *args, **kwargs): """ Handler upon entry to observatory state. """ log.info('Instrument agent entered state %s', self._fsm.get_current_state()) def _handler_observatory_exit(self, *args, **kwargs): """ Handler upon exit from observatory state. """ log.info('Instrument agent left state %s', self._fsm.get_current_state()) def _handler_observatory_go_inactive(self, *args, **kwargs): """ Handler for go_inactive agent command in observatory state. Attempt to disconnect and initialize all active driver channels. Switch to inactive state if successful. """ result = None next_state = None channels = self._dvr_client.cmd_dvr('get_active_channels') dis_result = self._dvr_client.cmd_dvr('disconnect', channels) [key for (key, val) in dis_result.iteritems() if not InstErrorCode.is_error(val)] init_result = self._dvr_client.cmd_dvr('initialize', channels) result = dis_result.copy() for (key, val) in init_result.iteritems(): result[key] = val self._active_channels = self._dvr_client.cmd_dvr('get_active_channels') if len(self._active_channels)==0: next_state = InstrumentAgentState.INACTIVE return (next_state, result) def _handler_observatory_reset(self, *args, **kwargs): """ Handler for reset agent command in observatory state. """ result = None next_state = None return (next_state, result) def _handler_observatory_clear(self, *args, **kwargs): """ Handler for clear agent command in observatory state. """ result = None next_state = None return (next_state, result) def _handler_observatory_pause(self, *args, **kwargs): """ Handler for pause agent command in observatory state. """ result = None next_state = None return (next_state, result) def _handler_observatory_go_streaming(self, *args, **kwargs): """ Handler for go_streaming agent command in observatory state. Send start autosample command to driver and switch to streaming state if successful. """ result = None next_state = None result = self._dvr_client.cmd_dvr('start_autosample', *args, **kwargs) if isinstance(result, dict): if any([val == None for val in result.values()]): next_state = InstrumentAgentState.STREAMING return (next_state, result) def _handler_observatory_go_direct_access(self, *args, **kwargs): """ Handler for go_direct_access agent ommand in observatory state. """ result = None next_state = None return (next_state, result) def _handler_get_params(self, params, *args, **kwargs): """ Handler for get_params resource command in observatory state. Send get command to driver and return result. """ result = self._dvr_client.cmd_dvr('get', params) next_state = None return (next_state, result) def _handler_observatory_set_params(self, params, *args, **kwargs): """ Handler for set_params resource command in observatory state. Send the set command to the driver and return result. """ result = self._dvr_client.cmd_dvr('set', params) next_state = None return (next_state, result) def _handler_observatory_execute_resource(self, command, *args, **kwargs): """ Handler for execute_resource command in observatory state. Issue driver command and return the result. """ result = None next_state = None if not command: raise iex.BadRequest("execute argument 'command' not present") if not command.command: raise iex.BadRequest("command not set") cmd_res = IonObject("AgentCommandResult", command_id=command.command_id, command=command.command) cmd_res.ts_execute = get_ion_ts() command.command = 'execute_' + command.command res = self._dvr_client.cmd_dvr(command.command, *command.args, **command.kwargs) cmd_res.status = 0 cmd_res.result = res result = cmd_res return (next_state, result) ############################################################################### # Streaming state handlers. ############################################################################### def _handler_streaming_enter(self, *args, **kwargs): """ Handler for entry to streaming state. """ log.info('Instrument agent entered state %s', self._fsm.get_current_state()) def _handler_streaming_exit(self, *args, **kwargs): """ Handler upon exit from streaming state. """ log.info('Instrument agent left state %s', self._fsm.get_current_state()) def _handler_streaming_go_inactive(self, *args, **kwargs): """ Handler for go_inactive agent command within streaming state. """ result = None next_state = None return (next_state, result) def _handler_streaming_reset(self, *args, **kwargs): """ Handler for reset agent command within streaming state. """ result = None next_state = None return (next_state, result) def _handler_streaming_go_observatory(self, *args, **kwargs): """ Handler for go_observatory agent command within streaming state. Command driver to stop autosampling, and switch to observatory mode if successful. """ result = None next_state = None result = self._dvr_client.cmd_dvr('stop_autosample', *args, **kwargs) if isinstance(result, dict): if all([val == None for val in result.values()]): next_state = InstrumentAgentState.OBSERVATORY return (next_state, result) ############################################################################### # Direct access state handlers. ############################################################################### def _handler_direct_access_enter(self, *args, **kwargs): """ Handler upon direct access entry. """ log.info('Instrument agent entered state %s', self._fsm.get_current_state()) def _handler_direct_access_exit(self, *args, **kwargs): """ Handler upon direct access exit. """ log.info('Instrument agent left state %s', self._fsm.get_current_state()) def _handler_direct_access_go_observatory(self, *args, **kwargs): """ Handler for go_observatory agent command within direct access state. """ result = None next_state = None return (next_state, result) ############################################################################### # Get resource state handlers. # Available for all states with a valid driver process. ############################################################################### def _handler_get_resource_params(self, *args, **kwargs): """ Handler for get_resource_params resource command. Send get_resource_params and args to driver and return result. """ result = self._dvr_client.cmd_dvr('get_resource_params') next_state = None return (next_state, result) def _handler_get_resource_commands(self, *args, **kwargs): """ Handler for get_resource_commands resource command. Send get_resource_commands and args to driver and return result. """ result = self._dvr_client.cmd_dvr('get_resource_commands') next_state = None return (next_state, result) ############################################################################### # Private helpers. ############################################################################### def _start_driver(self, dvr_config): """ Start the driver process and driver client. @param dvr_config The driver configuration. @param comms_config The driver communications configuration. @retval None or error. """ try: cmd_port = dvr_config['cmd_port'] evt_port = dvr_config['evt_port'] dvr_mod = dvr_config['dvr_mod'] dvr_cls = dvr_config['dvr_cls'] svr_addr = dvr_config['svr_addr'] except (TypeError, KeyError): # Not a dict. or missing required parameter. log.error('Insturment agent %s missing required parameter in start_driver.', self._proc_name) return InstErrorCode.REQUIRED_PARAMETER # Launch driver process. self._dvr_proc = ZmqDriverProcess.launch_process(cmd_port, evt_port, dvr_mod, dvr_cls) self._dvr_proc.poll() if self._dvr_proc.returncode: # Error proc didn't start. log.error('Insturment agent %s driver process did not launch.', self._proc_name) return InstErrorCode.AGENT_INIT_FAILED log.info('Insturment agent %s launched driver process.', self._proc_name) # Create client and start messaging. self._dvr_client = ZmqDriverClient(svr_addr, cmd_port, evt_port) self._dvr_client.start_messaging(self.evt_recv) log.info('Insturment agent %s driver process client started.', self._proc_name) time.sleep(1) try: retval = self._dvr_client.cmd_dvr('process_echo', 'Test.') log.info('Insturment agent %s driver process echo test: %s.', self._proc_name, str(retval)) except Exception: self._dvr_proc.terminate() self._dvr_proc.wait() self._dvr_proc = None self._dvr_client = None log.error('Insturment agent %s error commanding driver process.', self._proc_name) return InstErrorCode.AGENT_INIT_FAILED else: log.info('Insturment agent %s started its driver.', self._proc_name) self._construct_packet_factories() def _stop_driver(self): """ Stop the driver process and driver client. @retval None. """ if self._dvr_client: self._dvr_client.done() self._dvr_proc.wait() self._dvr_proc = None self._dvr_client = None self._clear_packet_factories() log.info('Insturment agent %s stopped its driver.', self._proc_name) time.sleep(1) def _construct_data_publishers(self): """ Construct the stream publishers from the stream_config agent config variable. @retval None """ stream_config = self.CFG.stream_config for (name, stream_id) in stream_config.iteritems(): self._data_streams[name] = stream_id publisher = self._stream_registrar.create_publisher(stream_id=stream_id) self._data_publishers[name] = publisher log.info('Instrumen agent %s created publisher for stream %s', self._proc_name, name) def _construct_packet_factories(self): """ Construct packet factories from packet_config member of the driver_config. @retval None """ packet_config = self._dvr_config['packet_config'] for (name, val) in packet_config.iteritems(): if val: mod = val[0] cls = val[1] import_str = 'from %s import %s' % (mod, cls) ctor_str = 'ctor = %s' % cls try: exec import_str exec ctor_str except Exception: log.error('Instrument agent %s had error creating packet factories from %s.%s', self._proc_name, mod, cls) else: self._packet_factories[name] = ctor log.info('Instrument agent %s created packet factory for stream %s', self._proc_name, name) def _clear_packet_factories(self): """ Delete packet factories. @retval None """ self._packet_factories.clear() log.info('Instrument agent %s deleted packet factories.', self._proc_name) ############################################################################### # Misc and test. ############################################################################### def test_ia(self): log.info('Hello from the instrument agent!')
class TestSBE16Driver(PyonTestCase): """ Integration tests for the sbe16 driver. This class tests and shows use patterns for the sbe16 driver as a zmq driver process. """ def setUp(self): """ Setup test cases. """ # Clear driver event list. self._events = [] # The port agent object. Used to start and stop the port agent. self._pagent = None # The driver process popen object. self._dvr_proc = None # The driver client. self._dvr_client = None # Create and start the port agent. mi_logger.info('start') self._start_pagent() self.addCleanup(self._stop_pagent) # Create and start the driver. self._start_driver() self.addCleanup(self._stop_driver) 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 _stop_pagent(self): """ Stop the port agent. """ if self._pagent: pid = self._pagent.get_pid() if pid: mi_logger.info('Stopping pagent pid %i', pid) self._pagent.stop() else: mi_logger.info('No port agent running.') def _start_driver(self): """ Start the driver process. """ # Launch driver process based on test config. this_pid = os.getpid() (dvr_proc, cmd_port, evt_port) = ZmqDriverProcess.launch_process(DVR_MOD, DVR_CLS, WORK_DIR, this_pid) self._dvr_proc = dvr_proc mi_logger.info('Started driver process for %d %d %s %s', cmd_port, evt_port, DVR_MOD, DVR_CLS) mi_logger.info('Driver process pid %d', self._dvr_proc.pid) # Create driver client. self._dvr_client = ZmqDriverClient('localhost', cmd_port, evt_port) mi_logger.info('Created driver client for %d %d %s %s', cmd_port, evt_port, DVR_MOD, DVR_CLS) # Start client messaging. self._dvr_client.start_messaging(self.evt_recd) mi_logger.info('Driver messaging started.') gevent.sleep(.5) def _stop_driver(self): """ Method to shut down the driver process. Attempt normal shutdown, and kill the process if unsuccessful. """ if self._dvr_proc: mi_logger.info('Stopping driver process pid %d', self._dvr_proc.pid) if self._dvr_client: self._dvr_client.done() self._dvr_proc.wait() self._dvr_client = None else: try: mi_logger.info('Killing driver process.') self._dvr_proc.kill() except OSError: pass self._dvr_proc = None def evt_recd(self, evt): """ Simple callback to catch events from the driver for verification. """ self._events.append(evt) def assertSampleDict(self, val): """ Verify the value is a sample dictionary for the sbe16. """ #{'p': [-6.945], 'c': [0.08707], 't': [20.002], 'time': [1333752198.450622]} self.assertTrue(isinstance(val, dict)) self.assertTrue(val.has_key('c')) self.assertTrue(val.has_key('t')) self.assertTrue(val.has_key('p')) self.assertTrue(val.has_key('time')) c = val['c'][0] t = val['t'][0] p = val['p'][0] time = val['time'][0] self.assertTrue(isinstance(c, float)) self.assertTrue(isinstance(t, float)) self.assertTrue(isinstance(p, float)) self.assertTrue(isinstance(time, float)) def assertParamDict(self, pd, all_params=False): """ Verify all device parameters exist and are correct type. """ if all_params: self.assertEqual(set(pd.keys()), set(PARAMS.keys())) #print str(pd) #print str(PARAMS) for (key, type_val) in PARAMS.iteritems(): #print key self.assertTrue(isinstance(pd[key], type_val)) else: for (key, val) in pd.iteritems(): self.assertTrue(PARAMS.has_key(key)) self.assertTrue(isinstance(val, PARAMS[key])) def assertParamVals(self, params, correct_params): """ Verify parameters take the correct values. """ self.assertEqual(set(params.keys()), set(correct_params.keys())) for (key, val) in params.iteritems(): correct_val = correct_params[key] if isinstance(val, float): # Verify to 5% of the larger value. max_val = max(abs(val), abs(correct_val)) self.assertAlmostEqual(val, correct_val, delta=max_val*.01) else: # int, bool, str, or tuple of same self.assertEqual(val, correct_val) def test_process(self): """ Test for correct launch of driver process and communications, including asynchronous driver events. """ # Verify processes exist. self.assertNotEqual(self._dvr_proc, None) drv_pid = self._dvr_proc.pid self.assertTrue(isinstance(drv_pid, int)) self.assertNotEqual(self._pagent, None) pagent_pid = self._pagent.get_pid() self.assertTrue(isinstance(pagent_pid, int)) # Send a test message to the process interface, confirm result. msg = 'I am a ZMQ message going to the process.' reply = self._dvr_client.cmd_dvr('process_echo', msg) self.assertEqual(reply,'process_echo: '+msg) # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) # Send a test message to the driver interface, confirm result. msg = 'I am a ZMQ message going to the driver.' reply = self._dvr_client.cmd_dvr('driver_echo', msg) self.assertEqual(reply, 'driver_echo: '+msg) # Test the event thread publishes and client side picks up events. events = [ 'I am important event #1!', 'And I am important event #2!' ] reply = self._dvr_client.cmd_dvr('test_events', events=events) gevent.sleep(1) # Confirm the events received are as expected. self.assertEqual(self._events, events) # Test the exception mechanism. with self.assertRaises(InstrumentException): exception_str = 'Oh no, something bad happened!' reply = self._dvr_client.cmd_dvr('test_exceptions', exception_str) # Verify we received a driver error event. gevent.sleep(1) error_events = [evt for evt in self._events if isinstance(evt, dict) and evt['type']==DriverAsyncEvent.ERROR] self.assertTrue(len(error_events) == 1) def test_config(self): """ Test to configure the driver process for device comms and transition to disconnected state. """ # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Initialize the driver and transition to unconfigured. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver returned state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) def test_connect(self): """ Test configuring and connecting to the device through the port agent. Discover device state. """ # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('connect') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.UNKNOWN) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('discover') # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('disconnect') # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Initialize the driver and transition to unconfigured. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) def test_get_set(self): """ Test device parameter access. """ # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) reply = self._dvr_client.cmd_dvr('connect') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.UNKNOWN) reply = self._dvr_client.cmd_dvr('discover') # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) # Get all device parameters. Confirm all expected keys are retrived # and have correct type. reply = self._dvr_client.cmd_dvr('get', SBE16Parameter.ALL) self.assertParamDict(reply, True) # Remember original configuration. orig_config = reply # Grab a subset of parameters. params = [ SBE16Parameter.TA0, SBE16Parameter.INTERVAL, SBE16Parameter.STORETIME, SBE16Parameter.TCALDATE ] reply = self._dvr_client.cmd_dvr('get', params) self.assertParamDict(reply) # Remember the original subset. orig_params = reply # Construct new parameters to set. old_date = orig_params[SBE16Parameter.TCALDATE] new_params = { SBE16Parameter.TA0 : orig_params[SBE16Parameter.TA0] * 1.2, SBE16Parameter.INTERVAL : orig_params[SBE16Parameter.INTERVAL] + 1, SBE16Parameter.STORETIME : not orig_params[SBE16Parameter.STORETIME], SBE16Parameter.TCALDATE : (old_date[0], old_date[1], old_date[2] + 1) } # Set parameters and verify. reply = self._dvr_client.cmd_dvr('set', new_params) reply = self._dvr_client.cmd_dvr('get', params) self.assertParamVals(reply, new_params) # Restore original parameters and verify. reply = self._dvr_client.cmd_dvr('set', orig_params) reply = self._dvr_client.cmd_dvr('get', params) self.assertParamVals(reply, orig_params) # Retrieve the configuration and ensure it matches the original. # Remove samplenum as it is switched by autosample and storetime. reply = self._dvr_client.cmd_dvr('get', SBE16Parameter.ALL) reply.pop('SAMPLENUM') orig_config.pop('SAMPLENUM') self.assertParamVals(reply, orig_config) # Disconnect from the port agent. reply = self._dvr_client.cmd_dvr('disconnect') # Test the driver is disconnected. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Deconfigure the driver. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) def test_poll(self): """ Test sample polling commands and events. """ # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) reply = self._dvr_client.cmd_dvr('connect') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.UNKNOWN) reply = self._dvr_client.cmd_dvr('discover') # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) # Poll for a sample and confirm result. reply = self._dvr_client.cmd_dvr('execute_acquire_sample') self.assertSampleDict(reply) # Poll for a sample and confirm result. reply = self._dvr_client.cmd_dvr('execute_acquire_sample') self.assertSampleDict(reply) # Poll for a sample and confirm result. reply = self._dvr_client.cmd_dvr('execute_acquire_sample') self.assertSampleDict(reply) # Confirm that 3 samples arrived as published events. gevent.sleep(1) sample_events = [evt for evt in self._events if evt['type']==DriverAsyncEvent.SAMPLE] self.assertEqual(len(sample_events), 3) # Disconnect from the port agent. reply = self._dvr_client.cmd_dvr('disconnect') # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Deconfigure the driver. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) def test_autosample(self): """ Test autosample mode. """ # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('connect') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.UNKNOWN) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('discover') # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) # Make sure the device parameters are set to sample frequently and # to transmit. params = { SBE16Parameter.NAVG : 1, SBE16Parameter.INTERVAL : 5, SBE16Parameter.TXREALTIME : True } reply = self._dvr_client.cmd_dvr('set', params) reply = self._dvr_client.cmd_dvr('execute_start_autosample') # Test the driver is in autosample mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.AUTOSAMPLE) # Wait for a few samples to roll in. gevent.sleep(30) # Return to command mode. Catch timeouts and retry if necessary. count = 0 while True: try: reply = self._dvr_client.cmd_dvr('execute_stop_autosample') except TimeoutError: count += 1 if count >= 5: self.fail('Could not wakeup device to leave autosample mode.') else: break # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) # Verify we received at least 2 samples. sample_events = [evt for evt in self._events if evt['type']==DriverAsyncEvent.SAMPLE] self.assertTrue(len(sample_events) >= 2) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('disconnect') # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Initialize the driver and transition to unconfigured. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) @unittest.skip('Not supported by simulator and very long (> 5 min).') def test_test(self): """ Test the hardware testing mode. """ # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('connect') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.UNKNOWN) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('discover') # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) start_time = time.time() reply = self._dvr_client.cmd_dvr('execute_test') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.TEST) while state != SBE16ProtocolState.COMMAND: gevent.sleep(5) elapsed = time.time() - start_time mi_logger.info('Device testing %f seconds elapsed.' % elapsed) state = self._dvr_client.cmd_dvr('get_current_state') # Verify we received the test result and it passed. test_results = [evt for evt in self._events if evt['type']==DriverAsyncEvent.TEST_RESULT] self.assertTrue(len(test_results) == 1) self.assertEqual(test_results[0]['value']['success'], 'Passed') # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('disconnect') # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Initialize the driver and transition to unconfigured. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) def test_errors(self): """ Test response to erroneous commands and parameters. """ # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) # Assert for an unknown driver command. with self.assertRaises(UnknownCommandError): reply = self._dvr_client.cmd_dvr('bogus_command') # Assert for a known command, invalid state. with self.assertRaises(StateError): reply = self._dvr_client.cmd_dvr('execute_acquire_sample') # Assert we forgot the comms parameter. with self.assertRaises(ParameterError): reply = self._dvr_client.cmd_dvr('configure') # Assert we send a bad config object (not a dict). with self.assertRaises(ParameterError): BOGUS_CONFIG = 'not a config dict' reply = self._dvr_client.cmd_dvr('configure', BOGUS_CONFIG) # Assert we send a bad config object (missing addr value). with self.assertRaises(ParameterError): BOGUS_CONFIG = COMMS_CONFIG.copy() BOGUS_CONFIG.pop('addr') reply = self._dvr_client.cmd_dvr('configure', BOGUS_CONFIG) # Assert we send a bad config object (bad addr value). with self.assertRaises(ParameterError): BOGUS_CONFIG = COMMS_CONFIG.copy() BOGUS_CONFIG['addr'] = '' reply = self._dvr_client.cmd_dvr('configure', BOGUS_CONFIG) # Configure for comms. reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Assert for a known command, invalid state. with self.assertRaises(StateError): reply = self._dvr_client.cmd_dvr('execute_acquire_sample') reply = self._dvr_client.cmd_dvr('connect') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.UNKNOWN) # Assert for a known command, invalid state. with self.assertRaises(StateError): reply = self._dvr_client.cmd_dvr('execute_acquire_sample') reply = self._dvr_client.cmd_dvr('discover') # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) # Poll for a sample and confirm result. reply = self._dvr_client.cmd_dvr('execute_acquire_sample') self.assertSampleDict(reply) # Assert for a known command, invalid state. with self.assertRaises(StateError): reply = self._dvr_client.cmd_dvr('execute_stop_autosample') # Assert for a known command, invalid state. with self.assertRaises(StateError): reply = self._dvr_client.cmd_dvr('connect') # Get all device parameters. Confirm all expected keys are retrived # and have correct type. reply = self._dvr_client.cmd_dvr('get', SBE16Parameter.ALL) self.assertParamDict(reply, True) # Assert get fails without a parameter. with self.assertRaises(ParameterError): reply = self._dvr_client.cmd_dvr('get') # Assert get fails without a bad parameter (not ALL or a list). with self.assertRaises(ParameterError): bogus_params = 'I am a bogus param list.' reply = self._dvr_client.cmd_dvr('get', bogus_params) # Assert get fails without a bad parameter (not ALL or a list). #with self.assertRaises(InvalidParameterValueError): with self.assertRaises(ParameterError): bogus_params = [ 'a bogus parameter name', SBE16Parameter.INTERVAL, SBE16Parameter.STORETIME, SBE16Parameter.TCALDATE ] reply = self._dvr_client.cmd_dvr('get', bogus_params) # Assert we cannot set a bogus parameter. with self.assertRaises(ParameterError): bogus_params = { 'a bogus parameter name' : 'bogus value' } reply = self._dvr_client.cmd_dvr('set', bogus_params) # Assert we cannot set a real parameter to a bogus value. with self.assertRaises(ParameterError): bogus_params = { SBE16Parameter.INTERVAL : 'bogus value' } reply = self._dvr_client.cmd_dvr('set', bogus_params) # Disconnect from the port agent. reply = self._dvr_client.cmd_dvr('disconnect') # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Deconfigure the driver. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) @unittest.skip('Not supported by simulator.') def test_discover_autosample(self): """ Test the device can discover autosample mode. """ # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('connect') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.UNKNOWN) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('discover') # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) # Make sure the device parameters are set to sample frequently. params = { SBE16Parameter.NAVG : 1, SBE16Parameter.INTERVAL : 5 } reply = self._dvr_client.cmd_dvr('set', params) reply = self._dvr_client.cmd_dvr('execute_start_autosample') # Test the driver is in autosample mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.AUTOSAMPLE) # Let a sample or two come in. gevent.sleep(30) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('disconnect') # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Initialize the driver and transition to unconfigured. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED) # Wait briefly before we restart the comms. gevent.sleep(10) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('configure', COMMS_CONFIG) # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('connect') # Test the driver is in unknown state. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.UNKNOWN) # Configure driver for comms and transition to disconnected. count = 0 while True: try: reply = self._dvr_client.cmd_dvr('discover') except TimeoutError: count += 1 if count >=5: self.fail('Could not discover device state.') else: break # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.AUTOSAMPLE) # Let a sample or two come in. # This device takes awhile to begin transmitting again after you # prompt it in autosample mode. gevent.sleep(30) # Return to command mode. Catch timeouts and retry if necessary. count = 0 while True: try: reply = self._dvr_client.cmd_dvr('execute_stop_autosample') except TimeoutError: count += 1 if count >= 5: self.fail('Could not wakeup device to leave autosample mode.') else: break # Test the driver is in command mode. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, SBE16ProtocolState.COMMAND) # Configure driver for comms and transition to disconnected. reply = self._dvr_client.cmd_dvr('disconnect') # Test the driver is configured for comms. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.DISCONNECTED) # Initialize the driver and transition to unconfigured. reply = self._dvr_client.cmd_dvr('initialize') # Test the driver is in state unconfigured. state = self._dvr_client.cmd_dvr('get_current_state') self.assertEqual(state, DriverConnectionState.UNCONFIGURED)
def test_autosample(self): """ Test autosample command and state, including events. """ # Launch driver process. driver_process = ZmqDriverProcess.launch_process(self.cmd_port, self.evt_port, self.dvr_mod, self.dvr_cls) # Create client and start messaging. driver_client = ZmqDriverClient(self.server_addr, self.cmd_port, self.evt_port) driver_client.start_messaging() time.sleep(2) reply = driver_client.cmd_dvr('configure', self.comms_config) time.sleep(2) reply = driver_client.cmd_dvr('connect') time.sleep(2) reply = driver_client.cmd_dvr('start_autosample') time.sleep(30) while True: reply = driver_client.cmd_dvr('stop_autosample') if not reply[SBE37Channel.CTD]: break time.sleep(2) time.sleep(2) reply = driver_client.cmd_dvr('disconnect') time.sleep(2) # Deconfigure the driver. reply = driver_client.cmd_dvr('initialize') time.sleep(2) # Terminate driver process and stop client messaging. driver_client.done() driver_process.wait()
def test_poll(self): """ Test sample polling commands and events. """ # Launch driver process. driver_process = ZmqDriverProcess.launch_process(self.cmd_port, self.evt_port, self.dvr_mod, self.dvr_cls) # Create client and start messaging. driver_client = ZmqDriverClient(self.server_addr, self.cmd_port, self.evt_port) self.clear_events() driver_client.start_messaging(self.evt_recd) time.sleep(2) reply = driver_client.cmd_dvr('configure', self.comms_config) time.sleep(2) reply = driver_client.cmd_dvr('connect') time.sleep(2) reply = driver_client.cmd_dvr('get_active_channels') time.sleep(2) reply = driver_client.cmd_dvr('execute_acquire_sample') time.sleep(2) reply = driver_client.cmd_dvr('execute_acquire_sample') time.sleep(2) reply = driver_client.cmd_dvr('execute_acquire_sample') time.sleep(2) print 'EVENTS RECEIVED:' print str(self.events) reply = driver_client.cmd_dvr('disconnect') time.sleep(2) # Deconfigure the driver. reply = driver_client.cmd_dvr('initialize') time.sleep(2) # Terminate driver process and stop client messaging. driver_client.done() driver_process.wait()
def test_get_set(self): """ Test driver parameter get/set interface including device persistence. TA2=-4.858579e-06 PTCA1=-0.6603433 TCALDATE=(8, 11, 2005) """ # Launch driver process. driver_process = ZmqDriverProcess.launch_process(self.cmd_port, self.evt_port, self.dvr_mod, self.dvr_cls) # Create client and start messaging. driver_client = ZmqDriverClient(self.server_addr, self.cmd_port, self.evt_port) driver_client.start_messaging() time.sleep(3) # Configure driver for comms and transition to disconnected. reply = driver_client.cmd_dvr('configure', self.comms_config) time.sleep(2) # Establish devcie comms and transition to command. reply = driver_client.cmd_dvr('connect') time.sleep(2) # Get all parameters. get_params = [ (SBE37Channel.CTD, SBE37Parameter.ALL) ] reply = driver_client.cmd_dvr('get', get_params) time.sleep(2) # Check overall and individual parameter success. Check parameter types. self.assertIsInstance(reply, dict) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.TA2)], float) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.PTCA1)], float) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.TCALDATE)], (list, tuple)) # Set up a param dict of the original values. old_ta2 = reply[(SBE37Channel.CTD, SBE37Parameter.TA2)] old_ptca1 = reply[(SBE37Channel.CTD, SBE37Parameter.PTCA1)] old_tcaldate = reply[(SBE37Channel.CTD, SBE37Parameter.TCALDATE)] orig_params = { (SBE37Channel.CTD, SBE37Parameter.TA2): old_ta2, (SBE37Channel.CTD, SBE37Parameter.PTCA1): old_ptca1, (SBE37Channel.CTD, SBE37Parameter.TCALDATE): old_tcaldate } # Set up a param dict of new values. new_ta2 = old_ta2*2 new_ptcal1 = old_ptca1*2 new_tcaldate = list(old_tcaldate) new_tcaldate[2] = new_tcaldate[2] + 1 new_tcaldate = tuple(new_tcaldate) new_params = { (SBE37Channel.CTD, SBE37Parameter.TA2): new_ta2, (SBE37Channel.CTD, SBE37Parameter.PTCA1): new_ptcal1, (SBE37Channel.CTD, SBE37Parameter.TCALDATE): new_tcaldate } # Set the params to their new values. reply = driver_client.cmd_dvr('set', new_params) time.sleep(2) # Check overall success and success of the individual paramters. self.assertIsInstance(reply, dict) mi_logger.debug('set result: %s', str(reply)) # Get the same paramters back from the driver. get_params = [ (SBE37Channel.CTD, SBE37Parameter.TA2), (SBE37Channel.CTD, SBE37Parameter.PTCA1), (SBE37Channel.CTD, SBE37Parameter.TCALDATE) ] reply = driver_client.cmd_dvr('get', get_params) time.sleep(2) # Check success, and check that the parameters were set to the # new values. self.assertIsInstance(reply, dict) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.TA2)], float) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.PTCA1)], float) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.TCALDATE)], (list, tuple)) self.assertAlmostEqual(reply[(SBE37Channel.CTD, SBE37Parameter.TA2)], new_ta2, delta=abs(0.01*new_ta2)) self.assertAlmostEqual(reply[(SBE37Channel.CTD, SBE37Parameter.PTCA1)], new_ptcal1, delta=abs(0.01*new_ptcal1)) self.assertEqual(reply[(SBE37Channel.CTD, SBE37Parameter.TCALDATE)], new_tcaldate) # Set the paramters back to their original values. reply = driver_client.cmd_dvr('set', orig_params) self.assertIsInstance(reply, dict) mi_logger.debug('set result: %s', str(reply)) # Get the parameters back from the driver. reply = driver_client.cmd_dvr('get', get_params) # Check overall and individual sucess, and that paramters were # returned to their original values. self.assertIsInstance(reply, dict) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.TA2)], float) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.PTCA1)], float) self.assertIsInstance(reply[(SBE37Channel.CTD, SBE37Parameter.TCALDATE)], (list, tuple)) self.assertAlmostEqual(reply[(SBE37Channel.CTD, SBE37Parameter.TA2)], old_ta2, delta=abs(0.01*old_ta2)) self.assertAlmostEqual(reply[(SBE37Channel.CTD, SBE37Parameter.PTCA1)], old_ptca1, delta=abs(0.01*old_ptca1)) self.assertEqual(reply[(SBE37Channel.CTD, SBE37Parameter.TCALDATE)], old_tcaldate) # Disconnect driver from the device and transition to disconnected. reply = driver_client.cmd_dvr('disconnect', [SBE37Channel.CTD]) time.sleep(2) # Deconfigure the driver and transition to unconfigured. reply = driver_client.cmd_dvr('initialize', [SBE37Channel.CTD]) time.sleep(2) # End driver process and client messaging. driver_client.done() driver_process.wait()
class BarsDriverTest(PyonBarsTestCase): """ Tests involving ZMQ driver process and ZMQ client. """ def setUp(self): super(BarsDriverTest, self).setUp() # Zmq parameters used by driver process and client. self.server_addr = 'localhost' self.cmd_port = 5556 self.evt_port = 5557 # Driver module parameters. self.dvr_mod = 'ion.services.mi.drivers.uw_bars.driver' self.dvr_cls = 'BarsInstrumentDriver' self._driver_process = ZmqDriverProcess.launch_process(self.cmd_port, self.evt_port, self.dvr_mod, self.dvr_cls) self._driver_client = ZmqDriverClient(self.server_addr, self.cmd_port, self.evt_port) self._driver_client.start_messaging() time.sleep(1) self.addCleanup(self._clean_up) def _clean_up(self): if self._driver_process: try: self._driver_client.done() self._driver_process.wait() finally: self._driver_process = None def tearDown(self): super(BarsDriverTest, self).tearDown() self._clean_up() def _initialize(self): driver_client = self._driver_client reply = driver_client.cmd_dvr('initialize', [BarsChannel.INSTRUMENT]) print("** initialize reply=%s" % str(reply)) reply = driver_client.cmd_dvr('get_current_state') print("** get_current_state reply=%s" % str(reply)) self.assertEqual(DriverState.UNCONFIGURED, reply) time.sleep(1) def _connect(self): driver_client = self._driver_client reply = driver_client.cmd_dvr('get_current_state') print("** get_current_state reply=%s" % str(reply)) self.assertEqual(DriverState.UNCONFIGURED, reply) self._initialize() configs = {BarsChannel.INSTRUMENT: self.config} reply = driver_client.cmd_dvr('configure', configs) print("** configure reply=%s" % str(reply)) reply = driver_client.cmd_dvr('get_current_state') print("** get_current_state reply=%s" % str(reply)) reply = driver_client.cmd_dvr('connect', [BarsChannel.INSTRUMENT]) print("** connect reply=%s" % str(reply)) time.sleep(1) reply = driver_client.cmd_dvr('get_current_state') print("** get_current_state reply=%s" % str(reply)) self.assertEqual(DriverState.AUTOSAMPLE, reply) time.sleep(1) reply = driver_client.cmd_dvr('get_status', [BarsChannel.INSTRUMENT]) print("** get_status reply=%s" % str(reply)) self.assertEqual(DriverState.AUTOSAMPLE, reply) time.sleep(1) def _disconnect(self): driver_client = self._driver_client reply = driver_client.cmd_dvr('disconnect', [BarsChannel.INSTRUMENT]) print("** disconnect reply=%s" % str(reply)) reply = driver_client.cmd_dvr('get_current_state') print("** get_current_state reply=%s" % str(reply)) self.assertEqual(DriverState.DISCONNECTED, reply) time.sleep(1) self._initialize() def test_connect_disconnect(self): """BARS connect and disconnect""" self._connect() self._disconnect() def test_get(self): """BARS get""" self._connect() driver_client = self._driver_client # get a parameter cp = (BarsChannel.INSTRUMENT, BarsParameter.TIME_BETWEEN_BURSTS) get_params = [cp] reply = driver_client.cmd_dvr('get', get_params) print "get reply = %s" % str(reply) seconds = reply.get(cp) assert isinstance(seconds, int) self._disconnect()