def _connect(self, channel, node_idx, datasheet): """ return network, node raise HwError() if the device is not connected raise ValueError(): if the device doesn't seem the right one """ # Connect to the CANbus and the CANopen network. network = canopen.Network() bustype = 'socketcan' if channel != 'fake' else 'virtual' try: network.connect(bustype=bustype, channel=channel) network.check() except CanError: raise model.HwError("CAN network %s not found." % (channel, )) except OSError as ex: if ex.errno == 19: # No such device raise model.HwError("CAN network %s not found." % (channel, )) raise # Tell CANopen what we *expect* to find if channel == 'fake': node = FakeRemoteNode(node_idx, datasheet) else: node = canopen.RemoteNode(node_idx, datasheet) # Note: add_node() supports a "upload_eds" flag to read the object dict from # the device. However the current firmware doesn't support that. network.add_node(node) # Check the device is there, and also force the state to be updated try: if channel != "fake": node.nmt.wait_for_heartbeat(timeout=5) except NmtError: raise model.HwError( "Focus tracker not found on channel %s with ID %s" % (channel, node_idx)) logging.debug("Device is in state %s", node.nmt.state) # If the device is stopped, it won't answer any SDO if node.nmt.state not in ("OPERATIONAL", "PRE-OPERATIONAL"): node.nmt.state = "PRE-OPERATIONAL" logging.debug("Turning on the device to state %s", node.nmt.state) # Check that the device has the right Vendor ID and Product code, mostly # in case the node index corresponds to a different device, also on the network. vid = node.sdo["Identity object"]["Vendor-ID"].raw pcode = node.sdo["Identity object"]["Product code"].raw if vid != VENDOR_ID or pcode != PRODUCT_CODE: raise ValueError( "Device %d on channel %s doesn't seem to be a FocusTracker (vendor 0x%04x, product 0x%04x)" % (node_idx, channel, vid, pcode)) return network, node
def __init__(self, host, port=23): """ host (string): the IP address or host name of the master controller port (int): the (IP) port number """ self._host = host self._port = port if host == "fake": self.socket = PM8742Simulator() else: try: self.socket = socket.create_connection((host, port), timeout=5) except socket.error: raise model.HwError( "Failed to connect to '%s:%d', check the New Focus " "controller is connected to the network, turned " "on, and correctly configured." % (host, port)) self.socket.settimeout(1.0) # s # it always sends '\xff\xfd\x03\xff\xfb\x01' on a new connection # => discard it try: data = self.socket.recv(100) except socket.timeout: logging.debug("Didn't receive any welcome message") # to acquire before sending anything on the socket self._net_access = threading.Lock()
def _state_error_run(self): ''' Creates or fixes an hardware error in the simcam if an file is present. Creating the file 'ERROR_STATE_FILE' (or by deleting this file) in the folder 'model.BASE_DIRECTORY' the state of the simcam is changed to and error (or fixed by putting the state back to the standard 'running'). ''' try: while self._is_running: time.sleep(0.3) # max 3 Hz # Check if an error file is present error_file_present = os.path.isfile( os.path.join(model.BASE_DIRECTORY, ERROR_STATE_FILE)) if error_file_present and not isinstance( self.state.value, model.HwError): self.state._set_value(model.HwError( "Camera disconnected due to forced testing error."), force_write=True) elif not error_file_present and isinstance( self.state.value, model.HwError): self.state._set_value(model.ST_RUNNING, force_write=True) except Exception as e: logging.warning( "In changing states in SimCam the error '%s' occurred", e)
def __init__(self, name, role, host, port=5041, daemon=None, **kwargs): """ host: (string) the TCP/IP hostname of the server port: (int) the TCP/IP port of the server. Raises: ValueError if no scanner child is present """ super(Cryolab, self).__init__(name, role, daemon=daemon, **kwargs) self._host = host self._port = port self._is_connected = False try: logging.debug("Connecting to %s:%d", self._host, self._port) self._socket = socket.create_connection((self._host, self._port)) self._socket.settimeout(2.0) except socket.error: raise model.HwError( "Failed to connect to '%s:%d', check that the Kryoz Cooler " "Server is operating, and connected to the network, turned " "on, and correctly configured." % (host, port)) # to acquire before sending anything on the socket self._net_access = threading.Lock()
def __init__(self, host, port=DEFAULT_PORT): """ host (string): the IP address or host name of the master controller port (int): the (IP) port number """ self._host = host self._port = port self._is_connected = False if self._host == "fake": self.simulator = FakeDG1000Z() self._host = "localhost" else: self.simulator = None try: logging.debug("Connecting to %s:%d", self._host, self._port) self.socket = socket.create_connection((self._host, self._port), timeout=1) self._is_connected = True except socket.error: raise model.HwError( "Failed to connect to '%s:%d', check that the Rigol " "Clock Generator is connected, turned on, " "and correctly configured." % (host, port)) # to acquire before sending anything on the socket self._net_access = threading.Lock()
def _try_recover(self): self.state._set_value( model.HwError("Connection lost, reconnecting..."), force_write=True) # Retry to connect to the device, infinitely while True: if self.network: try: self.network.disconnect() except Exception: logging.exception("Failed closing the previous network") self.network = None self.node = None try: logging.debug("Searching for the device %d on bus %s", self._node_idx, self._channel) self.network, self.node = self._connect( self._channel, self._node_idx, self._datasheet) self._position_sdo = self.node.sdo[POS_SDO][1] self._configure_device() except model.HwError as ex: logging.info("%s", ex) except Exception: logging.exception( "Unexpected error while trying to recover device") raise else: # We found it back! break # it now should be accessible again self.state._set_value(model.ST_RUNNING, force_write=True) logging.info("Recovered device on bus %s", self._channel)
def _open_device(self, sn): """ return IdentityType, AvsHandle: info on the device, and opaque handle """ # Check all USB devices self.Init(0) # USB only ndevices = self.UpdateUSBDevices() if ndevices == 0: raise model.HwError("Device not found, check it is powered on and connected") dev_ids = self.GetList(ndevices) for dev_id in dev_ids: if sn is None or dev_id.SerialNumber.decode("ascii") == sn: if dev_id.Status not in (USB_AVAILABLE, ETH_AVAILABLE): raise model.HwError("Device already in use. Close other applications") dev_hdl = self.Activate(dev_id) return dev_id, dev_hdl raise model.HwError("Device not found, check it is powered on and connected")
def _checkForError(self): ''' Checks for an error. Raises an exception if an error occurred. Returns None raise: HwError: if the device reports an error ''' err_code, err_msg = self.QueryErrorState() if err_code is not None: err = "Error code %d from %s: %s" % (err_code, self.name, err_msg) logging.error(err) raise model.HwError(err)
def _reconnect(self): """ Attempt to reconnect. It will block until this happens. On return, the hardware should be ready to use as before. """ num_it = 5 self.state._set_value( model.HwError("Beam deflection controller disconnected"), force_write=True) logging.warning("Failed to write registers, trying to reconnect...") for i in range(num_it): try: self._serial.close() self._serial = None self._port = self._findDevice(self._portpattern, self._serialnum) self._serial = self._openSerialPort(self._port) logging.info("Recovered device.") break except IOError: continue else: raise IOError("Failed to reconnect to beam deflection controller.") self.state._set_value(model.ST_RUNNING, force_write=True)
def __init__(self, name, role, host, children=None, port=DEFAULT_PORT, daemon=None, **kwargs): """ children (dict str -> dict): internal role -> kwargs. The internal roles can be "scanner" host: (string) the TCP/IP hostname of the server port: (int) the TCP/IP port of the server. Raises: ValueError if no scanner child is present """ super(Controller, self).__init__(name, role, daemon=daemon, **kwargs) if not children: raise ValueError("Symphotime detector requires a scanner child. ") self._host = host self._port = port self._is_connected = False try: logging.debug("Connecting to %s:%d", self._host, self._port) self._socket = socket.create_connection((self._host, self._port)) self._socket.settimeout(2.0) except socket.error: raise model.HwError( "Failed to connect to '%s:%d', check that the Symphotime " "Server is connected to the network, turned " "on, and correctly configured." % (host, port)) # to acquire before sending anything on the socket self._net_access = threading.Lock() # Data depth is 0, as we don't get the data self._shape = (0, ) # try get parameters from metadata self._metadata[model.MD_PIXEL_SIZE] = (10e-6, 10e-6) self.measurement_type = PQ_MEASTYPE_IMAGESCAN # Children try: ckwargs = children["scanner"] except KeyError: raise ValueError("No 'scanner' child configuration provided") self.scanner = Scanner(parent=self, daemon=daemon, **ckwargs) self.children.value.add(self.scanner) # Check for an optional "detector-live" child try: ckwargs = children["detector-live"] self.detector_live = DetectorLive(parent=self, daemon=daemon, **ckwargs) self.children.value.add(self.detector_live) except KeyError: logging.debug("No 'detector-live' child configuration provided") self.detector_live = None # Measurement parameters self.data = BasicDataFlow(self.StartMeasurement, self.StopMeasurement, self._checkImScan) self._acq_md = { } # Metadata as it was configured at measurement starts self._acq_md_live = {} # Metadata for live detector # Create a thread to listen to messages from SymPhoTime self._shutdown_flag = False self._user_break = False self._measurement_stopped = threading.Event() self._measurement_stopped.set() self._listener_thread = threading.Thread(target=self._listen) self._listener_thread.daemon = True self._listener_thread.start()