Exemple #1
0
class ExportViewTarget(object):
  def __init__(self, project, filename, parent):
    self.mutex = QMutex()
    self.project = project
    self.filename = filename
    self.parent = parent
    self.surface = QOffscreenSurface()
    self.surface.setFormat(QSurfaceFormat.defaultFormat())
    self.surface.create()

  def destroy(self):
    self.surface.destroy()

  def render(self, view, uniforms=dict()):
    self.project.setCameraMode('view')
    self.project.setCameraViewRef(view)
    self.project.setCameraAtOrigin()
    self.project.render(self.ctx.functions(), view.info.width, view.info.height, uniforms)
    depth = self.project.renderer.depthmap(self.ctx.functions(), view.info.width, view.info.height)
    return depth

  def __enter__(self):
    self.mutex.lock()
    self.ctx = QOpenGLContext()
    self.ctx.setShareContext(self.parent)
    self.ctx.create()
    if not self.ctx.makeCurrent(self.surface):
      raise Exception("cannot make context current")
    self.project.renderer.lock()

  def __exit__(self, type, value, tb):
    self.project.renderer.unlock()
    self.ctx.doneCurrent()
    del self.ctx
    self.mutex.unlock()
    def __init__(self,
                 cfg,
                 tracker=None,
                 server_addr=None,
                 events_server_addr=None,
                 sharing_server_addr=None,
                 upload_server_addr=None,
                 parent=None):

        logger.debug("Initializing API server client...")
        QObject.__init__(self, parent=parent)

        self._sessions = dict()

        self.server_addr = server_addr if server_addr \
            else API_URI.format(cfg.host)
        self.events_server_addr = events_server_addr if events_server_addr \
            else API_EVENTS_URI.format(cfg.host)
        self.sharing_server_addr = sharing_server_addr if sharing_server_addr \
            else API_SHARING_URI.format(cfg.host)
        self.upload_server_addr = upload_server_addr if upload_server_addr \
            else API_UPLOAD_URI.format(cfg.host)
        self._tracker = tracker
        self.ip_addr = None
        self.cfg = cfg
        self.node_sign = None
        self._ip_lock = QMutex(parent=self)
        self._os_name, self._is_server = get_os_name_and_is_server()
Exemple #3
0
class Barrier:
    """
    Implement a barrier, such that threads block until other monitored threads reach a specific location.
    The barrier can be used multiple times (it is reinitialized after the threads passed).

    See https://stackoverflow.com/questions/9637374/qt-synchronization-barrier/9639624#9639624
    """
    def __init__(self, count):
        self.count = count
        self.origCount = count
        self.mutex = QMutex()
        self.condition = QWaitCondition()

    def wait(self):
        """
        Wait until all monitored threads called wait.
        :return: None
        """
        self.mutex.lock()
        self.count -= 1
        if self.count > 0:
            self.condition.wait(self.mutex)
        else:
            self.count = self.origCount
            self.condition.wakeAll()
        self.mutex.unlock()
Exemple #4
0
 def __init__(self):
     self.ser = serial.Serial()
     self.escape = 0
     self.connected = 0
     self.state = WAITING_DLE
     self.crc_data = []
     self.data = []
     self.mutex = QMutex()
Exemple #5
0
    def __init__(self, parent=None):
        super(FortuneThread, self).__init__(parent)

        self.quit = False
        self.hostName = ''
        self.cond = QWaitCondition()
        self.mutex = QMutex()
        self.port = 0
Exemple #6
0
 def __init__(self, project, filename, parent):
   self.mutex = QMutex()
   self.project = project
   self.filename = filename
   self.parent = parent
   self.surface = QOffscreenSurface()
   self.surface.setFormat(QSurfaceFormat.defaultFormat())
   self.surface.create()
