Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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()
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
    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()
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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")
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
    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()