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()
class SignalThread(QThread): def __init__(self, parent=None): QThread.__init__(self, parent) self.waitcond = QWaitCondition() self.mutex = QMutex() self.isstopped = False def trigger(self): """lock first to make sure the QThread is actually waiting for a signal""" self.mutex.lock() self.waitcond.wakeOne() self.mutex.unlock() def stopThread(self): self.mutex.lock() self.isstopped = True self.waitcond.wakeOne() self.mutex.unlock() def run(self): self.mutex.lock() while not self.isstopped: # just wait, and trigger every time we receive a signal self.waitcond.wait(self.mutex) if not self.isstopped: self.emit(SIGNAL("triggerSignal()")) self.mutex.unlock()
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)
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()
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)
class CSVRegenerator(QThread): cleanLocalFolderStepSignal = Signal(int) cleanCameraFolderStepSignal = Signal(int) renameLaserItemsStepSignal = Signal(int) downloadItemsFromLaserStepSignal = Signal(int) cleanLaserFolderStepSignal = Signal(int) csvBuildProcessStepSignal = Signal(int) sendCsvToLaserStepSignal = Signal(int) sendCsvToCameraStepSignal = Signal(int) exitCodeSignal = Signal(int) cvsNewFileEmptySignal = Signal(bool) threadPausedSignal = Signal(bool) 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() def setLaserFileList(self, fileList: list): locker = QMutexLocker(self.__mutex) self.__laserFileList = fileList def getLaserFileList(self): locker = QMutexLocker(self.__mutex) return self.__laserFileList def getRowMargin(self): return self.__rowMargin def setRowMargin(self, rowMargin: int): self.__rowMargin = rowMargin def setLaserConnectionParameters(self, ftpAddress, ftpPort, ftpRemotePath=""): locker = QMutexLocker(self.__mutex) self.__laserFTPAddress = ftpAddress self.__laserFTPPort = ftpPort self.__laserFTPRemotePath = ftpRemotePath def getLaserConnectionParameters(self): locker = QMutexLocker(self.__mutex) return self.__laserFTPAddress, self.__laserFTPPort, self.__laserFTPRemotePath def setCameraConnectionParameters(self, cameraPath: str): locker = QMutexLocker(self.__mutex) self.__cameraPath = cameraPath def getCameraConnectionParameters(self): locker = QMutexLocker(self.__mutex) return self.__cameraPath def getCameraSendCSV(self): locker = QMutexLocker(self.__mutex) return self.__cameraSendCsv def setCameraSendCSV(self, cameraSendCSV: bool): locker = QMutexLocker(self.__mutex) self.__cameraSendCsv = cameraSendCSV def getLocalWaitTimeBeforeStart(self): locker = QMutexLocker(self.__mutex) return self.__localWaitTimeBeforeStart def setLocalWaitTimeBeforeStart(self, waitTime: int): locker = QMutexLocker(self.__mutex) self.__localWaitTimeBeforeStart = waitTime def setLocalLoadingPath(self, path: str): locker = QMutexLocker(self.__mutex) self.__localLoadingPath = path def getLocalLoadingPath(self): locker = QMutexLocker(self.__mutex) return self.__localLoadingPath def setLocalDownloadingPath(self, path: str): locker = QMutexLocker(self.__mutex) self.__localDownloadingPath = path def getLocalDownloadingPath(self): locker = QMutexLocker(self.__mutex) return self.__localDownloadingPath def getCsvFilename(self): locker = QMutexLocker(self.__mutex) return self.__csvFilename def setCsvFilename(self, filename: str): locker = QMutexLocker(self.__mutex) self.__csvFilename = filename def getErrorFilename(self): locker = QMutexLocker(self.__mutex) return self.__errorFilename def setErrorFilename(self, filename: str): locker = QMutexLocker(self.__mutex) self.__errorFilename = filename def getLogFilename(self): locker = QMutexLocker(self.__mutex) return self.__logFilename def setLogFilename(self, filename: str): locker = QMutexLocker(self.__mutex) self.__logFilename = filename def getPauseRequest(self): locker = QMutexLocker(self.__mutex) return self.__pauseRequest def setPauseRequest(self, pause: bool): locker = QMutexLocker(self.__mutex) self.__pauseRequest = pause if not self.__pauseRequest: self.__waitCondition.notify_all() def getStopRequest(self): locker = QMutexLocker(self.__mutex) return self.__stopRequest def setStopRequest(self, stop: bool): locker = QMutexLocker(self.__mutex) self.__stopRequest = stop def connectFtp(self, ftpController) -> bool: isConnected: bool = False try: Logger().info("Connessione al laser in FTP") ftpController.connect() ftpController.login() isConnected = True except ftplib.all_errors as ftpErr: Logger().error("Errore connessione FTP: " + str(ftpErr)) ftpController.close() isConnected = False return isConnected def run(self): Logger().info("Start CSV Regenerator") self.cleanLocalFolderStepSignal.emit(CSVRegeneratorStepStatus.IDLE) self.cleanCameraFolderStepSignal.emit(CSVRegeneratorStepStatus.IDLE) self.renameLaserItemsStepSignal.emit(CSVRegeneratorStepStatus.IDLE) self.downloadItemsFromLaserStepSignal.emit( CSVRegeneratorStepStatus.IDLE) self.cleanLaserFolderStepSignal.emit(CSVRegeneratorStepStatus.IDLE) self.csvBuildProcessStepSignal.emit(CSVRegeneratorStepStatus.IDLE) self.sendCsvToLaserStepSignal.emit(CSVRegeneratorStepStatus.IDLE) self.sendCsvToCameraStepSignal.emit(CSVRegeneratorStepStatus.IDLE) self.cvsNewFileEmptySignal.emit(False) locker = QMutexLocker(self.__mutex) rowMargin = self.__rowMargin laserFileList = self.__laserFileList laserFTPAddress = self.__laserFTPAddress laserFTPPort = self.__laserFTPPort laserFTPRemotePath = self.__laserFTPRemotePath cameraPath = self.__cameraPath cameraSendCSV = self.__cameraSendCsv waitTimeBeforeStart = self.__localWaitTimeBeforeStart localDownloadingPath = self.__localDownloadingPath csvFilename = self.__csvFilename csvExpireFilename = self.__csvFilename + ".expire" errorFilename = self.__errorFilename logFilename = self.__logFilename csvNewFilename = self.__csvFilename + ".new" locker.unlock() Logger().debug("Laser FTP Address: " + laserFTPAddress) Logger().debug("Laser FTP Port: " + str(laserFTPPort)) Logger().debug("Laser FTP Remote Path: " + laserFTPRemotePath) Logger().debug("Camera Path: " + cameraPath) Logger().debug("Camera Send CSV: " + str(cameraSendCSV)) Logger().debug("Local Downloading Path: " + localDownloadingPath) Logger().debug("Csv Filename: " + csvFilename) Logger().debug("Error Filename: " + errorFilename) Logger().debug("Log Filename: " + logFilename) Logger().debug("Csv New Filename: " + csvNewFilename) Logger().info("Aspetto " + str(waitTimeBeforeStart) + " [s] prima di iniziare") self.sleep(waitTimeBeforeStart) Logger().info("Inizio il processo") # path csv e file di errore csvFileLocalPath = localDownloadingPath + "\\" + csvFilename csvNewFileLocalPath = localDownloadingPath + "\\" + csvNewFilename errorFileLocalPath = localDownloadingPath + "\\" + errorFilename localLogPath = localDownloadingPath + "\\log" csvCameraPath = cameraPath + "\\" + csvFilename # variabili locali itemFounded = 0 canContinue = False errorCode = ThreadExitCode.NO_ERROR stepToProcess = CSVRegeneratorStep.CLEAN_LOCAL_FOLDER # variabili connessione FTP ftpController = FTP() ftpController.host = laserFTPAddress ftpController.port = laserFTPPort isFtpConnected = False while stepToProcess != CSVRegeneratorStep.PROCESS_END: # controllo se posso continuare locker = QMutexLocker(self.__mutex) while self.__pauseRequest: self.threadPausedSignal.emit(True) self.__waitCondition.wait(self.__mutex) self.threadPausedSignal.emit(False) stopRequest = self.__stopRequest locker.unlock() if stopRequest: break # stopRequest = self.getStopRequest() # if stopRequest: # break if stepToProcess == CSVRegeneratorStep.CLEAN_LOCAL_FOLDER: Logger().info("Rimozione files nella cartella download locale") self.cleanLocalFolderStepSignal.emit( CSVRegeneratorStepStatus.IN_PROGRESS) try: if os.path.exists(csvFileLocalPath): Logger().info("Rimozione file: " + csvFileLocalPath) os.remove(csvFileLocalPath) if os.path.exists(csvNewFileLocalPath): Logger().info("Rimozione file: " + csvNewFileLocalPath) os.remove(csvNewFileLocalPath) if os.path.exists(errorFileLocalPath): Logger().info("Rimozione file: " + errorFileLocalPath) os.remove(errorFileLocalPath) except OSError as err: if err != errno.ENOENT: Logger().error("Rimozione file fallita, errore: " + str(err)) self.cleanLocalFolderStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) self.sleep(1) continue stepToProcess += 1 self.cleanLocalFolderStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) Logger().info( "Rimozione files nella cartella download locale OK") elif stepToProcess == CSVRegeneratorStep.CLEAN_CAMERA_FOLDER: Logger().info("Rimozione file " + csvFilename + " dalla camera") self.cleanCameraFolderStepSignal.emit( CSVRegeneratorStepStatus.IN_PROGRESS) try: if os.path.exists(csvCameraPath): Logger().debug("Rimozione file .csv dalla camera") os.remove(csvCameraPath) except OSError as err: if err != errno.ENOENT: Logger().error("Rimozione file fallita") self.cleanCameraFolderStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) self.sleep(1) continue stepToProcess += 1 self.cleanCameraFolderStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) Logger().info("Rimozione file " + csvFilename + " dalla camera OK") elif stepToProcess == CSVRegeneratorStep.RENAME_LASER_ITEMS: Logger().info("Rinomino file " + csvFilename + " in " + csvExpireFilename) self.renameLaserItemsStepSignal.emit( CSVRegeneratorStepStatus.IN_PROGRESS) if not isFtpConnected: isFtpConnected = self.connectFtp(ftpController) if not isFtpConnected: self.renameLaserItemsStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) self.sleep(1) continue try: Logger().info("Spostamento nella cartella FTP: " + laserFTPRemotePath) ftpController.cwd(laserFTPRemotePath) Logger().info("Rinomino il file " + csvFilename + " in " + csvExpireFilename) ftpController.rename(csvFilename, csvExpireFilename) except ftplib.all_errors as ftpErr: Logger().error("Errore connessione FTP: " + str(ftpErr)) self.renameLaserItemsStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) ftpController.close() isFtpConnected = False self.sleep(1) continue stepToProcess += 1 self.renameLaserItemsStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) Logger().info("Rinomino file " + csvFilename + " in " + csvExpireFilename + " OK") elif stepToProcess == CSVRegeneratorStep.DOWNLOAD_ITEMS_FROM_LASER: Logger().info("Download file dal laser") self.downloadItemsFromLaserStepSignal.emit( CSVRegeneratorStepStatus.IN_PROGRESS) if not os.path.exists(localLogPath): os.mkdir(localLogPath) if not isFtpConnected: isFtpConnected = self.connectFtp(ftpController) if not isFtpConnected: self.downloadItemsFromLaserStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) self.sleep(1) continue try: ftpController.cwd(laserFTPRemotePath) # recupero il file lista.csv e lo elimino da ftp Logger().info("Download file: " + csvExpireFilename) cmd = "RETR " + csvExpireFilename Logger().debug("Comando: " + cmd) ftpController.retrbinary( cmd, open(csvFileLocalPath, 'wb').write) # recupero il file error.txt e lo elimino da ftp Logger().info("Download file: " + errorFilename) cmd = "RETR " + errorFilename Logger().debug("Comando: " + cmd) ftpController.retrbinary( cmd, open(errorFileLocalPath, 'wb').write) except ftplib.all_errors as ftpErr: Logger().error("Errore download file: " + str(ftpErr)) self.downloadItemsFromLaserStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) ftpController.close() isFtpConnected = False self.sleep(1) continue try: # recupero il file log ts = time.time() logFilenameTS = datetime.datetime.fromtimestamp( ts).strftime('%Y%m%d-%H%M%S') logFilenameTS = localLogPath + "\\" + logFilenameTS + ".log" Logger().info("Download file: " + logFilename) cmd = "RETR " + logFilename Logger().debug("Comando: " + cmd) ftpController.retrbinary(cmd, open(logFilenameTS, 'wb').write) except ftplib.all_errors as ftpErr: Logger().error("Errore download file: " + str(ftpErr)) ftpController.close() isFtpConnected = False stepToProcess += 1 self.downloadItemsFromLaserStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) Logger().info("Download file dal laser OK") elif stepToProcess == CSVRegeneratorStep.CLEAN_LASER_FOLDER: Logger().info("Rimozione file cartella laser") self.cleanLaserFolderStepSignal.emit( CSVRegeneratorStepStatus.IN_PROGRESS) if not isFtpConnected: isFtpConnected = self.connectFtp(ftpController) if not isFtpConnected: self.cleanLaserFolderStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) self.sleep(1) continue try: ftpController.cwd(laserFTPRemotePath) Logger().info("Rimozione file: " + csvExpireFilename) ftpController.delete(csvExpireFilename) Logger().info("Rimozione file: " + errorFilename) ftpController.delete(errorFilename) except ftplib.all_errors as ftpErr: Logger().error("Errore rimozione file: " + str(ftpErr)) self.cleanLaserFolderStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) ftpController.close() isFtpConnected = False self.sleep(1) continue stepToProcess += 1 self.cleanLaserFolderStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) Logger().info("Rimozione file cartella laser OK") elif stepToProcess == CSVRegeneratorStep.CSV_BUILD_PROCESS: Logger().info("Generazione nuovo file csv") self.csvBuildProcessStepSignal.emit( CSVRegeneratorStepStatus.IN_PROGRESS) # apro il file error in lettura per vedere l'indice dell'ultima stringa stampata fp = None try: Logger().info("Recupero informazioni dal file: " + errorFileLocalPath) fp = open(errorFileLocalPath, encoding="utf-8-sig", newline="\n") lineStr = fp.readline().rstrip("\n") lastPrintedString = fp.readline() Logger().debug("Line: " + str(lineStr)) Logger().debug("LastPrintedString: " + lastPrintedString) lineToSeek = int(lineStr) lineToSeek += rowMargin except OSError: Logger().error("Errore apertura file " + errorFileLocalPath) self.csvBuildProcessStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) fp.close() self.sleep(1) continue except ValueError: Logger().error("Errore conversione indice riga a intero") self.csvBuildProcessStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) fp.close() self.sleep(1) continue fp.close() # creo la lista di stringhe scartando quelle gia' stampate streamFile = None Logger().info("Lettura file locale " + csvFilename + " escludendo le stringhe stampate") try: fp = open(csvFileLocalPath, newline="\r\n", encoding="utf-8") for rowCounter in range(lineToSeek): readLine = fp.readline() if readLine == "": break streamFile = fp.read() except OSError: Logger().error("Errore apertura file: " + csvFileLocalPath) self.csvBuildProcessStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) fp.close() self.sleep(1) continue fp.close() # se file vuoto, allora ho finito, devo far caricare al cliente un nuovo file csv if streamFile == None or len(streamFile) == 0: Logger().info("Lista vuota") self.cvsNewFileEmptySignal.emit(True) stepToProcess = CSVRegeneratorStep.PROCESS_END self.csvBuildProcessStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) continue # creo il nuovo file csv con la nuova lista Logger().info("Scrittura file " + csvNewFilename + " senza le stringhe stampate") try: fp = open(csvNewFileLocalPath, "wb") bytes2send = bytearray(streamFile, "utf-8") fp.write(bytes2send) except OSError: Logger().error("Errore apertura file: " + csvNewFileLocalPath) self.csvBuildProcessStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) fp.close() self.sleep(1) continue fp.close() stepToProcess += 1 self.csvBuildProcessStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) Logger().info("Generazione nuovo file csv OK") elif stepToProcess == CSVRegeneratorStep.SEND_CSV_TO_LASER: Logger().info("Invio file " + csvNewFilename + " al laser") self.sendCsvToLaserStepSignal.emit( CSVRegeneratorStepStatus.IN_PROGRESS) if not isFtpConnected: isFtpConnected = self.connectFtp(ftpController) if not isFtpConnected: self.sendCsvToLaserStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) self.sleep(1) continue try: ftpController.cwd(laserFTPRemotePath) Logger().info("Upload file: " + csvFilename) cmd = "STOR " + csvFilename Logger().debug("Comando: " + cmd) fp = open(csvNewFileLocalPath, "rb") ftpController.storbinary(cmd, fp) except ftplib.all_errors as ftpErr: Logger().error("Error on FTP:" + str(ftpErr)) self.sendCsvToLaserStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) ftpController.close() isFtpConnected = False self.sleep(1) continue stepToProcess += 1 self.sendCsvToLaserStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) Logger().info("Invio file " + csvNewFilename + " al laser OK") elif stepToProcess == CSVRegeneratorStep.SEND_CSV_TO_CAMERA: if cameraSendCSV: Logger().info("Invio nuovo file " + csvFilename + " alla camera") self.sendCsvToCameraStepSignal.emit( CSVRegeneratorStepStatus.IN_PROGRESS) try: shutil.copy(csvNewFileLocalPath, csvCameraPath) except: Logger().error( "Impossibile copiare il nuovo fil csv in camera: " + csvNewFileLocalPath) self.sendCsvToCameraStepSignal.emit( CSVRegeneratorStepStatus.ENDED_KO) self.sleep(1) continue self.sendCsvToCameraStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) stepToProcess += 1 Logger().info("Invio nuovo file " + csvFilename + " alla camera OK") else: Logger().info("Invio nuovo file " + csvFilename + " alla camera non richiesto") stepToProcess += 1 self.sendCsvToCameraStepSignal.emit( CSVRegeneratorStepStatus.ENDED_OK) Logger().info("Processo terminato correttamente") if isFtpConnected: ftpController.close() self.exit(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)