class TestThread(QThread):
    startRecording = Signal()

    def __init__(self, config, aruco_tester_widget, acs_control, parent=None):
        QThread.__init__(self, parent)
        self.config = config
        self.aruco_tester_widget = aruco_tester_widget
        self.image_miner = aruco_tester_widget.image_miner
        self.acs_control = acs_control

        self.startRecording.connect(self.aruco_tester_widget.onRecordClicked)

        self.recordingStopped = QWaitCondition()
        self.mutex = QMutex()

    @Slot()
    def wake(self):
        self.recordingStopped.wakeAll()
        pass

    def run(self):
        print('starting...')
        base_dir = os.path.dirname(os.path.realpath(__file__))
        config = self.config['config']
        angles = self.config['angles']
        j = 0
            
        self.image_miner.set_video_capture_property('CAP_PROP_BRIGHTNESS', 50.5/100.)
        self.image_miner.set_video_capture_property('CAP_PROP_CONTRAST', 50.5/100.)
        self.image_miner.set_video_capture_property('CAP_PROP_SATURATION', 50.5/100.)

        prop = 'CAP_PROP_BRIGHTNESS'

        print(prop)
        start = config[prop]['start']
        end = config[prop]['end']
        step = config[prop]['step']
        for i in range(start, end+1, step):
            print(i)
            self.image_miner.set_video_capture_property(prop, i/100.)
            series_dir = os.path.join(base_dir, str(prop), str(i), str(self.aruco_tester_widget.use_board))
            j += 1
            
            for angle in angles:
                fileName = os.path.join(series_dir, str(angle))
                print(angle)
                self.acs_control.pa(angle)
                time.sleep(5)
                self.mutex.lock()
                self.startRecording.emit()
                print('wait for recording to stop')
                self.recordingStopped.wait(self.mutex)
                print('saving data to {}'.format(fileName))
                self.aruco_tester_widget.broadcaster.saveToFile(fileName)
                self.mutex.unlock()

            self.acs_control.pa(0)
            time.sleep(10)
Exemple #8
0
    def __init__(self):
        super(Operator, self).__init__()

        logging.debug('Operator::__init__() called')
        self.threadpool = QThreadPool.globalInstance()
        self.procHandleMutex = QMutex()

        self._startAll = OperatorStartAll(self)

        self.identGenMutex = QMutex()
        self.n_ident = 0
    def __init__(self, config, aruco_tester_widget, acs_control, parent=None):
        QThread.__init__(self, parent)
        self.config = config
        self.aruco_tester_widget = aruco_tester_widget
        self.image_miner = aruco_tester_widget.image_miner
        self.acs_control = acs_control

        self.startRecording.connect(self.aruco_tester_widget.onRecordClicked)

        self.recordingStopped = QWaitCondition()
        self.mutex = QMutex()
Exemple #10
0
    def __init__(self, thread_pool: QThreadPool):
        """
        Runs a runnable on a thread pool, canceling the previous runnable if it is still enqueued.

        Parameters
        ----------
        thread_pool
            The thread pool that will be used to run the runnable.
        """
        super().__init__()
        self._thread_pool = thread_pool
        self._current_runnable = None
        self._lock = QMutex()
    def __init__(self, func_id, parent=None):
        super().__init__(parent)
        self.func_id = func_id
        self.call_graph = nx.DiGraph()

        self.mutex = QMutex()
        self._abort = False
Exemple #12
0
 def __init__(self, config):  # pylint: disable=unused-argument
     super().__init__()
     self._deviceId = 0
     self._registeredDevices = {}
     self._mutex = QMutex()
     self._recordingActive = False
     self._appConn = None
Exemple #13
0
    def __init__(self, parent=None):
        super(RenderThread, self).__init__(parent)

        self.mutex = QMutex()
        self.condition = QWaitCondition()
        self.centerX = 0.0
        self.centerY = 0.0
        self.scaleFactor = 0.0
        self.resultSize = QSize()
        self.colormap = []

        self.restart = False
        self.abort = False

        for i in range(RenderThread.ColormapSize):
            self.colormap.append(self.rgbFromWaveLength(380.0 + (i * 400.0 / RenderThread.ColormapSize)))
    def __init__(self, parent=None):
        super(FortuneThread, self).__init__(parent)

        self.quit = False
        self.hostName = ''
        self.cond = QWaitCondition()
        self.mutex = QMutex()
        self.port = 0
Exemple #15
0
 def __init__(self):
     super(MainWindow, self).__init__()
     self.ui = Ui_MainWindow()
     self.ui.setupUi(self)
     self.signals = MainWindowSignals()
     self.save_data_dir = None
     self.current_measurement = 0
     self.max_measurements = 0
     self.collecting = False
     self.time_axis = None
     self.mutex = QMutex()
     self.comp_thread = QThread()
     self.exp_thread = QThread()
     self._connect_components()
     self._set_initial_widget_states()
     self._store_line_objects()
     self._set_plot_mouse_mode()
