コード例 #1
0
ファイル: SocketServer.py プロジェクト: spewil/RTGraph
 def open(self, host='', port=45454, timeout=0.01):
     """
     Opens a socket connection to specified host and port
     :param host: Host address to connect to.
     :type host: str.
     :param port: Port number to connect to.
     :type port: int.
     :param timeout: Sets timeout for socket interactions.
     :type timeout: float.
     :return: True if the connection was open.
     :rtype: bool.
     """
     try:
         # self._socket_server.timeout = timeout
         port = int(port)
         self._socket_server.bind((host, port))
         Log.i(TAG, "Socket open {}:{}".format(host, port))
         print("listening on {}:{}".format(
             self._socket_server.getsockname()[0],
             self._socket_server.getsockname()[1]))
         self._socket_server.listen(1)
         self._conn, address = self._socket_server.accept()
         self._conn.setblocking(0)  # non-blocking
         print("accepted from {}".format(address))
         return True
     except socket.timeout:
         Log.w(TAG, "Connection timeout")
     return False
コード例 #2
0
    def start(self):
        """
        Starts all processes, based on configuration given in constructor.
        :return:
        """
        self.reset_buffers(self._samples)
        if self._export:
            self._csv_process = CSVProcess(path=self._path)
            self._parser_process = ParserProcess(
                self._queue, store_reference=self._csv_process)
        else:
            self._parser_process = ParserProcess(self._queue)

        if self._source == SourceType.serial:
            self._acquisition_process = SerialProcess(self._parser_process)
        elif self._source == SourceType.simulator:
            self._acquisition_process = SimulatorProcess(self._parser_process)
        if self._acquisition_process.open(port=self._port, speed=self._speed):
            self._parser_process.start()
            if self._export:
                self._csv_process.start()
            self._acquisition_process.start()
            return True
        else:
            Log.i(TAG, "Port is not available")
            return False
コード例 #3
0
 def stop(self):
     """
     Signals the process to stop acquiring data.
     :return:
     """
     Log.i(TAG, "Process finishing...")
     self._exit.set()
コード例 #4
0
    def __init__(self,
                 data_queue,
                 store_reference=None,
                 split=Constants.csv_delimiter,
                 consumer_timeout=Constants.parser_timeout_ms):
        """

        :param data_queue: Reference to Queue where processed data will be put.
        :type data_queue: multiprocessing Queue.
        :param store_reference: Reference to CSVProcess instance, if needed.
        :type store_reference: CSVProcess (multiprocessing.Process)
        :param split: Delimiter in incoming data.
        :type split: str.
        :param consumer_timeout: Time to wait after emptying the internal buffer before next parsing.
        :type consumer_timeout: float.
        """
        mp.Process.__init__(self)
        self._exit = mp.Event()
        self._in_queue = mp.Queue()
        self._out_queue = data_queue  # Queue from the worker process
        self._consumer_timeout = consumer_timeout
        self._split = split
        self._store_reference = store_reference
        self._leftover = ''
        Log.d(TAG, "Process ready")
コード例 #5
0
ファイル: SocketServer.py プロジェクト: spewil/RTGraph
 def stop(self):
     """
     Signals the process to stop acquiring data.
     :return:
     """
     Log.i(TAG, "Server closing")
     self._conn.close()
     self._socket_server.close()
     self._exit.set()
コード例 #6
0
 def _update_sample_size(self):
     """
     Updates the sample size of the plot.
     This function is connected to the valueChanged signal of the sample Spin Box.
     :return:
     """
     if self.worker is not None:
         Log.i(TAG, "Changing sample size")
         self.worker.reset_buffers(self.ui.sBox_Samples.value())
コード例 #7
0
 def closeEvent(self, evnt):
     """
     Overrides the QTCloseEvent.
     This function is connected to the clicked signal of the close button of the window.
     :param evnt: QT evnt.
     :return:
     """
     if self.worker.is_running():
         Log.i(TAG, "Window closed without stopping capture, stopping it")
         self.stop()
コード例 #8
0
 def stop(self):
     """
     Stops the acquisition of the selected serial port.
     This function is connected to the clicked signal of the Stop button.
     :return:
     """
     Log.i(TAG, "Clicked stop")
     self._timer_plot.stop()
     self._enable_ui(True)
     self.worker.stop()
