Sun, 03 Jun 2018 18:04:11 +0200
[plotter] fix and improve a bit the HPGL plotter emulator
at least, the mocked version now works again
--- a/pygpibtoolkit/plotter/gpib_plotter.py Fri May 18 01:07:28 2018 +0200 +++ b/pygpibtoolkit/plotter/gpib_plotter.py Sun Jun 03 18:04:11 2018 +0200 @@ -33,11 +33,13 @@ } def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1, - address=5): + address=5, started_cb=None): super().__init__(device, baudrate, timeout, address, mode=0) + self.plot_started_cb = started_cb - def plotStarted(self): - pass + def plot_started(self): + if callable(self.plot_started_cb): + self.plot_started_cb() def load_plot(self, wait_timeout=0): """ @@ -50,8 +52,11 @@ """ res = "" i = 0 + # replies dict is modified in some cases, so make a copy replies = self._replies.copy() - if wait_timeout is not None and not isinstance(wait_timeout, (float, int)): + + if wait_timeout is not None and not isinstance( + wait_timeout, (float, int)): raise TypeError("wait_timeout (%s:%s) has wrong type" % ( repr(wait_timeout), type(wait_timeout))) if wait_timeout < 0: @@ -59,25 +64,27 @@ self._cnx.timeout = wait_timeout firstloop = True - newdata = False - while i<self._retries: - l = self._cnx.readline().strip() + while i < self._retries: + l = self._cnx.readline().strip().decode() if l and firstloop: self._cnx.timeout = self._timeout firstloop = False - self.plotStarted() - if l == "": + self.plot_started() + if not l: if i == 0: # > (self._retries/2): - # ie. we just received new stuffs (i is reset in the else block) + # we just received new stuffs (i is reset in the else blk) for k, v in replies.items(): # check wether we should reply smthg eres = res.replace('\n', '').strip() - if eres.endswith(k) or eres.endswith(k+';') or eres.endswith(k+';OE'): - self._cnx.write("%s" % v) + shouldreply = any(eres.endswith(k + sfx) + for sfx in ('', ';', ';OE')) + if shouldreply: + self._cnx.write(("%s" % v).encode()) if k == "OS": + # don't remember why we need this... replies[k] = "16" break - self._cnx.write('\r') + self._cnx.write(b'\r') # time.sleep(0.1) i += 1 else: @@ -94,26 +101,31 @@ if __name__ == '__main__': import optparse opt = optparse.OptionParser( - 'A simple HP7470A GPIB plotter emulator for USB-GPIB bundle (ProLogix)') - opt.add_option('-f', '--filename', default=None, - dest='filename', - help='Output filename. If not set, write to stdout') - opt.add_option('-d', '--device', default='/dev/ttyUSB0', - dest='device', - help='Device of the RS232 connection (default: /dev/ttyUSB0)', - ) - opt.add_option('-a', '--address', default=0, - dest='address', - help='GPIB address of the device', - ) - opt.add_option('-l', '--loop', default=False, - action="store_true", - dest="loop", - help="Continuously wait for new plots. If set, filename must be set and files will be created with _n at the end") - opt.add_option('-v', '--verbose', default=False, - action="store_true", - dest="verbose", - help="Verbose mode",) + 'A simple HP7470A GPIB plotter emulator for ' + 'USB-GPIB bundle (ProLogix)') + opt.add_option( + '-f', '--filename', default=None, + dest='filename', + help='Output filename. If not set, write to stdout') + opt.add_option( + '-d', '--device', default='/dev/ttyUSB0', + dest='device', + help='Device of the RS232 connection (default: /dev/ttyUSB0)') + opt.add_option( + '-a', '--address', default=0, + dest='address', + help='GPIB address of the device') + opt.add_option( + '-l', '--loop', default=False, + action="store_true", + dest="loop", + help=("Continuously wait for new plots. If set, filename must be " + "set and files will be created with _n at the end")) + opt.add_option( + '-v', '--verbose', default=False, + action="store_true", + dest="verbose", + help="Verbose mode") options, argv = opt.parse_args(sys.argv) @@ -125,13 +137,13 @@ else: outf = sys.stdout - try: plotter = GPIBplotter( device=options.device, address=int(options.address), timeout=0.06) except (gpib.SerialException, gpib.ConnectionError) as e: - sys.stderr.write('Connection error:\n\t' + '\n\t'.join([str(x) for x in e.args]) + '\n') + sys.stderr.write('Connection error:\n\t' + '\n\t'.join( + [str(x) for x in e.args]) + '\n') sys.stderr.write('Check your parameters\n') sys.exit(1) if options.verbose: @@ -147,10 +159,11 @@ outf.write(plot) if options.verbose: sys.stderr.write('\n') - sys.stderr.write('Received a new plot (written to %s)\n'%outf.name) + sys.stderr.write( + 'Received a new plot (written to %s)\n' % outf.name) if not options.loop: loop = False else: nloop += 1 fname, ext = os.path.splitext(options.filename) - outf = open(fname + "_%d"%nloop + ext, 'w') + outf = open(fname + "_%d" % nloop + ext, 'w')
--- a/pygpibtoolkit/plotter/gpib_plotter_mockup.py Fri May 18 01:07:28 2018 +0200 +++ b/pygpibtoolkit/plotter/gpib_plotter_mockup.py Sun Jun 03 18:04:11 2018 +0200 @@ -15,37 +15,39 @@ """ import glob -import os import time import random -class GPIBplotter:#(GPIB): - """ - A mockup thet will find in a directory some HPGL files and feed them randomly + +class GPIBplotter: + """A mockup thet will find in a directory some HPGL files and feed them + randomly + """ def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1, - address=5): + address=5, started_cb=None): self._timeout = timeout self.filenames = glob.glob('examples/hpgl_plots/*.plt') - self._next = random.randint(10,50) + self._next = random.randint(10, 50) self._num = 0 + self.plot_started_cb = started_cb - def plotStarted(self): - pass - + def plot_started(self): + if callable(self.plot_started_cb): + self.plot_started_cb() + def load_plot(self, wait_timeout=0): if wait_timeout: time.sleep(wait_timeout) self._num += 1 if self._num > self._next: - ret = open(random.choice(self.filenames)).read() - if len(ret)>0: - self.plotStarted() + with open(random.choice(self.filenames)) as fobj: + ret = fobj.read().strip() + if ret: + self.plot_started() self._num = 0 - self._next = random.randint(10,100) - time.sleep(random.randint(1,3)) + self._next = random.randint(10, 100) + time.sleep(random.randint(1, 3)) return ret return None return None - -
--- a/pygpibtoolkit/plotter/qgpib_plotter.py Fri May 18 01:07:28 2018 +0200 +++ b/pygpibtoolkit/plotter/qgpib_plotter.py Sun Jun 03 18:04:11 2018 +0200 @@ -19,9 +19,10 @@ import time from PyQt5 import QtWidgets, QtGui, QtCore, QtPrintSupport, uic -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, pyqtSignal from pygpibtoolkit.plotter.hpgl_qt import QHPGLPlotterWidget +from pygpibtoolkit.plotter.gpib_plotter import GPIBplotter from pygpibtoolkit.qt5.qpreferences import IntItem, UnicodeItem, ColorItem from pygpibtoolkit.qt5.qpreferences import BoolItem @@ -40,14 +41,10 @@ os.path.join(HERE, "qhpgl_plotter.ui"), from_imports=True, import_from='pygpibtoolkit.plotter',) except Exception as e: - print(e) - from pygpibtoolkit.plotter.qhpgl_plotter_ui import Ui_MainWindow as form_class + from pygpibtoolkit.plotter.qhpgl_plotter_ui import ( + Ui_MainWindow as form_class) -if "-m" in sys.argv: - from pygpibtoolkit.plotter.gpib_plotter_mockup import GPIBplotter -else: - from pygpibtoolkit.plotter.gpib_plotter import GPIBplotter class Preferences(AbstractPreferences): @@ -97,7 +94,8 @@ autodisplay = BoolItem( default=True, name="Auto display", - description="Automatically display a new plot as soon as it is received", + description=( + "Automatically display a new plot as soon as it is received"), group="Misc") @@ -151,7 +149,8 @@ self._plots_list = QtCore.QStringListModel() self.plotsView.setModel(self._plots_list) self.plotsView.activated.connect(self.currentPlotChanged) - self.plotsView.selectionModel().currentChanged.connect(self.currentPlotChanged) + self.plotsView.selectionModel().currentChanged.connect( + self.currentPlotChanged) self.setReceivingLed() def currentPlotChanged(self, index, old_index=None): @@ -170,8 +169,8 @@ self.close() def closeEvent(self, event): + # if self.promptForSave(): if 1: - #if self.promptForSave(): self._prefs._pos = self.pos() self._prefs._size = self.size() self._prefs._appState = self.saveState() @@ -193,7 +192,6 @@ def openFiles(self, filenames): ok = False for filename in filenames: - print('FNAE=', filename) if os.path.exists(filename): data = open(filename).read() name = os.path.basename(filename) @@ -260,9 +258,10 @@ def initializeGPIB(self): self._online = False try: - self.gpib_plotter = QGPIBplotter(device=self._prefs.device, - address=self._prefs.address, - ) + self.gpib_plotter = GPIBplotter( + device=self._prefs.device, + address=self._prefs.address, + ) self.captureThread = GPIBReceiver(self.gpib_plotter) self.captureThread.plotReceived.connect(self.plotReceived) self.captureThread.plotStarted.connect(self.plotStarted) @@ -278,9 +277,9 @@ self.initializeGPIB() if self.gpib_plotter is None: QtWidgets.QMessageBox.critical( - self, self.tr("GPIB error"), - self.tr("<b>Unable to initialize GPIB connection</b>." - "<br>Please check your GPIB dongle and settings.")) + self, "GPIB error", + "<b>Unable to initialize GPIB connection</b>." + "<br>Please check your GPIB dongle and settings.") self._online = False self.setCaptureLed() return @@ -308,57 +307,37 @@ self.receivingButton.setIcon(icn) -class QGPIBplotter(GPIBplotter): - def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1, - address=5): - super().__init__(device, baudrate, timeout, address) - self.emitter = None - - def plotStarted(self): - if self.emitter: - self.emitter.emit(SIGNAL('plotStarted()')) - # self.emitter.msleep(1) - class GPIBReceiver(QtCore.QThread): + plotStarted = pyqtSignal() + plotReceived = pyqtSignal(int) + def __init__(self, cnx, parent=None): super().__init__(parent) self.gpibplotter = cnx - self.gpibplotter.emitter = self + self.gpibplotter.plot_started_cb = self.plotStarted.emit - self._cancelmutex = QtCore.QMutex() self._cancel = False # self._nreceived = 0 self._plotsmutex = QtCore.QMutex() self._plots = [] - self._startstopmutex = QtCore.QMutex() - self._startstop = QtCore.QWaitCondition() self._capturing = False def cancel(self): - self._cancelmutex.lock() self._cancel = True - self._cancelmutex.unlock() def startCapture(self): - self._startstop.wakeOne() + self._capturing = True def stopCapture(self): - self._startstopmutex.lock() self._capturing = False - self._startstopmutex.unlock() def run(self): - while 1: - self._cancelmutex.lock() - if self._cancel: - return - self._cancelmutex.unlock() - self._startstopmutex.lock() + while not self._cancel: if not self._capturing: - self._startstop.wait(self._startstopmutex) - self._capturing = True - self._startstopmutex.unlock() + self.msleep(100) + continue + plot = self.gpibplotter.load_plot(wait_timeout=0.1) timestamp = time.time() if plot: @@ -366,7 +345,8 @@ self._plots.append((plot, timestamp)) n = len(self._plots) self._plotsmutex.unlock() - self.emit(SIGNAL('plotReceived(int)'), n-1) + + self.plotReceived.emit(n - 1) self.msleep(10) def getPlot(self, num): @@ -378,6 +358,8 @@ def main(): + global GPIBplotter + import optparse opt = optparse.OptionParser( 'A simple PyQt4 HP7470A GPIB plotter emulator for USB-GPIB bundle ' @@ -393,6 +375,8 @@ help="Verbose mode",) options, argv = opt.parse_args(sys.argv) + if options.mockup: + from pygpibtoolkit.plotter.gpib_plotter_mockup import GPIBplotter a = QtWidgets.QApplication(argv) w = QtHPGLPlotter()