Exemple #16
0
    def __init__(self, multicast_addr, port, parent=None):
        super().__init__(parent)

        self.multicast_addr = multicast_addr
        self.port = port
        self.bind_addr = '0.0.0.0'
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.worker = _Worker(self.messageReceivedSignal, self.sock, self)
        self.mutex = QMutex()
Exemple #17
0
    def __init__(self):
        super().__init__()
        self.__activeCount: int = 0  # number of operations in progress
        centralWidget = MainWidget()
        self.setCentralWidget(centralWidget)
        self.notifier = None  # Set by main script
        # Initialise a thread pool
        self.threadPool = QThreadPool.globalInstance()
        logging.info('Multithreading with maximum {} threads'.format(
            self.threadPool.maxThreadCount()))
        self.setWindowTitle('dataMole')

        self.setUpMenus()
        self.__spinnerMutex = QMutex()

        centralWidget.frameInfoPanel.operationRequest.connect(
            self.executeOperation)
        centralWidget.workbenchView.selectedRowChanged[str, str].connect(
            self.changedSelectedFrame)
Exemple #18
0
 def __init__(self, mainWindow=None, name="", goalPosition=0, status=False):
     """
     Initialization
     :param mainWindow: The main window of the ui
     :param name: The name of the motor
     :param pos: The position of the motor
     :param status: the status of the motor
     """
     ## The main window of the ui
     self.__name = name
     ## The goal position of the motor
     self.__goalPosition = goalPosition
     ## The current position of the motor
     self.__currentPosition = 0
     ## The status of the motor
     self.__status = status
     ## The main window of the ui
     self.__window = mainWindow
     self.mu = QMutex()
Exemple #19
0
 def __init__(self, history_time_s=1.0):
     self.mutex = QMutex()
     self.history_time_ns = np.int64(history_time_s * 1e9)
     self.times = np.zeros((0, ), dtype=np.int64)
     self.gas = np.zeros((0, ), dtype=np.uint16)
     self.brake = np.zeros((0, ), dtype=np.uint16)
     self.clutch = np.zeros((0, ), dtype=np.uint16)
     self.sx = np.zeros((0, ), dtype=np.uint16)
     self.sy = np.zeros((0, ), dtype=np.uint16)
     self.calib = CalibData()
Exemple #20
0
class QIpScanner(QObject):
    networkIpReceived = Signal(str, str, str)

    def __init__(self, parent=None):
        super().__init__(parent)

        self.isScanning = False
        self.worker = _Worker(self.networkIpReceived, self)
        self.mutex = QMutex()

    @Slot(result=bool)
    def isRunning(self):
        return self.worker.isRunning()

    @Slot()
    def scan(self):
        self.mutex.lock()
        if not self.worker.isRunning():
            self.worker.start()
        self.mutex.unlock()
Exemple #21
0
    def __init__(self, parent=None):
        super(DetailViewer, self).__init__(parent)

        self.ui = detailViewer_ui.Ui_MainWindow()
        self.ui.setupUi(self)

        self.__deviceModel = DeviceModel(self)
        self.__folderModel = FolderModel(self)
        self.ui.deviceTreeView.setModel(self.__deviceModel)
        self.ui.folderTreeView.setModel(self.__folderModel)

        self.__deviceEventCatched = ServerEventCatcher(
            [sth.DevicesConfigurationEvent])
        self.__deviceEventCatched.event_arrived.connect(self.process_event)
        self.__folderEventCatched = ServerEventCatcher(
            [sth.FoldersConfigurationEvent])
        self.__folderEventCatched.event_arrived.connect(self.process_event)

        self.__setterMutex = QMutex()
        self.__server = None
 def __init__(self, name, parentPropColl, loadedFromConfig=None):
     PropertyCollection.__init__(self)
     assertMainThread()
     self._properties = {}
     self._accessed = False # if no access to properties has been made, we stick with configs from config file.
     self._loadedFromConfig = loadedFromConfig if loadedFromConfig is not None else {}
     self._propertyMutex = QMutex(QMutex.Recursive)
     if parentPropColl is not None:
         if not isinstance(parentPropColl, PropertyCollectionImpl):
             raise NexTInternalError("parentPropColl should always be a property collection instance but it isn't")
         parentPropColl.addChild(name, self)