コード例 #9
0
 def set_user_log_level(self):
     """
     Sets the user specified log level.
     :return:
     """
     if self._parser is not None:
         self._parse_log_level()
     else:
         Log.w(TAG, "Parser was not created !")
         return None
コード例 #10
0
ファイル: SocketClient.py プロジェクト: spewil/RTGraph
 def __init__(self, parser_process):
     """
     Initialises values for process.
     :param parser_process: Reference to a ParserProcess instance.
     :type parser_process: ParserProcess
     """
     multiprocessing.Process.__init__(self)
     self._exit = multiprocessing.Event()
     self._parser = parser_process
     self._socket_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     Log.i(TAG, "Process Ready")
コード例 #11
0
 def __init__(self, parser_process):
     """
     Initialises values for process.
     :param parser_process: Reference to a ParserProcess instance.
     :type parser_process: ParserProcess.
     """
     multiprocessing.Process.__init__(self)
     self._exit = multiprocessing.Event()
     self._parser = parser_process
     self._serial = serial.Serial()
     Log.i(TAG, "Process ready")
コード例 #12
0
 def run(self):
     """
     Process will monitor the internal buffer to parse raw data and distribute to graph and storage, if needed.
     The process will loop again after timeout if more data is available.
     :return:
     """
     Log.d(TAG, "Process starting...")
     while not self._exit.is_set():
         self._consume_queue()
         sleep(self._consumer_timeout)
     # last check on the queue to completely remove data.
     self._consume_queue()
     Log.d(TAG, "Process finished")
コード例 #13
0
ファイル: worker.py プロジェクト: spewil/RTGraph
 def consume_queue(self):
     """
     Empties the internal queue, updating data to consumers.
     :return:
     """
     # i = 0
     while True:
         try:
             # i += 1
             self._store_data(self._queue.get(block=False))
         except queue.Empty:
             # print("parsed queue: ", i)
             return
     Log.d(TAG, f"queue len: {i}")
コード例 #14
0
 def reset_buffers(self, samples):
     """
     Setup/clear the internal buffers.
     :param samples: Number of samples for the buffers.
     :type samples: int.
     :return:
     """
     self._data_buffers = []
     for tmp in Constants.plot_colors:
         self._data_buffers.append(RingBuffer(samples))
     self._time_buffer = RingBuffer(samples)
     while not self._queue.empty():
         self._queue.get()
     Log.i(TAG, "Buffers cleared")
コード例 #15
0
 def run(self):
     """
     Simulates raw data incoming as CSV.
     :return:
     """
     Log.i(TAG, "Process starting...")
     timestamp = time()
     coef = 2 * np.pi
     while not self._exit.is_set():
         stamp = time() - timestamp
         self._parser.add([stamp, str(("{},{}\r\n".format(np.sin(coef * stamp), np.cos(coef * stamp))))
                          .encode(Constants.app_encoding)])
         sleep(self._period)
     Log.i(TAG, "Process finished")
コード例 #16
0
ファイル: SocketServer.py プロジェクト: spewil/RTGraph
 def __init__(self, parser_process):
     """
     Initialises values for process.
     :param parser_process: Reference to a ParserProcess instance.
     :type parser_process: ParserProcess
     """
     multiprocessing.Process.__init__(self)
     self._exit = multiprocessing.Event()
     self._parser = parser_process
     self._socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     self._socket_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
                                    1)
     self._conn = None
     Log.i(TAG, "Process Ready")
コード例 #17
0
 def open(self, port=None, speed=Constants.simulator_default_speed, timeout=0.5):
     """
     Opens a specified serial port.
     :param port: Not used.
     :type port: str.
     :param speed: Period of the generated signal.
     :type speed: float.
     :param timeout: Not used.
     :type timeout: float.
     :return: True if the port is available.
     :rtype: bool.
     """
     self._period = float(speed)
     Log.i(TAG, "Using sample rate at {}".format(self._period))
     return True
