def stopCameras(self): self.active_cameras = 0 # Stop master cameras first. for camera in self.camera_functionalities: if camera.isCamera() and camera.isMaster(): self.active_cameras += 1 self.sendMessage( halMessage.HalMessage( m_type="stop camera", data={"camera": camera.getCameraName()}, finalizer=self.handleStopCamera)) # Force sync. self.sendMessage(halMessage.SyncMessage(self)) # Stop slave cameras last. for camera in self.camera_functionalities: if camera.isCamera() and not camera.isMaster(): self.active_cameras += 1 self.sendMessage( halMessage.HalMessage( m_type="stop camera", data={"camera": camera.getCameraName()}, finalizer=self.handleStopCamera))
def stopCameras(self): # Stop master cameras first. self.sendMessage(halMessage.HalMessage(m_type = "stop camera", data = {"master" : True})) # Force sync. self.sendMessage(halMessage.SyncMessage(self)) # Stop slave cameras last. self.sendMessage(halMessage.HalMessage(m_type = "stop camera", data = {"master" : False}, finalizer = self.handleStopCamera))
def startCameras(self): # Start slave camera(s) first. self.sendMessage(halMessage.HalMessage(m_type = "start camera", data = {"master" : False})) # Force sync. # # We need to make sure that the slave cameras have started before # starting the master cameras or we'll have a race condition. # self.sendMessage(halMessage.SyncMessage(self)) # Start master camera(s) last. self.sendMessage(halMessage.HalMessage(m_type = "start camera", data = {"master" : True}))
def startCameras(self): # Start slave cameras first. for camera in self.camera_functionalities: if camera.isCamera() and not camera.isMaster(): self.sendMessage( halMessage.HalMessage( m_type="start camera", data={"camera": camera.getCameraName()})) # Force sync. # # We need to make sure that the slave cameras have started before # starting the master cameras or we'll have a race condition. # self.sendMessage(halMessage.SyncMessage(self)) # Start master cameras last. for camera in self.camera_functionalities: if camera.isCamera() and camera.isMaster(): self.sendMessage( halMessage.HalMessage( m_type="start camera", data={"camera": camera.getCameraName()}))
def __init__(self, config=None, parameters_file_name=None, testing_mode=False, show_gui=True, **kwds): super().__init__(**kwds) self.modules = [] self.module_name = "core" self.qt_settings = QtCore.QSettings( "storm-control", "hal4000" + config.get("setup_name").lower()) self.queued_messages = deque() self.queued_messages_timer = QtCore.QTimer(self) self.running = True # This is solely for the benefit of unit tests. self.sent_messages = [] self.strict = config.get("strict", False) self.queued_messages_timer.setInterval(0) self.queued_messages_timer.timeout.connect(self.handleSendMessage) self.queued_messages_timer.setSingleShot(True) # Initialize messages. halMessage.initializeMessages() # Load all the modules. print("Loading modules") # # For HAL it is easier to just use a list of modules, but at initialization # we also send a dictionary with the module names as keys to all of the # modules # # In testing mode the testing.testing module may use the other modules to # spoof the message sources. # # During normal operation most inter-module communication is done using # messages. Modules may also request functionalities from other modules # that they can use to do specific tasks, such as daq output or displaying # the images from a camera. # all_modules = {} if testing_mode: all_modules["core"] = self else: all_modules["core"] = True # # Need to load HAL's main window first so that other GUI windows will # have the correct Qt parent. # module_names = sorted(config.get("modules").getAttrs()) module_names.insert(0, module_names.pop(module_names.index("hal"))) for module_name in module_names: print(" " + module_name) # Get module specific parameters. module_params = config.get("modules").get(module_name) # Add the 'root' parameters to this module parameters # so that they are visible to the module. for root_param in config.getAttrs(): if (root_param != "modules"): module_params.add(root_param, config.getp(root_param)) # Load the module. a_module = importlib.import_module( module_params.get("module_name")) a_class = getattr(a_module, module_params.get("class_name")) a_object = a_class(module_name=module_name, module_params=module_params, qt_settings=self.qt_settings) # If this is HAL's main window set the HalDialog qt_parent class # attribute so that any GUI QDialogs will have the correct Qt parent. if (module_name == "hal"): halDialog.HalDialog.qt_parent = a_object.view self.modules.append(a_object) if testing_mode: all_modules[module_name] = a_object else: all_modules[module_name] = True print("") # Connect signals. for module in self.modules: module.newMessage.connect(self.handleMessage) # Create messages. # # We do it this way with finalizers because otherwise all of these messages # would get queued first and the modules would not have a chance to insert # messages in between these messages. # # The actual sequence of sent messages is: # # 1. "configure1", tell modules to finish configuration. # The message includes a dictionary of the names of # all modules that were loaded. # # 2. "configure2", gives the modules a chance to 'react' # based on what happened during configure1. # # 3. "configure3", gives the modules a chance to 'react' # based on what happened during configure1. # # 4. "new parameters file", initial parameters (if any). # # 5. "start", tell the modules to start. # This is the point where any GUI modules that are # visible should call show(). # message_chain = [] # configure1. message_chain.append( halMessage.HalMessage(source=self, m_type="configure1", data={"all_modules": all_modules})) # configure2. message_chain.append( halMessage.HalMessage(source=self, m_type="configure2")) # configure3. message_chain.append( halMessage.HalMessage(source=self, m_type="configure3")) # update default parameters. if parameters_file_name is not None: message_chain.append( halMessage.HalMessage(source=self, m_type="new parameters file", data={ "parameters filename": parameters_file_name, "is_default": True })) # start. # # It is safe to stop blocking Qt's last window closed behavior after # this message as HAL's main window will be open. # # If we run HAL from another module, in testing for example, app might # be none. # if app is not None: message_chain.append( halMessage.HalMessage( source=self, m_type="start", data={"show_gui": show_gui}, sync=True, finalizer=lambda: app.setQuitOnLastWindowClosed(True))) else: message_chain.append( halMessage.HalMessage(source=self, m_type="start", data={"show_gui": show_gui}, sync=True)) message_chain.append(halMessage.SyncMessage(source=self)) self.handleMessage( halMessage.chainMessages(self.handleMessage, message_chain))
def handleMessageReceived(self, tcp_message): """ TCP message handling. """ if self.verbose: print(">TCP message received:") print(tcp_message) print("") if tcp_message.isType('Check Focus Lock'): # This is supposed to ensure that everything else, like stage moves is complete. self.controlMessage.emit(halMessage.SyncMessage()) action = TCPAction(tcp_message=tcp_message) self.controlAction.emit(action) elif tcp_message.isType('Find Sum'): # This is supposed to ensure that everything else, like stage moves is complete. self.controlMessage.emit(halMessage.SyncMessage()) action = TCPAction(tcp_message=tcp_message) self.controlAction.emit(action) elif tcp_message.isType("Set Directory"): print(">> Warning the 'Set Directory' message is deprecated.") directory = tcp_message.getData("directory") if not os.path.isdir(directory): tcp_message.setError(True, directory + " is an invalid directory") else: self.test_directory = directory if not tcp_message.isTest(): # # We don't respond immediately to the client as we want to make sure # that the HAL actually takes care of the directory change. Though # this should happen really fast and it is not clear this step is # necessary. # self.controlMessage.emit( halMessage.HalMessage(m_type="change directory", data={"directory": directory}, finalizer=lambda: self.server. sendMessage(tcp_message))) return self.server.sendMessage(tcp_message) elif tcp_message.isType("Set Parameters"): if tcp_message.isTest(): action = TCPActionGetParameters(tcp_message=tcp_message) else: action = TCPActionSetParameters(tcp_message=tcp_message) self.controlAction.emit(action) elif tcp_message.isType("Take Movie"): # Check that movie length is valid. if (tcp_message.getData("length") is None) or (tcp_message.getData("length") < 1): tcp_message.setError( True, str(message.getData("length")) + " is an invalid movie length.") self.server.sendMessage(tcp_message) return # Some messy logic here to check if we will over-write a existing films? For now, just # verify that the movie.xml file does not exist. if not tcp_message.getData("overwrite"): directory = tcp_message.getData("directory") if directory is None: directory = self.test_directory filename = os.path.join(directory, tcp_message.getData("name")) + ".xml" if os.path.exists(filename): tcp_message.setError( True, "The movie file '" + filename + "' already exists.") self.server.sendMessage(tcp_message) return # More messy logic here to return film size, time, etc.. if tcp_message.isTest(): # If the movie has parameters specified, we'll request them specially. if tcp_message.getData("parameters") is not None: action = TCPActionGetMovieStats(tcp_message=tcp_message) self.controlAction.emit(action) # Otherwise calculate based on the current parameters. else: calculateMovieStats(tcp_message, self.test_parameters) self.server.sendMessage(tcp_message) else: action = TCPActionTakeMovie(tcp_message=tcp_message) self.controlAction.emit(action) else: if tcp_message.isTest() or (not self.parallel_mode): action = TCPAction(tcp_message=tcp_message) self.controlAction.emit(action) else: msg = halMessage.HalMessage(m_type="tcp message", data={"tcp message": tcp_message}) self.controlMessage.emit(msg) self.server.sendMessage(tcp_message)