Exemple #23
0
 def __init__(self,
              parent: QWidget = None,
              frame: Union[Frame, Shape] = Frame()):
     super().__init__(parent)
     if isinstance(frame, Frame):
         self.__frame: Frame = frame
         self.__shape: Shape = self.__frame.shape
     elif isinstance(frame, Shape):  # it's a Shape
         self.__frame: Frame = Frame()
         self.__shape: Shape = frame
     else:
         self.__frame: Frame = Frame()
         self.__shape: Shape = Shape()
     # Dictionary { attributeIndex: value }
     self._statistics: Dict[int, Dict[str, object]] = dict()
     self._histogram: Dict[int, Dict[Any, int]] = dict()
     # Dataframe name
     self.name: str = ''
     # Set of alive workers by identifier (attribute number, type, operation)
     self._runningWorkers: Set[Tuple] = set()
     self._dataAccessMutex = QMutex()
Exemple #24
0
class SingleRunnableManager(QObject):
    def __init__(self, thread_pool: QThreadPool):
        """
        Runs a runnable on a thread pool, canceling the previous runnable if it is still enqueued.

        Parameters
        ----------
        thread_pool
            The thread pool that will be used to run the runnable.
        """
        super().__init__()
        self._thread_pool = thread_pool
        self._current_runnable = None
        self._lock = QMutex()

    def remove_runnable(self) -> None:
        """
        Removes the current runnable without canceling its execution.
        """
        self._lock.lock()
        try:
            del self._current_runnable
            self._current_runnable = None
            gc.collect()
        finally:
            self._lock.unlock()

    def _cancel(self) -> None:
        if self._current_runnable is not None:
            self._thread_pool.cancel(self._current_runnable)
        del self._current_runnable
        self._current_runnable = None
        gc.collect()

    def start(self, runnable: QRunnable) -> None:
        """
        Cancel the current runnable (if any) and enqueue the runnable for execution on the thread pool.

        Parameters
        ----------
        runnable
            The runnable to run

        """
        self._lock.lock()
        try:
            self._cancel()
            self._thread_pool.start(runnable)
        finally:
            self._lock.unlock()
 def __init__(self, library, factoryFunction, propertyCollection, mockup=None):
     BaseFilterEnvironment.__init__(self, propertyCollection)
     # ports are accessed by multiple threads (from FilterMockup.createFilter)
     self._portMutex = QMutex(QMutex.Recursive)
     self._ports = []
     self._mockup = mockup
     self._state = FilterState.CONSTRUCTING
     if library is not None:
         plugin = PluginManager.singleton().create(library, factoryFunction, self)
         if plugin is not None:
             self.setPlugin(plugin)
             plugin.setObjectName(str(library) + "_" + str(factoryFunction))
         self._state = FilterState.CONSTRUCTED
Exemple #26
0
class USBWriteThread(QThread):
    mutex = QMutex()

    def __init__(self, device, tx_data):
        QThread.__init__(self)
        self.device = device
        self.tx_data = tx_data
        self.num_bytes_written = 0

    def run(self, *args, **kwargs):
        self.mutex.lock()
        self.num_bytes_written = self.device.write(self.tx_data)
        # print "write thread:", self.num_bytes_written, self.tx_data.encode('hex')
        self.mutex.unlock()
Exemple #27
0
def test_dark_current_compensated(empty_settings, preamble,
                                  raw_data_without_pump):
    """Ensure that dark current is subtracted from the raw signals.

    The dummy preamble is populated with signals around 1.0, so we subtract
    a dark current of 0.5 in order to be able to very clearl distinguish
    when the dark current has been subtracted.
    """
    settings = empty_settings
    settings.dark_curr_par = 0.5
    mutex = QMutex()
    worker = ComputationWorker(mutex, settings)
    worker.store_preamble(preamble)
    worker.compute_signals(raw_data_without_pump)
    assert worker.without_pump.par.mean() < 0.75
Exemple #28
0
    def __init__(self, parent=None):
        super(RenderThread, self).__init__(parent)

        self.mutex = QMutex()
        self.condition = QWaitCondition()
        self.centerX = 0.0
        self.centerY = 0.0
        self.scaleFactor = 0.0
        self.resultSize = QSize()
        self.colormap = []

        self.restart = False
        self.abort = False

        for i in range(RenderThread.ColormapSize):
            self.colormap.append(self.rgbFromWaveLength(380.0 + (i * 400.0 / RenderThread.ColormapSize)))