コード例 #18
0
    def run(self):
        if Architecture.is_python_version(MinimalPython.major,
                                          minor=MinimalPython.minor):
            Log.i(TAG, "Starting RTGraph")
            win = mainWindow.MainWindow(samples=self._args.get_user_samples())
            win.setWindowTitle("{} - {}".format(Constants.app_title,
                                                Constants.app_version))
            win.show()
            self._app.exec()

            Log.i(TAG, "Finishing RTGraph\n")
            win.close()
        else:
            self._fail()
        self.close()
コード例 #19
0
 def get_source_speeds(source):
     """
     Gets the available speeds for specified source.
     :param source: Source to get available speeds.
     :type source: SourceType.
     :return: List of available speeds.
     :rtype: str list.
     """
     if source == SourceType.serial:
         return SerialProcess.get_speeds()
     elif source == SourceType.simulator:
         return SimulatorProcess.get_speeds()
     else:
         Log.w(TAG, "Unknown source selected")
         return None
コード例 #20
0
 def get_ports():
     """
     Gets a list of the available serial ports.
     :return: List of available serial ports.
     :rtype: str list.
     """
     if Architecture.get_os() is OSType.macosx:
         import glob
         return glob.glob("/dev/tty.*")
     else:
         found_ports = []
         for port in list(list_ports.comports()):
             Log.d(TAG, "found device {}".format(port))
             found_ports.append(port.device)
         return found_ports
コード例 #21
0
ファイル: worker.py プロジェクト: spewil/RTGraph
 def get_source_ports(source):
     """
     Gets the available ports for specified source.
     :param source: Source to get available ports.
     :type source: SourceType.
     :return: List of available ports.
     :rtype: str list.
     """
     if source == SourceType.serial:
         return SerialProcess.get_ports()
     elif source == SourceType.simulator:
         return SimulatorProcess.get_ports()
     elif source == SourceType.SocketServer:
         return SocketProcess.get_default_host()
     else:
         Log.w(TAG, "Unknown source selected")
         return None
コード例 #22
0
 def run(self):
     """
     Process will monitor the internal buffer to write data to the export file,
     and the process will loop again after timeout if more data is available.
     :return:
     """
     Log.i(TAG, "Process starting...")
     self._csv = csv.writer(self._file,
                            delimiter=Constants.csv_delimiter,
                            quoting=csv.QUOTE_MINIMAL)
     while not self._exit.is_set():
         self._consume_queue()
         sleep(self._timeout)
     # last check on the queue to completely remove data.
     self._consume_queue()
     Log.i(TAG, "Process finished")
     self._file.close()
コード例 #23
0
    def _source_changed(self):
        """
        Updates the source and depending boxes on change.
        This function is connected to the indexValueChanged signal of the Source ComboBox.
        :return:
        """
        Log.i(TAG, "Scanning source {}".format(self._get_source().name))
        # clear boxes before adding new
        self.ui.cBox_Port.clear()
        self.ui.cBox_Speed.clear()

        source = self._get_source()
        ports = self.worker.get_source_ports(source)
        speeds = self.worker.get_source_speeds(source)

        self.ui.cBox_Port.addItems(ports)
        self.ui.cBox_Speed.addItems(speeds)
        self.ui.cBox_Speed.setCurrentIndex(len(speeds) - 1)
コード例 #24
0
 def _create_file(filename, path=None, extension=Constants.csv_extension):
     """
     Creates the file to export the data.
     :param filename: Name of the file where data will be exported.
     :type filename: str.
     :param path: Path where data file will be saved.
     :type path: str.
     :param extension: Extension to give to the export file.
     :type extension: str.
     :return: Reference to the export file.
     """
     FileManager.create_dir(path)
     full_path = FileManager.create_file(filename,
                                         extension=extension,
                                         path=path)
     if not FileManager.file_exists(full_path):
         Log.i(TAG, "Storing in {}".format(full_path))
         return open(full_path, "a", newline='')
     return None
コード例 #25
0
 def start(self):
     """
     Starts the acquisition of the selected serial port.
     This function is connected to the clicked signal of the Start button.
     :return:
     """
     Log.i(TAG, "Clicked start")
     self.worker = Worker(port=self.ui.cBox_Port.currentText(),
                          speed=float(self.ui.cBox_Speed.currentText()),
                          samples=self.ui.sBox_Samples.value(),
                          source=self._get_source(),
                          export_enabled=self.ui.chBox_export.isChecked())
     if self.worker.start():
         self._timer_plot.start(Constants.plot_update_ms)
         self._enable_ui(False)
     else:
         Log.i(TAG, "Port is not available")
         PopUp.warning(self, Constants.app_title, "Selected port \"{}\" is not available"
                       .format(self.ui.cBox_Port.currentText()))