Exemple #29
0
class ConfigWriter(QThread):

    config = None
    configSaved = Signal(object)
    mutex = QMutex()

    def __init__(self):
        super().__init__()
        self.cfg_file = Path.home() / 'Pythonic' / 'current_config.json'

    def saveConfig(self, config):

        self.mutex.lock()
        self.config = deepcopy(config)
        self.mutex.unlock()
        self.start()

    def run(self):

        logging.debug('ConfigWriter::saveConfig() called')

        self.mutex.lock()
        try:
            with open(self.cfg_file, 'w') as file:
                json.dump(self.config, file, indent=4)
        except Exception as e:
            logging.debug('ConfigWriter::saveConfig() - {}'.format(e))
            pass
            return

        self.mutex.unlock()
        last_saved = "Config last saved: " + datetime.now().strftime(
            '%H:%M:%S')

        cmd = {
            'cmd': 'SetInfoText',
            'data': last_saved,
            'address': {
                "target": "MainWindow"
            }
        }

        self.configSaved.emit(cmd)
Exemple #30
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.__mutex = QMutex()
        self.__laserFileList: list = None
        self.__rowMargin: int = 0

        self.__laserFTPAddress: str = ""
        self.__laserFTPPort: int = 0
        self.__laserFTPRemotePath: str = ""

        self.__cameraPath: str = ""
        self.__cameraSendCsv: bool = True

        self.__localWaitTimeBeforeStart: int = 1
        self.__localLoadingPath: str = ""
        self.__localDownloadingPath: str = ""

        self.__csvFilename: str = ""
        self.__errorFilename: str = ""
        self.__logFilename: str = ""
        self.__stopRequest: bool = False
        self.__pauseRequest: bool = False
        self.__waitCondition = QWaitCondition()
Exemple #31
0
class RenderThread(QThread):
    ColormapSize = 512

    renderedImage = Signal(QImage, float)

    def __init__(self, parent=None):
        super(RenderThread, self).__init__(parent)

        self.mutex = QMutex()
        self.condition = QWaitCondition()
        self.centerX = 0.0
        self.centerY = 0.0
        self.scaleFactor = 0.0
        self.resultSize = QSize()
        self.colormap = []

        self.restart = False
        self.abort = False

        for i in range(RenderThread.ColormapSize):
            self.colormap.append(self.rgbFromWaveLength(380.0 + (i * 400.0 / RenderThread.ColormapSize)))

    def stop(self):
        self.mutex.lock()
        self.abort = True
        self.condition.wakeOne()
        self.mutex.unlock()

        self.wait(2000)

    def render(self, centerX, centerY, scaleFactor, resultSize):
        locker = QMutexLocker(self.mutex)

        self.centerX = centerX
        self.centerY = centerY
        self.scaleFactor = scaleFactor
        self.resultSize = resultSize

        if not self.isRunning():
            self.start(QThread.LowPriority)
        else:
            self.restart = True
            self.condition.wakeOne()

    def run(self):
        while True:
            self.mutex.lock()
            resultSize = self.resultSize
            scaleFactor = self.scaleFactor
            centerX = self.centerX
            centerY = self.centerY
            self.mutex.unlock()

            halfWidth = resultSize.width() // 2
            halfHeight = resultSize.height() // 2
            image = QImage(resultSize, QImage.Format_RGB32)

            NumPasses = 8
            curpass = 0

            while curpass < NumPasses:
                MaxIterations = (1 << (2 * curpass + 6)) + 32
                Limit = 4
                allBlack = True

                for y in range(-halfHeight, halfHeight):
                    if self.restart:
                        break
                    if self.abort:
                        return

                    ay = 1j * (centerY + (y * scaleFactor))

                    for x in range(-halfWidth, halfWidth):
                        c0 = centerX + (x * scaleFactor) + ay
                        c = c0
                        numIterations = 0

                        while numIterations < MaxIterations:
                            numIterations += 1
                            c = c*c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c*c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c*c + c0
                            if abs(c) >= Limit:
                                break
                            numIterations += 1
                            c = c*c + c0
                            if abs(c) >= Limit:
                                break

                        if numIterations < MaxIterations:
                            image.setPixel(x + halfWidth, y + halfHeight,
                                           self.colormap[numIterations % RenderThread.ColormapSize])
                            allBlack = False
                        else:
                            image.setPixel(x + halfWidth, y + halfHeight, qRgb(0, 0, 0))

                if allBlack and curpass == 0:
                    curpass = 4
                else:
                    if not self.restart:
                        self.renderedImage.emit(image, scaleFactor)
                    curpass += 1

            self.mutex.lock()
            if not self.restart:
                self.condition.wait(self.mutex)
            self.restart = False
            self.mutex.unlock()

    def rgbFromWaveLength(self, wave):
        r = 0.0
        g = 0.0
        b = 0.0

        if wave >= 380.0 and wave <= 440.0:
            r = -1.0 * (wave - 440.0) / (440.0 - 380.0)
            b = 1.0
        elif wave >= 440.0 and wave <= 490.0:
            g = (wave - 440.0) / (490.0 - 440.0)
            b = 1.0
        elif wave >= 490.0 and wave <= 510.0:
            g = 1.0
            b = -1.0 * (wave - 510.0) / (510.0 - 490.0)
        elif wave >= 510.0 and wave <= 580.0:
            r = (wave - 510.0) / (580.0 - 510.0)
            g = 1.0
        elif wave >= 580.0 and wave <= 645.0:
            r = 1.0
            g = -1.0 * (wave - 645.0) / (645.0 - 580.0)
        elif wave >= 645.0 and wave <= 780.0:
            r = 1.0

        s = 1.0
        if wave > 700.0:
            s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0)
        elif wave < 420.0:
            s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0)

        r = pow(r * s, 0.8)
        g = pow(g * s, 0.8)
        b = pow(b * s, 0.8)

        return qRgb(r*255, g*255, b*255)
Exemple #32
0
class msv2:
    def __init__(self):
        self.ser = serial.Serial()
        self.escape = 0
        self.connected = 0
        self.state = WAITING_DLE
        self.crc_data = []
        self.data = []
        self.mutex = QMutex()

    def explore(self):
         list = serial.tools.list_ports.comports(include_links=False)
         return [x.device for x in list]

    def connect(self, port):
        self.port = port
        self.ser.baudrate = BAUDRATE
        self.ser.port = port
        self.ser.timeout = 0.2
        try:
            self.ser.open()
            self.connected = 1
            print("connected")
            return 1
        except:
            return 0
    def reconnect(self):
        try:
            self.ser.port = self.port
            self.ser.baudrate = BAUDRATE
            self.ser.timeout = 0.2
            self.ser.open()
            self.connected = 1
            print("connected")
            return 1
        except:
            return 0

    def disconnect(self):
        try:
            self.ser.close()
            self.connected = 0
            print("disconnected")
            return 1
        except:
            return 0

    def is_connected(self):
        return self.connected

    def encode(self, opcode, data):
        bin_data = []
        crc_data = []
        bin_data.append(DLE)
        bin_data.append(STX)
        bin_data.append(opcode)
        bin_data.append(int(len(data)/2))
        crc_data.append(opcode)
        crc_data.append(int(len(data)/2))
        i = 0
        for byte in data:
            bin_data.append(byte)
            crc_data.append(byte)
            if byte == DLE:
                bin_data.append(byte)

        crc_data.append(0)
        crc_data.append(0)
        crc = crc16(crc_data)
        
        bin_data.append(crc & 0x00ff)
        bin_data.append((crc >> 8) & 0x00ff)
        return bin_data


    def decode(self, d):
        #print("decode state:", self.state)
        d = ord(d)
        if (self.escape == 1 and d == STX):
            self.state = WAITING_OPCODE
            self.escape = 0
            return MSV2_PROGRESS

        if (self.state == WAITING_DLE and d == DLE):
            self.crc_data = []
            self.data = []
            self.state = WAITING_STX
            return MSV2_PROGRESS

        if (d == DLE and self.escape == 0):
            self.escape = 1
            return MSV2_PROGRESS

        if (d == DLE and self.escape == 1):
            self.escape = 0

        if (self.state == WAITING_STX and d == STX):
            self.state = WAITING_OPCODE
            return MSV2_PROGRESS

        if (self.state == WAITING_OPCODE):
            self.opcode = d
            self.state = WAITING_LEN
            self.crc_data.append(d)
            return MSV2_PROGRESS

        if (self.state == WAITING_LEN):
            self.data_len = d
            self.length = 2*d
            self.crc_data.append(d)
            self.counter = 0
            self.state = WAITING_DATA
            return MSV2_PROGRESS

        if (self.state == WAITING_DATA):
            self.data.append(d)
            self.crc_data.append(d)
            self.counter += 1
            if (self.counter==self.length):
                self.state = WAITING_CRC1
            return MSV2_PROGRESS

        if (self.state == WAITING_CRC1):
            self.crc = d
            self.state = WAITING_CRC2
            return MSV2_PROGRESS

        if (self.state == WAITING_CRC2):
            self.crc += d<<8
            self.state = WAITING_DLE
            self.crc_data.append(0)
            self.crc_data.append(0)
            if(self.crc == crc16(self.crc_data)):
                return MSV2_SUCCESS
            else:
                return MSV2_WRONG_CRC

        self.state=WAITING_DLE
        return MSV2_PROGRESS

    def send(self, opcode, data):
        if self.connected:
            self.mutex.lock()
            msg = self.encode(opcode, data)
            error = 0
            try:
                self.ser.write(msg)
            except:
                print("WRITE ERROR")
                self.mutex.unlock()
                self.reconnect()
                return -1
            #print('[{}]'.format(', '.join(hex(x) for x in msg)))
            try:
                while 1:
                    byte = self.ser.read(1)
                    #print("dta: {}".format(hex(ord(byte))))
                    if not byte:
                        print("no resp error")
                        self.mutex.unlock()
                        return 0
                    res = self.decode(byte)
                    #print("res:", res)
                    if not res == MSV2_PROGRESS:
                        break
                #print('[{}]'.format(', '.join(hex(x) for x in self.data)))
                if self.data == [0xce, 0xec] or self.data == [0xbe, 0xeb]:
                    self.mutex.unlock()
                    print("CRC_ERROR")
                    return 0
                else:
                    self.mutex.unlock()
                    print("nominal_resp")
                    return self.data
            except:
                print("READ ERROR")
                self.mutex.unlock()
                self.reconnect()
                return -1
        else:
            print("CONN_ERROR")
            return -1