コード例 #26
0
ファイル: SocketClient.py プロジェクト: spewil/RTGraph
 def open(self, port='', speed=45454, timeout=0.01):
     """
     Opens a socket connection to specified host and port
     :param port: Host address to connect to.
     :type port: str.
     :param speed: Port number to connect to.
     :type speed: int.
     :param timeout: Sets timeout for socket interactions.
     :type timeout: float.
     :return: True if the connection was open.
     :rtype: bool.
     """
     try:
         #self._socket_client.timeout = timeout
         speed = int(speed)
         self._socket_client.connect((port, speed))
         Log.i(TAG, "Socket open {}:{}".format(port, speed))
         return True
     except socket.timeout:
         Log.w(TAG, "Connection timeout")
     return False
コード例 #27
0
 def _parse_csv(self, time, line):
     """
     Parses incoming data and distributes to external processes.
     :param time: Timestamp.
     :type time: float.
     :param line: Raw data coming from acquisition process.
     :type line: basestring.
     :return:
     """
     if len(line) > 0:
         try:
             if type(line) == bytes:
                 values = line.decode("UTF-8").split(self._split)
             elif type(line) == str:
                 values = line.split(self._split)
             else:
                 raise TypeError
             values = [float(v) for v in values]
             Log.d(TAG, values)
             self._out_queue.put((time, values))
             if self._store_reference is not None:
                 self._store_reference.add(time, values)
         except ValueError:
             Log.w(TAG, "Can't convert to float. Raw: {}".format(line.strip()))
         except AttributeError:
             Log.w(TAG, "Attribute error on type ({}). Raw: {}".format(type(line), line.strip()))
コード例 #28
0
    def __init__(self, filename=None, path=None, timeout=0.5):
        """
        Sets up the file to export the data as CSV.
        If filename is not specified, a default name based on time will be used.
        :param filename: Name of the file where data will be exported.
        :type filename: str.
        :param path: Path where data file will be saved.
        :type path: str.
        :param timeout: Time to wait after emptying the internal buffer before next write.
        :type timeout: float.
        """
        multiprocessing.Process.__init__(self)
        self._exit = multiprocessing.Event()
        self._store_queue = multiprocessing.Queue()
        self._csv = None
        self._file = None
        self._timeout = timeout

        if filename is None:
            filename = strftime(Constants.csv_default_filename, gmtime())
        self._file = self._create_file(filename, path=path)
        Log.i(TAG, "Process ready")
コード例 #29
0
 def run(self):
     """
     Reads the serial port expecting CSV until a stop call is made.
     The expected format is comma (",") separated values, and a new line (CRLF or LF) as a new row.
     While running, it will parse CSV data convert each value to float and added to a queue.
     If incoming data from serial port can't be converted to float, that data will be discarded.
     :return:
     """
     Log.i(TAG, "Process starting...")
     if self._is_port_available(self._serial.port):
         if not self._serial.isOpen():
             self._serial.open()
             Log.i(TAG, "Port opened")
             timestamp = time()
             while not self._exit.is_set():
                 self._parser.add(
                     [time() - timestamp,
                      self._serial.readline()])
             Log.i(TAG, "Process finished")
             self._serial.close()
         else:
             Log.w(TAG, "Port is not opened")
     else:
         Log.w(TAG, "Port is not available")
コード例 #30
0
ファイル: SocketClient.py プロジェクト: spewil/RTGraph
    def run(self):
        """
        Reads the socket until a stop call is made.
        :return:
        """
        Log.i(TAG, "Process starting...")
        timestamp = time()

        while not self._exit.is_set():
            stamp = time() - timestamp
            try:
                data = self._socket_client.recv(
                    Constants.SocketClient.buffer_recv_size).decode()
                if len(data) > 0:
                    self._parser.add([stamp, data])
            except socket.timeout:
                Log.w(TAG, "read timeout")
        Log.i(TAG, "Process finished")