## included in the packaging of this file. Please review the following
## information to ensure the GNU General Public License requirements will
## be met: https://www.gnu.org/licenses/gpl-3.0.html.
##
## $QT_END_LICENSE$
##
#############################################################################
'''Test cases for QThread'''

import unittest
from PySide2.QtCore import QThread, QCoreApplication, QObject, SIGNAL, QMutex, QTimer
from PySide2.QtCore import QEventLoop

from helper import UsesQCoreApplication

mutex = QMutex()


class Dummy(QThread):
    '''Dummy thread'''
    def __init__(self, *args):
        super(Dummy, self).__init__(*args)
        self.called = False

    def run(self):
        #Start-quit sequence
        self.qobj = QObject()
        mutex.lock()
        self.called = True
        mutex.unlock()
class FortuneThread(QThread):
    newFortune = Signal(str)

    error = Signal(int, str)

    def __init__(self, parent=None):
        super(FortuneThread, self).__init__(parent)

        self.quit = False
        self.hostName = ''
        self.cond = QWaitCondition()
        self.mutex = QMutex()
        self.port = 0

    def __del__(self):
        self.mutex.lock()
        self.quit = True
        self.cond.wakeOne()
        self.mutex.unlock()
        self.wait()

    def requestNewFortune(self, hostname, port):
        locker = QMutexLocker(self.mutex)
        self.hostName = hostname
        self.port = port
        if not self.isRunning():
            self.start()
        else:
            self.cond.wakeOne()

    def run(self):
        self.mutex.lock()
        serverName = self.hostName
        serverPort = self.port
        self.mutex.unlock()

        while not self.quit:
            Timeout = 5 * 1000

            socket = QTcpSocket()
            socket.connectToHost(serverName, serverPort)

            if not socket.waitForConnected(Timeout):
                self.error.emit(socket.error(), socket.errorString())
                return

            while socket.bytesAvailable() < 2:
                if not socket.waitForReadyRead(Timeout):
                    self.error.emit(socket.error(), socket.errorString())
                    return

            instr = QDataStream(socket)
            instr.setVersion(QDataStream.Qt_4_0)
            blockSize = instr.readUInt16()

            while socket.bytesAvailable() < blockSize:
                if not socket.waitForReadyRead(Timeout):
                    self.error.emit(socket.error(), socket.errorString())
                    return

            self.mutex.lock()
            fortune = instr.readQString()
            self.newFortune.emit(fortune)

            self.cond.wait(self.mutex)
            serverName = self.hostName
            serverPort = self.port
            self.mutex.unlock()