Esempio n. 1
0
 def __init__(self, parent = None):
     super(ProdGui, self).__init__(parent)
     
     # counters
     self.face_count = 0
     self.device_count = 1
     self.current_device_no = 1
     
     # Create the queues for data transfer from serial
     self.q_Data = None
     self.q_Error = None
     # Create (serial) event monitor flag
     self.event_monitor = False
     self.com_monitor = None
     # Create a data class
     self.livefeed = LiveDataFeed()
     self.value_samples = []
     # Create a Timer Class
     self.timer = QTimer()
     
     #Init the UI
     self.create_main_frame()
     self.create_menu()
     
     #text file we will be saving in
     # ACC | GSM | GSM_SNR | RTC | SD | NRF_SPI | STN | V_BAT | GPS | GPS_ANT | NRF-ACC | NRF_SD | NRF_OTA
     self.failed_checks = {"acc":0,"gsm":0,"gsm_snr":0,"rtc":0,"sd":0,"nrf_spi":0,"stn":0,"v_bat":0,
                           "gps":0,"gps_ant":0,"nrf_acc":0,"nrf_sd":0,"nrf_ota":0}
     
     self.setWindowTitle("Carnot Production")
     
     #advanced stuff
     self.advanced_set = False
     self.timer_counter = 0
     self.small_string_flag = 0
Esempio n. 2
0
 def __init__(self, *args, **kwargs):
     MyMplCanvas.__init__(self, *args, **kwargs)
     timer = QtCore.QTimer(self)
     timer.timeout.connect(self.on_timer)
     timer.start(100)
     self.livefeed = LiveDataFeed()
     self.xydata = []
Esempio n. 3
0
class CellCount_Qt_Mpl(QtGui.QWidget, ui_CellCount_Qt_Mpl.Ui_CellCount_Qt_Mpl):

    def __init__(self, parent=None):
    #def __init__(self, text, parent=None):
        super(CellCount_Qt_Mpl, self).__init__(parent)
        self.setupUi(self)
        
        # create live data feed object
        self.livefeed = LiveDataFeed()        
        # add title & legends for plots        
        self.setLegends()
          
    def on_start(self):
        # create timer object
        self.timer = QTimer()
        # connect signals with slots
        self.connect(self.timer, SIGNAL('timeout()'), self.on_timer)
        # update timer every ... seconds
        self.timer.start(frequency * 1000)
        
    def on_timer(self):
        """
        Executed periodically when the monitor update timer is fired.
        """
        
        # read the actual data
        data = np.loadtxt(options.filename, delimiter='\t')
        self.livefeed.add_data(data)
        
        """
        The livefeed is used to find out whether new data was received since the last update.
        If not, nothing is updated.
        """        
        
        if self.livefeed.has_new_data:
            data = self.livefeed.read_data()        
        
            # update bar plot
            self.barplot.axes.bar(data[:,0],data[:,1],width=0.5, bottom=0, color='r')
            self.barplot.axes.grid(True)
            self.barplot.axes.set_ylim(data[:,1].min()*0.9, data[:,1].max()*1.1)
            # update sum plot
            self.sumplot.axes.bar(data[:,0],data[:,2],width=0.5, bottom=0, color='g')
            self.sumplot.axes.grid(True)  
            #update plots
            self.setLegends()    
            self.barplot.draw()
            self.sumplot.draw()
            
    def setLegends(self):
        
        # add title & legends for the 1st plot        
        self.barplot.axes.set_title('Cell Count Current')        
        self.barplot.axes.set_xlabel('Frame')
        self.barplot.axes.set_ylabel('Cell Number')
        # add title & legends for the 2nd plot
        self.sumplot.axes.set_title('Cell Count Cumulative')        
        self.sumplot.axes.set_xlabel('Frame')
        self.sumplot.axes.set_ylabel('Sum of Cells')
Esempio n. 4
0
 def __init__(self, parent=None):
 #def __init__(self, text, parent=None):
     super(CellCount_Qt_Mpl, self).__init__(parent)
     self.setupUi(self)
     
     # create live data feed object
     self.livefeed = LiveDataFeed()        
     # add title & legends for plots        
     self.setLegends()
Esempio n. 5
0
    def __init__(self, parent=None):
        super(DataMonitor, self).__init__(parent)

        self.monitor_active = False
        self.livefeed = LiveDataFeed()
        self.timer = QTimer()
        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()
Esempio n. 6
0
class MyDynamicMplCanvas(MyMplCanvas):
    """A canvas that updates itself every second with a new plot."""
    def __init__(self, *args, **kwargs):
        MyMplCanvas.__init__(self, *args, **kwargs)
        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.on_timer)
        timer.start(100)
        self.livefeed = LiveDataFeed()
        self.xydata = []

    def on_start(self):
        channel_A = 0x30
        channel_B = 0x34
        StartGPIO()
        print("GPIO setup complete")

        StartSPI()
        print("SPI setup complete")

        self.data_q = Queue.Queue()
        self.adc = ADCMonitor(self.data_q, 0)
        self.dac = DAC()
        self.dac.write(0.75000, channel_B)
        self.adc.start()

    def on_stop(self):
        self.adc.join()

    def on_timer(self):
        self.read_adc_data()
        self.update_figure()

    def read_adc_data(self):
        qdata = list(get_all_from_queue(self.data_q))
        if len(qdata) > 0:
            data = dict(ts=qdata[-1][0], voltage=qdata[-1][1])
            self.livefeed.add_data(data)

    def compute_initial_figureself():
        self.axes.plot([0], [0], 'r')

    def update_figure(self):

        data = self.livefeed.read_data()
        self.xydata.append((data['ts'], data['voltage']))

        xdata = [s[0] for s in self.xydata]
        ydata = [s[1] for s in self.xydata]

        # Build a list of 4 random integers between 0 and 10 (both inclusive)
        #l = [random.randint(0, 10) for i in range(4)]

        self.axes.set_ylim(min(ydata), max(ydata))
        self.axes.plot(xdata, ydata, 'r')
        self.draw()
Esempio n. 7
0
 def __init__(self, parent=None):
     super(PlottingDataMonitor, self).__init__(parent)
     
     self.monitor_active = False
     self.com_monitor = None
     self.com_data_q = None
     self.com_error_q = None
     self.livefeed = LiveDataFeed()
     self.temperature_samples = []
     self.timer = QTimer()
     
     self.create_menu()
     self.create_main_frame()
     self.create_status_bar()
    def __init__(self, parent=None):
        super(PlottingDataMonitor, self).__init__(parent)

        self.monitor_active = False
        self.com_monitor = None
        self.com_data_q = None
        self.com_error_q = None
        self.livefeed = LiveDataFeed()
        self.temperature_samples = []
        self.timer = QTimer()

        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()
Esempio n. 9
0
class PlottingDataMonitor(QMainWindow):
    def __init__(self, parent=None):
        super(PlottingDataMonitor, self).__init__(parent)

        self.monitor_active = False
        self.logger_active = False
        self.com_monitor = None
        self.com_data_q = None
        self.com_error_q = None
        self.livefeed = LiveDataFeed()
        self.temperature_samples = []
        self.timer = QTimer()


        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()


    def make_data_box(self, name):
        label = QLabel(name)
        qle = QLineEdit()
        qle.setEnabled(False)
        qle.setFrame(False)
        return (label, qle)

    def create_plot(self):
        plot = Qwt.QwtPlot(self)
        plot.setCanvasBackground(Qt.black)

        #plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, 10000, 1000)



        plot.setAxisTitle(Qwt.QwtPlot.xBottom, 'Time')
        plot.setAxisScaleDraw(Qwt.QwtPlot.xBottom, DateTimeScaleDraw())
        plot.setAxisLabelRotation(Qwt.QwtPlot.xBottom, -45.0 )
        plot.setAxisLabelAlignment(Qwt.QwtPlot.xBottom, QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom )

        plot.setAxisTitle(Qwt.QwtPlot.yLeft, 'CDC Counts')
        plot.setAxisAutoScale(Qwt.QwtPlot.yLeft)
        #plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, 8000000, 1000000)
        #plot.replot()

        curve = Qwt.QwtPlotCurve('')
        curve.setRenderHint(Qwt.QwtPlotItem.RenderAntialiased)
        pen = QPen(QColor('limegreen'))
        pen.setWidth(2)
        curve.setPen(pen)
        curve.attach(plot)

        return plot, curve

    def create_status_bar(self):
        self.status_text = QLabel('Monitor idle')
        self.statusBar().addWidget(self.status_text, 1)

    def create_main_frame(self):
        # Edit Box
        #
        self.editbox = QTextEdit()
        self.editbox.setReadOnly(True)
        editbox_layout = QVBoxLayout()
        editbox_layout.addWidget(self.editbox)
        editbox_layout.addStretch(1)
        editbox_groupbox = QGroupBox('CDC Counts')
        editbox_groupbox.setLayout(editbox_layout)
        # Port name
        #
        portname_l, self.portname = self.make_data_box('COM Port:')
        portname_layout = QHBoxLayout()
        portname_layout.addWidget(portname_l)
        portname_layout.addWidget(self.portname, 0)
        portname_layout.addStretch(1)
        portname_groupbox = QGroupBox('COM Port')
        portname_groupbox.setLayout(portname_layout)
        # Period Box
        #
        periodBox_l, self.periodBox = self.make_data_box('Period:')
        meanBox_l, self.meanBox = self.make_data_box('Mean:')
        deviationBox_l, self.deviationBox = self.make_data_box('Deviation:')
        countBox_l, self.countBox = self.make_data_box('Counts:')

        self.resetButton = QPushButton(QIcon('lucia.png'), 'Reset')
        self.resetButton.setGeometry(10, 10, 100, 30)
        self.resetButton.clicked.connect(self.periodReset)

        self.stopButton = QPushButton(QIcon('lucia.png'), 'Stop')
        self.stopButton.setGeometry(10,10,100,30)
        self.stopButton.clicked.connect(self.periodStop)

        periodBox_layout = QHBoxLayout()

        periodBox_layout.addWidget(periodBox_l)
        periodBox_layout.addWidget(self.periodBox, 0)

        #periodBox_layout.addWidget(meanBox_l)
        #periodBox_layout.addWidget(self.meanBox, 0)

        periodBox_layout.addWidget(deviationBox_l)
        periodBox_layout.addWidget(self.deviationBox, 0)

        periodBox_layout.addWidget(countBox_l)
        periodBox_layout.addWidget(self.countBox, 0)

        periodBox_layout.addWidget(self.resetButton)
        periodBox_layout.addWidget(self.stopButton)
        self.stop = 1


        periodBox_layout.addStretch(1)
        periodBox_groupbox = QGroupBox('Period Calculation')
        self.periodBox.setText('0')
        #self.meanBox.setText('M0')
        self.deviationBox.setText('0')
        self.countBox.setText('0')
        periodBox_groupbox.setLayout(periodBox_layout)
        # Add The Plot
        #
        self.plot, self.curve = self.create_plot()
        plot_layout = QVBoxLayout()
        plot_layout.addWidget(self.plot)
        plot_groupbox = QGroupBox('Capacitive to Digital Sensor Graph')
        plot_groupbox.setLayout(plot_layout)
        # Add The Zoomer
        #
        self.zoomer = Qwt.QwtPlotZoomer(
            Qwt.QwtPlot.xBottom,
            Qwt.QwtPlot.yLeft,
            Qwt.QwtPicker.DragSelection,
            Qwt.QwtPicker.AlwaysOff,
            self.plot.canvas())
        self.zoomer.setRubberBandPen(QPen(Qt.red))
        #self.zoomer.setZoomBase(True)
        # Main frame and layout
        #
        self.main_frame = QWidget()
        main_layout = QVBoxLayout()
        main_layout.addWidget(portname_groupbox)
        main_layout.addWidget(plot_groupbox)
        main_layout.addWidget(periodBox_groupbox)
        main_layout.addWidget(editbox_groupbox)
        main_layout.addStretch(1)
        self.main_frame.setLayout(main_layout)
        self.setCentralWidget(self.main_frame)
        self.set_actions_enable_state()

    def periodReset(self):
        print('Reset')
        self.periodAvg = []
        self.periodCount = 0
        self.stop = 0
        self.startTime=time.clock()
        self.r = Tk()
        self.r.withdraw()
        self.r.clipboard_clear()


    def periodStop(self):
        print('Stop')
        self.stop = 1
        try:
            for elem in self.periodAvg[2:len(self.periodAvg)]:
                self.r.clipboard_append(str(elem))
                self.r.clipboard_append('\n')
            self.r.destroy()
        except:
            print('There is nothing in the clipboard')

        #win32clipboard.OpenClipboard()
        #win32clipboard.EmptyClipboard()
        #win32clipboard.SetClipboardText(str(self.periodAvg[1:len(self.periodAvg)]))

        #win32clipboard.CloseClipboard()


    def create_menu(self):
        # The File Menu
        #
        self.file_menu = self.menuBar().addMenu("&File")
        selectport_action = self.create_action("Select COM &Port...",
            shortcut="Ctrl+P", slot=self.on_select_port, tip="Select a COM port")
        self.startMon_action = self.create_action("&Start monitor",
            shortcut="Ctrl+M", slot=self.on_startMon, tip="Start the data monitor")
        self.stopMon_action = self.create_action("&Stop monitor",
            shortcut="Ctrl+T", slot=self.on_stopMon, tip="Stop the data monitor")
        self.startLog_action = self.create_action("&Start logger",
            shortcut="Ctrl+L", slot=self.on_startLog, tip="Start the data logger")
        self.stopLog_action = self.create_action("&Stop logger",
            shortcut="Ctrl+T", slot=self.on_stopLog, tip="Stop the data logger")


        self.openFile = QAction(QIcon('open.png'), 'Open Graph', self)
        self.openFile.setShortcut('Ctrl+O')
        self.openFile.setStatusTip('Open Graph File')
        self.openFile.triggered.connect(self.on_Open)







        exit_action = self.create_action("E&xit", slot=self.close,
            shortcut="Ctrl+X", tip="Exit the application")
        self.startMon_action.setEnabled(False)
        self.stopMon_action.setEnabled(False)

        self.startLog_action.setEnabled(False)
        self.stopLog_action.setEnabled(False)

        self.add_actions(self.file_menu,
            (   selectport_action, self.openFile, self.startMon_action, self.stopMon_action, self.startLog_action, self.stopLog_action,
                None, exit_action))

        self.help_menu = self.menuBar().addMenu("&Help")
        about_action = self.create_action("&About",
            shortcut='F1', slot=self.on_about,
            tip='About the monitor')

        self.add_actions(self.help_menu, (about_action,))

    def selected(self, _):
        self.showInfo()

    def meanstdv(self, x):
        """ Calculate mean and standard deviation of data x[]:
        mean = {\sum_i x_i \over n} std = sqrt(\sum_i (x_i - mean)^2 \over n-1)
        """
        from math import sqrt
        n, mean, std = len(x), 0, 0
        for a in x:
            mean = mean + a
        mean = mean / float(n)
        for a in x:
            std = std + (a - mean)**2
        std = sqrt(std / float(n-1))
        return mean, std

    def on_Open(self):
        cdc_data = []
        index = []
        fname = QFileDialog.getOpenFileName(self, 'Open file', 'QDir::currentPath()')


        if fname.isEmpty() == False:
            f = open(fname, 'r')
            cdc_data = f.readlines()
            f.close()
            cdc_data.pop(0) #Pop the first and the last to get rid of bad data
            cdc_data.pop(-1)
            cdc_data_float = map(float, cdc_data)
            index = [i for i in range(len(cdc_data))]

            # Draw the Graph
            #

            self.curve.setData(index, cdc_data_float)
            #self.curve.setData(index[0:3600], cdc_data_float[0:3600])
            #Set up the axis scales
            self.plot.setAxisAutoScale(Qwt.QwtPlot.xBottom)
            self.plot.setAxisAutoScale(Qwt.QwtPlot.yLeft)
            self.zoomer.setZoomBase(True)

            #self.plot.replot()

    def set_actions_enable_state(self):
        if self.portname.text() == '':
            startMon_enable = stopMon_enable = False
            startLog_enable = stopLog_enable = False
        else:
            startMon_enable = not self.monitor_active
            stopMon_enable = self.monitor_active
            startLog_enable = not self.logger_active
            stopLog_enable = self.logger_active

        self.startLog_action.setEnabled(startLog_enable)
        self.startMon_action.setEnabled(startMon_enable)

        self.stopLog_action.setEnabled(stopLog_enable)
        self.stopMon_action.setEnabled(stopMon_enable)

    def on_about(self):
        msg = __doc__
        QMessageBox.about(self, "About cdcLogger", msg.strip())

    def on_select_port(self):
        ports = list(enumerate_serial_ports())
        if len(ports) == 0:
            QMessageBox.critical(self, 'No ports',
                'No serial ports found')
            return

        item, ok = QInputDialog.getItem(self, 'Select a port',
                    'Serial port:', ports, 0, False)

        if ok and not item.isEmpty():
            self.portname.setText(item)
            self.set_actions_enable_state()

    def on_stopMon(self):
        if self.com_monitor is not None:
            self.com_monitor.join(10)
            self.com_monitor = None

        self.monitor_active = False
        self.timer.stop()
        self.set_actions_enable_state()
        self.status_text.setText('Monitor idle')

    def on_startMon(self):
        if self.com_monitor is not None or self.portname.text() == '':
           return

        # First define a couple of variables that will be used to calculate the period
        #self.startTime = 1.1
        self.mark = 'False'
        self.periodAvg = []
        self.periodCount = 0


        self.data_q = Queue.Queue()
        self.error_q = Queue.Queue()
        self.com_monitor = ComMonitorThread(
            self.data_q,
            self.error_q,
            full_port_name(str(self.portname.text())),
            57600)
        self.com_monitor.start()

        com_error = get_item_from_queue(self.error_q)
        if com_error is not None:
            QMessageBox.critical(self, 'ComMonitorThread error', com_error)
            self.com_monitor = None

        self.monitor_active = True
        self.set_actions_enable_state()

        self.timer = QTimer()
        self.connect(self.timer, SIGNAL('timeout()'), self.on_timer)

        self.timer.start(.005)
        self.status_text.setText('Monitor running')

    def on_startLog(self):
        self.log()
        self.logger_active = True
        self.set_actions_enable_state()

    def on_stopLog(self):
        self.logger_active = False
        self.set_actions_enable_state()

    def on_timer(self):
        """ Executed periodically when the monitor update timer
            is fired.
        """
        self.read_serial_data()
        self.update_monitor()

    def log(self):
        self.log_state = True
        self.reading_num = 0

        self.today = str(datetime.date.today())
        self.logname = '%s.csv' % self.today
        self.file = open(self.logname, "wb")
        self.file_cvs = csv.writer(self.file)

    def save_data(self,reading):
        self.file_cvs.writerow ([reading])

    def save_data_stamps(self,reading_num,reading,timestamp,utimestamp):
        self.file_cvs.writerow ([reading_num,reading,timestamp,utimestamp])

    def update_monitor(self):
        """ Updates the state of the monitor window with new
            data. The livefeed is used to find out whether new
            data was received since the last update. If not,
            nothing is updated.
        """
        if self.livefeed.has_new_data:
            data = self.livefeed.read_data()



            # time.time() is a timestamp for the graph X axis ticks
            # This may be a good place to add period calculation
            #
            self.temperature_samples.append((time.time(), data['temperature']))
            if len(self.temperature_samples) > 765:
                self.temperature_samples.pop(0)

            xdata = [s[0] for s in self.temperature_samples]
            ydata = [s[1] for s in self.temperature_samples]


            if (len(self.temperature_samples) > 2 and self.stop == 0):

                if data['temperature'] > self.temperature_samples[-2][1]:
                    self.mark = 1
                elif (data['temperature'] < self.temperature_samples[-2][1]) and (self.mark == 1):
                    endTime = time.clock()
                    period = (endTime - self.startTime)
                    self.periodAvg.append(period)
                    if (len(self.periodAvg) <= 3):
                        self.periodBox.setText('0')
                        self.deviationBox.setText('0')
                        self.countBox.setText('Waiting')


                    if (len(self.periodAvg) > 3):
                        self.Average, self.Deviation = self.meanstdv(self.periodAvg[2:len(self.periodAvg)])
                        self.periodBox.setText(str(self.Average))
                        self.deviationBox.setText(str(self.Deviation))
                        self.countBox.setText(str(len(self.periodAvg)-2))






                    self.startTime = endTime
                    self.periodCount += 1
                    self.mark = 0

            #avg = sum(ydata) / float(len(ydata))


            self.plot.setAxisAutoScale(Qwt.QwtPlot.yLeft)
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, xdata[0], max(20, xdata[-1]))
            self.curve.setData(xdata, ydata)

            self.plot.replot()

            #self.plot.setAxisAutoScale(Qwt.QwtPlot.xBottom)
            #self.zoomer.setZoomBase(True)
            #self.thermo.setValue(avg)

    def read_serial_data(self):
        """ Called periodically by the update timer to read data
            from the serial port.
        """
        qdata = list(get_all_from_queue(self.data_q))
        if len(qdata) > 0: # At this point qdata object is a list type
            count = 0

            # Updates the text box with the incoming values
            # Clears the text box every 4096 values so that
            # Memory does not fill up with scrolling text
            for elem in list(qdata):
                self.editbox.append(qdata[count][0])
                if self.editbox.document().blockCount() == 4096:
                    self.editbox.clear()
                data = dict(timestamp=qdata[count][1],temperature=int(qdata[count][0]))
                self.livefeed.add_data(data)


                if self.logger_active:
                    self.reading_num = self.reading_num + 1

                    #Uncomment for stamps
                    #

                    #utimestamp = time.time() #A unix style timestamp for the log
                    #self.save_data_stamps(self.reading_num,int(qdata[count][0]),qdata[count][1],utimestamp)


                    if self.today != str(datetime.date.today()):
                        self.file.close()
                        self.log();
                        self.reading_num = self.reading_num + 1

                    self.save_data(int(qdata[count][0]))

                count=count+1

            #data = dict(timestamp=qdata[-1][1],
            #           temperature=int(qdata[-1][0]))

            #self.livefeed.add_data(data)

    def add_actions(self, target, actions):
        '''The following two methods are utilities for simpler creation
        and assignment of actions
        '''
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(  self, text, slot=None, shortcut=None,
                        icon=None, tip=None, checkable=False,
                        signal="triggered()"):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        if checkable:
            action.setCheckable(True)
        return action

    def closeEvent(self, event):
        self.editbox.append("closing PyQtTest")
    def __init__(self, parent=None):
        super(PlottingDataMonitor, self).__init__(parent)

        self.monitor_active = False
        self.com_monitor = None
        self.livefeed = LiveDataFeed()
        self.temperature_samples = []
        self.timer = QTimer()

        # menu
        #
        self.file_menu = self.menuBar().addMenu("&File")
        selectport_action = QAction('Select TTY &Port...', self)
        selectport_action.triggered.connect(self.on_select_port)
        self.file_menu.addAction(selectport_action)

        self.start_action = QAction('&Start monitor')
        self.start_action.triggered.connect(self.on_start)
        self.start_action.setEnabled(False)
        self.file_menu.addAction(self.start_action)

        self.stop_action = QAction('&Stop monitor')
        self.stop_action.triggered.connect(self.on_stop)

        # main widget
        #
        # port
        portname_label = QLabel('tty port:')
        self.portname = QLineEdit()
        self.portname.setEnabled(False)
        self.portname.setFrame(False)
        portname_layout = QHBoxLayout()
        portname_layout.addWidget(portname_label)
        portname_layout.addWidget(self.portname, 0)
        portname_layout.addStretch(1)
        portname_groupbox = QGroupBox('Port')
        portname_groupbox.setLayout(portname_layout)

        # plot widget
        self.plot = qwt.QwtPlot(self)
        self.plot.setCanvasBackground(Qt.black)
        self.plot.setAxisTitle(qwt.QwtPlot.xBottom, 'Time')
        self.plot.setAxisScale(qwt.QwtPlot.xBottom, 0, 10, 1)
        self.plot.setAxisTitle(qwt.QwtPlot.yLeft, 'Temperature')
        self.plot.setAxisScale(qwt.QwtPlot.yLeft, 0, 250, 40)
        self.plot.replot()

        # curve widget
        self.curve = qwt.QwtPlotCurve('')
        self.curve.setRenderHint(qwt.QwtPlotItem.RenderAntialiased)
        pen = QPen(QColor('limegreen'))
        pen.setWidth(2)
        self.curve.setPen(pen)
        self.curve.attach(self.plot)

        # dial
        #
        self.dial = QDial()
        self.dial.setNotchesVisible(True)
        self.dial.setRange(0, 20)
        self.dial.setValue(10)
        self.dial.valueChanged.connect(self.on_dial_change)

        self.dial_label = QLabel('Update speed = %s (Hz)' % self.dial.value())
        self.dial_label.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
        dial_layout = QVBoxLayout()
        dial_layout.addWidget(self.dial)
        dial_layout.addWidget(self.dial_label)

        # plot layout
        plot_layout = QVBoxLayout()
        plot_layout.addWidget(self.plot)
        plot_layout.addLayout(dial_layout)

        plot_groupbox = QGroupBox('Temperature')
        plot_groupbox.setLayout(plot_layout)

        # main
        self.main_frame = QWidget()
        main_layout = QVBoxLayout()
        main_layout.addWidget(portname_groupbox)
        main_layout.addWidget(plot_groupbox)
        main_layout.addStretch(1)
        self.main_frame.setLayout(main_layout)

        self.setCentralWidget(self.main_frame)

        # status
        #
        self.status_text = QLabel('Monitor idle')
        self.statusBar().addWidget(self.status_text, 1)
class PlottingDataMonitor(QMainWindow):
    def __init__(self, parent=None):
        super(PlottingDataMonitor, self).__init__(parent)

        self.monitor_active = False
        self.com_monitor = None
        self.livefeed = LiveDataFeed()
        self.temperature_samples = []
        self.timer = QTimer()

        # menu
        #
        self.file_menu = self.menuBar().addMenu("&File")
        selectport_action = QAction('Select TTY &Port...', self)
        selectport_action.triggered.connect(self.on_select_port)
        self.file_menu.addAction(selectport_action)

        self.start_action = QAction('&Start monitor')
        self.start_action.triggered.connect(self.on_start)
        self.start_action.setEnabled(False)
        self.file_menu.addAction(self.start_action)

        self.stop_action = QAction('&Stop monitor')
        self.stop_action.triggered.connect(self.on_stop)

        # main widget
        #
        # port
        portname_label = QLabel('tty port:')
        self.portname = QLineEdit()
        self.portname.setEnabled(False)
        self.portname.setFrame(False)
        portname_layout = QHBoxLayout()
        portname_layout.addWidget(portname_label)
        portname_layout.addWidget(self.portname, 0)
        portname_layout.addStretch(1)
        portname_groupbox = QGroupBox('Port')
        portname_groupbox.setLayout(portname_layout)

        # plot widget
        self.plot = qwt.QwtPlot(self)
        self.plot.setCanvasBackground(Qt.black)
        self.plot.setAxisTitle(qwt.QwtPlot.xBottom, 'Time')
        self.plot.setAxisScale(qwt.QwtPlot.xBottom, 0, 10, 1)
        self.plot.setAxisTitle(qwt.QwtPlot.yLeft, 'Temperature')
        self.plot.setAxisScale(qwt.QwtPlot.yLeft, 0, 250, 40)
        self.plot.replot()

        # curve widget
        self.curve = qwt.QwtPlotCurve('')
        self.curve.setRenderHint(qwt.QwtPlotItem.RenderAntialiased)
        pen = QPen(QColor('limegreen'))
        pen.setWidth(2)
        self.curve.setPen(pen)
        self.curve.attach(self.plot)

        # dial
        #
        self.dial = QDial()
        self.dial.setNotchesVisible(True)
        self.dial.setRange(0, 20)
        self.dial.setValue(10)
        self.dial.valueChanged.connect(self.on_dial_change)

        self.dial_label = QLabel('Update speed = %s (Hz)' % self.dial.value())
        self.dial_label.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
        dial_layout = QVBoxLayout()
        dial_layout.addWidget(self.dial)
        dial_layout.addWidget(self.dial_label)

        # plot layout
        plot_layout = QVBoxLayout()
        plot_layout.addWidget(self.plot)
        plot_layout.addLayout(dial_layout)

        plot_groupbox = QGroupBox('Temperature')
        plot_groupbox.setLayout(plot_layout)

        # main
        self.main_frame = QWidget()
        main_layout = QVBoxLayout()
        main_layout.addWidget(portname_groupbox)
        main_layout.addWidget(plot_groupbox)
        main_layout.addStretch(1)
        self.main_frame.setLayout(main_layout)

        self.setCentralWidget(self.main_frame)

        # status
        #
        self.status_text = QLabel('Monitor idle')
        self.statusBar().addWidget(self.status_text, 1)

    def set_actions_enable_state(self):
        if self.portname.text() == '':
            start_enable = stop_enable = False
        else:
            start_enable = not self.monitor_active
            stop_enable = self.monitor_active

        self.start_action.setEnabled(start_enable)
        self.stop_action.setEnabled(stop_enable)

    def read_serial_data(self):
        '''Called periodically be the update timer to read data from the
serial port.

        '''
        qdata = list(get_all_from_queue(self.data_q))
        if len(qdata) > 0:
            # print(len(qdata))

            data = dict(timestamp=qdata[-1][1], temperature=ord(qdata[-1][0]))
            # print(data)
            self.livefeed.add_data(data)
        else:
            print('no data')

    def update_monitor(self):
        '''Updates the state of the monitor window with new data. The
livefeed is used to dind out whether new data was received since last
update. If not, nothing is updated.

        '''
        if self.livefeed.has_new_data:
            data = self.livefeed.read_data()
            # print(data)
            self.temperature_samples.append(
                (data['timestamp'], data['temperature']))
            if len(self.temperature_samples) > 100:
                self.temperature_samples.pop(0)

            xdata = [s[0] for s in self.temperature_samples]
            ydata = [s[1] for s in self.temperature_samples]

            avg = sum(ydata) / float(len(ydata))

            self.plot.setAxisScale(qwt.QwtPlot.xBottom, xdata[0],
                                   max(20, xdata[-1]))
            self.curve.setData(xdata, ydata)
            self.plot.replot()

    # slots
    def on_select_port(self):
        text, ok = QInputDialog.getText(self, 'Port Name', 'Enter tty:')
        if ok:
            self.portname.setText(str(text))
            self.set_actions_enable_state()

    def on_start(self):
        '''Start the monitor: com_monitor thread and the update timer'''
        if self.com_monitor is not None or self.portname.text() == '':
            return

        self.data_q = Queue()
        self.error_q = Queue()
        self.com_monitor = ComMonitorThread(self.data_q, self.error_q,
                                            self.portname.text(), 38400)
        self.com_monitor.start()
        com_error = None
        try:
            com_error = self.error_q.get(True, 0.01)
        except Empty:
            pass
        if com_error is not None:
            QMessageBox.critical(self, 'ComMonitorThread error', com_error)
            self.com_monitor = None

        self.monitor_active = True
        self.set_actions_enable_state()

        self.timer = QTimer()
        self.timer.timeout.connect(self.on_timer)

        update_freq = self.dial.value()
        if update_freq > 0:
            self.timer.start(1000 / update_freq)

        self.status_text.setText('Monitor running')

    def on_stop(self):
        '''Stop the monitor'''
        if self.com_monitor is not None:
            self.com_monitor.join(0.01)
            self.com_monitor = None

        self.monitor_actibe = False
        self.timer.stop()
        self.set_actions_enable_state()

        self.status_text.setText('Monitor idle')

    def on_timer(self):
        '''Executed periodically when the monitor update timer is fired.'''
        self.read_serial_data()
        self.update_monitor()

    def on_dial_change(self):
        '''When the dial is rotated, it sets the update interval of the
timer'''
        update_freq = self.dial.value()
        self.dial_label.setText('Update speed = %s (Hz)' % self.dial.value())

        if self.timer.isActive():
            update_freq = max(0.01, update_freq)
            self.timer.setInterval(1000 / update_freq)
Esempio n. 12
0
class ProdGui(QMainWindow):
    def __init__(self, parent = None):
        super(ProdGui, self).__init__(parent)
        
        # counters
        self.face_count = 0
        self.device_count = 1
        self.current_device_no = 1
        
        # Create the queues for data transfer from serial
        self.q_Data = None
        self.q_Error = None
        # Create (serial) event monitor flag
        self.event_monitor = False
        self.com_monitor = None
        # Create a data class
        self.livefeed = LiveDataFeed()
        self.value_samples = []
        # Create a Timer Class
        self.timer = QTimer()
        
        #Init the UI
        self.create_main_frame()
        self.create_menu()
        
        #text file we will be saving in
        # ACC | GSM | GSM_SNR | RTC | SD | NRF_SPI | STN | V_BAT | GPS | GPS_ANT | NRF-ACC | NRF_SD | NRF_OTA
        self.failed_checks = {"acc":0,"gsm":0,"gsm_snr":0,"rtc":0,"sd":0,"nrf_spi":0,"stn":0,"v_bat":0,
                              "gps":0,"gps_ant":0,"nrf_acc":0,"nrf_sd":0,"nrf_ota":0}
        
        self.setWindowTitle("Carnot Production")
        
        #advanced stuff
        self.advanced_set = False
        self.timer_counter = 0
        self.small_string_flag = 0
        
    def create_main_frame(self):
        self.createFaces()
        self.create_next_button()
        self.create_status_bar()
        
        self.leftGroupBox.setEnabled(False)
        self.middleGroupBox.setEnabled(False)
        self.rightGroupBox.setEnabled(False)
        self.basicGroupBox.setEnabled(False)
        self.leftGroupBox.hide()
        self.middleGroupBox.hide()
        self.rightGroupBox.hide()
        
        self.basic.pixelLabel.setPixmap(QPixmap("images/logo.png"))
        self.left.pixelLabel.setPixmap(QPixmap("images/logo.png"))
        self.basic.saveToText.clicked.connect(self.on_save_txt)
        self.basic.submitButton.clicked.connect(self.on_submit)
        self.basic.device_text.append(str(self.current_device_no))
        self.basic.nextButton.clicked.connect(self.on_flash_button)
#         self.left.device_id.append(str(self.current_device_no))
        
        self.main_frame = QWidget()
        
        face_widget = QWidget()
        face_layout = QHBoxLayout()
        face_layout.addWidget(self.leftGroupBox);
        face_layout.addWidget(self.middleGroupBox);
        face_layout.addWidget(self.rightGroupBox);
        face_layout.addWidget(self.basicGroupBox)
        face_widget.setLayout(face_layout)
        
        main_layout = QVBoxLayout()
        main_layout.addWidget(face_widget)
        main_layout.addWidget(self.next_button)
        self.main_frame.setLayout(main_layout)
        self.setCentralWidget(self.main_frame)
        
    def on_flash_button(self):
        
        print("\n\nFlashing NRF\n")
        os.system("flashNRF.cmd")
        os.system('testing_main1.cmd')
        time.sleep(5)
    
    def create_menu(self):
        self.menu = self.menuBar().addMenu("&File")
        
        self.start_qc = self.create_action("Start &QC", 
                                           shortcut = "Ctrl+Q", slot = self.on_start, 
                                           tip = "Start the QC process")
        self.advanced = self.create_action("&Advanced", 
                                           shortcut = "Ctrl+C", slot = self.on_advanced, 
                                           tip = "Super Saiyan")
        self.menu.addAction(self.start_qc)
        self.menu.addAction(self.advanced) 
        
     
    def createFaces(self):
        self.leftGroupBox = QGroupBox("Step 1")
        self.left = LeftWidget()
        layout1 = QVBoxLayout()
        layout1.addWidget(self.left)
        self.leftGroupBox.setLayout(layout1)
        self.leftGroupBox.setMaximumSize(400, 450)
        
        self.middleGroupBox = QGroupBox("Step 2")
        self.middle = MiddleWidget()
        layout2 = QVBoxLayout()
        layout2.addWidget(self.middle)
        self.middleGroupBox.setLayout(layout2)
        self.middleGroupBox.setMaximumSize(450, 450)
        
        self.rightGroupBox = QGroupBox("Step 3")
        self.right = RightWidget()
        layout3 = QVBoxLayout()
        layout3.addWidget(self.right)
        self.rightGroupBox.setLayout(layout3)
        self.rightGroupBox.setMaximumSize(400, 450)
        # adding the next device button the right widget
        self.right.nextButton.clicked.connect(self.new_device)
        
        self.basicGroupBox = QGroupBox("Carnot")
        self.basic = BasicWidget()
        layout4 = QVBoxLayout()
        layout4.addWidget(self.basic)
        self.basicGroupBox.setLayout(layout4)
        self.basicGroupBox.setMinimumSize(400, 550)
        self.basicGroupBox.setMaximumSize(400, 1000)
        #self.basic.nextButton.clicked.connect(self.new_device())
        
    
    def create_next_button(self):
        self.next_button = QPushButton("Next")
        #self.next_button.clicked.connect(self.__next_face)
        self.next_button.clicked.connect(self.new_device)
        self.next_button.setEnabled(False)
        
    def create_status_bar(self):
        self.status_text = QLabel("Idle  (No QC?)")
        #self.statusBar().addWidget(self.status_text)
    
    def create_action(  self, text, slot=None, shortcut=None, 
                        icon=None, tip=None, checkable=False, 
                        signal="triggered()"):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.triggered.connect(slot)
        if checkable:
            action.setCheckable(True)
        return action   
        
    def new_device(self):
        
        #inclease device number
        self.basic.device_text.clear()
        self.basic.device_text.append(str(int(self.current_device_no) + 1))
        self.current_device_no = int(self.current_device_no) + 1
        #disable the buttons
        self.basic.saveToText.setEnabled(False)
        self.basic.submitButton.setEnabled(False)
        self.basic.nextButton.setEnabled(False) 
        self.basic.pixelLabel.setPixmap(QPixmap("images/logo.png"))
        #refresh_face
        #self.update_faces()
        '''
        self.leftGroupBox.setEnabled(False)
        self.middleGroupBox.setEnabled(False)
        self.rightGroupBox.setEnabled(False)
        self.leftGroupBox.setEnabled(True)
        self.next_button.setEnabled(True)
        print("device count:", self.device_count, '\n')
        self.left.update(self.on_serial_ports(),"Checked", qr_code(self.device_count))
        '''
        
    def __next_face(self):
        
        if self.face_count == 0:
            self.middleGroupBox.setEnabled(True)
            self.face_count += 1
            self.update_faces()
        elif self.face_count == 1:
            self.rightGroupBox.setEnabled(True)
            self.face_count = 0
            self.next_button.setEnabled(False)
            self.device_count += 1
            
            
    def on_serial_ports(self):
        ''' get a list of ports available.
        '''
        
        port_list = serial_ports()
        if len(port_list) == 0:
            QMessageBox.critical(self, "Check Connection",
                                  "Device Not Connected")
            return
        port = port_list
        return port
    
    def on_timer(self):
        """Executed periodically when qc update timer is launched""" 
        self.read_serial_data()
        
    def on_advanced(self):
        self.leftGroupBox.show()
        self.middleGroupBox.show()
        self.advanced_set = True
        if self.basicGroupBox.isEnabled():
            self.leftGroupBox.setEnabled(True)
            self.middleGroupBox.setEnabled(True)
        else:
            self.leftGroupBox.setEnabled(False)
            self.middleGroupBox.setEnabled(False)
    
    def on_start(self):
        ''' Start session -> on_serial_ports, then com_monitor
        thread 
        '''
        # this will call the flashing cmd scripts
        print("\n\nFlashing NRF\n")
        os.system("flashNRF.cmd")
        os.system("testing_main1.cmd")
        # so on start we will flash the device
        #then we sleep for 5 seconds so that the system is ready
        time.sleep(5)
        
        self.basicGroupBox.setEnabled(True)
        self.next_button.setEnabled(True)
#         self.basic.pixelLabel.setPixmap(QPixmap("images/cross-1.png"))
        self.basic.pixelLabel.setEnabled(True)
        
        if self.advanced_set:
            self.leftGroupBox.setEnabled(True)
            self.middleGroupBox.setEnabled(True)
        
        if self.com_monitor is not None and self.left.com_set() == "":
            return
        self.q_Data = queue.Queue()
        self.q_Error = queue.Queue()
        self.com_monitor = ComMonitorThread(
            self.q_Data,
            self.q_Error,
            self.on_serial_ports(),
            9600)
        self.com_monitor.start()
        
        com_error = get_item_from_queue(self.q_Error)
        if com_error is not None:
            QMessageBox.critical(self, 'ComMonitorThread error',
                com_error)
            self.com_monitor = None
            
        self.event_monitor = True
        
        self.timer = QTimer()
#         self.connect(self.timer, SIGNAL('timeout()'), self.on_timer)
        self.timer.timeout.connect(self.on_timer)
        self.timer.start(500.0)
        
        #self.status_text.setText("Bad Batch")
        
    def read_serial_data(self):
        """Called periodically to see if serial buffer
        data available"""
        
        ''' each qdata has a list which with-in has a list with 
        single character plus time stamp.
        '''
        #[STAT]: ACC | GSM | GSM_SNR | RTC | SD | NRF_SPI | STN | GPS | GPS_ANT | NRF-ACC
        #[INFO]: STM_FW | STM_ID | STN_FW | GSM_Ver | CCID | NRF_ID_low | NRF_ID_high
        
        b = []
        self.timer_counter += 1
        #every 1 sec
        if self.timer_counter > 2:
            self.timer_counter = 0
            qdata = list(get_all_from_queue(self.q_Data))
            print(qdata)
            if len(qdata) > 0 and b'S' in qdata[0][0]:
                qdata = qdata[1:] #skip the first S
                if len(qdata) > 70:
                    self.left.update(self.on_serial_ports(),"Checked", qr_code(self.device_count))
                for i_a in qdata:
                    if b'\r' in i_a:
                        break
                    b.append(i_a[0])
                #TODO: there is a glich in the code, if we do advanced while running the QC,
                # we only get a portion of the UART string
                if len(b) > 120:
                    if b[1] == b'A':
                        #in b we dont need the last 3 values \r \n and b'S'
                        #and in the bedinning we dont need b'TAT'
                        data = []
#                         print(b)
                        for i in range(0,len(b)):
                            data.append(b[i].decode("utf-8"))
                            
                        #find position of "I" for STAT string ending
                        #find position of "S" or "\r" for INFT string ending
#                         print(data)
                        if "I" in data:
                            data_stat = data[4:(data.index("I")-1)]
                            data_info = data[data.index("I")+5:]
                            print(data_stat)
                            print(data_info)
                            data_stat = "".join(data_stat)
                            data_info = "".join(data_info)
                            data_stat = data_stat.split(",")
                            data_info = data_info.split(",")
                            # now we have our data in the above variables
                            '''ACC | GSM | GSM_SNR | RTC | SD | NRF_SPI | STN | V_BAT | GPS | GPS_ANT | NRF-ACC | NRF_SD | NRF_OTA
                               STM_FW | STM_ID | STN_FW | GSM_Ver | CCID | NRF_ID_low | NRF_ID_high
                            '''
                            print(data_stat)
                            print(data_info)
                            self.livefeed.add_status(data_stat)
                            self.livefeed.add_info(data_info)
                            self.update_faces()
                else:
                    self.small_string_flag += 1
                    if self.small_string_flag > 10:
                        QMessageBox.information(self, "Check Connections", "Receiving less data, maybe NRF SPI has failed")
                        self.small_string_flag = 5
            else:
                pass
            
        self.current_device_no = self.basic.device_text.toPlainText()
        if self.current_device_no != "":
            self.basic.qr.clear()
            self.basic.qr.append(qr_code(self.current_device_no))
        #the following is for data from Teensy
        '''data = qdata[0]
        data = data[0].decode("utf-8")
        data_stat = "".join(data[5:34])
        data_info = ''.join(data[41:])
        
        data_stat = data_stat.split(",")
        data_info = data_info.split(",")
        print(data_stat)
        print(data_info)
        self.livefeed.add_status(data_stat)
        self.livefeed.add_info(data_info)
        self.update_faces()'''
        
        
    def update_faces(self):
        '''ACC | GSM | GSM_SNR | RTC | SD | NRF_SPI | STN | V_BAT | GPS | GPS_ANT | NRF-ACC | NRF_SD | NRF_OTA
           STM_FW | STM_ID | STN_FW | GSM_Ver | CCID | NRF_ID_low | NRF_ID_high | NRF_Version
        '''
        if self.livefeed.has_new_status:
            data_status = self.livefeed.read_status()
            #update battery voltage
            self.basic.text1.clear()
            self.basic.text1.append(data_status[7])
            #read info
            data_info = self.livefeed.read_info()
            if self.check_stm_status(data_status,data_info):
                print("All stats good")
            else:
                print("Error\n")
                   
        if self.livefeed.has_new_info:
            data_info = self.livefeed.read_info()
        else:
            pass
        
        '''if self.livefeed.has_new_status:
            data_status = self.livefeed.read_status()
            if self.check_stm_status(data_status):
                self.middle.update_middle_status(data_status[-1])
            else:
                print("Error\n")
            
#             self.middle.update_middle(data[0], data[1], data[2], data[3:])   
        if self.livefeed.has_new_info:
            data_info = self.livefeed.read_info()
            #format stm_id, nrf_id, stm_ver, nrf_ver
            if self.check_stm_status(data_status):
                self.middle.update_middle(data_info[1], data_info[-1], data_info[0], data_info[2])
            else:
                print("Error\n")
        else:
            pass'''
        
    def check_stm_status(self,data,info):
        '''ACC | GSM | GSM_SNR | RTC | SD | NRF_SPI | STN | V_BAT | GPS | GPS_ANT | NRF-ACC | NRF_SD | NRF_OTA
           STM_FW | STM_ID | STN_FW | GSM_Ver | CCID | NRF_ID_low | NRF_ID_high | NRF_version
        '''
        #this is used for teensy debugging
        #[STAT]: //ACC | GSM | GSM_SNR | RTC | SD | NRF_SPI | STN | V_BAT | GPS | GPS_ANT | NRF-ACC | NRF_SD | NRF_OTA
        #self.middle.update_status_flags(data[6], data[1], data[0], data[3], data[5],data[2],
        #                                data[4], data[7], data[8], data[9])
        if self.advanced_set:
            print(info[8])
            if 'S' not in info[8]:
                self.middle.update_middle(*info)
                self.middle.update_status_flags(data[6], data[1], data[0], data[3], data[5], data[2],
                                                 data[4], data[8], data[9], data[10], data[11], data[12])
            else:
                print("Bad info string received\n")
        
        
        #print(data)
        if '0' in data:
            print(data)
            number_fails = data.count('0')
            fail = ""
            failed_devices = []
            if data[0] == '0':
                failed_devices.append("ACC")
            if data[1] == '0':
                failed_devices.append("GSM")
            if data[2] == '0':
                failed_devices.append("GSM-SNR")
            if data[3] == '0':
                failed_devices.append("RTC")
            if data[4] == '0':
                failed_devices.append("SD")
            if data[5] == '0':
                failed_devices.append("NRF-SPI")
            if data[6] == '0':
                failed_devices.append("STN")
            if data[7] == '0':
                failed_devices.append("GPS")
            if data[8] == '0':
                failed_devices.append("GPS-ANT")
            if data[9] == '0':
                failed_devices.append("NRF-ACC")
            print(failed_devices)
            fail = " ".join(failed_devices)
            print(fail)
            
            QMessageBox.critical(self, "Device Modules Failed", "%s module(s) failed"% fail)
            self.basic.pixelLabel.setPixmap(QPixmap("images/cross-1.png"))
            #TODO: Disable this popup from comming again and again
            return 0
        elif int(data[2]) < 12:
            QMessageBox.critical(self, "GSM Antenna", "Please reconnect it")
        else:
            #TODO: Enable all the buttons
            self.basic.pixelLabel.setPixmap(QPixmap("images/tick-black.png"))
            self.basic.submitButton.setEnabled(True)
            self.basic.saveToText.setEnabled(True)
            self.basic.nextButton.setEnabled(True)
            return 1
        
    def on_submit(self):
        self.basic.pixelLabel.setPixmap(QPixmap("images/wait_1.jpg"))
        time.sleep(1)
        data_status = self.livefeed.read_status()
        data_info = self.livefeed.read_info()
        user_input_voltage = self.basic.text2.toPlainText()
        if user_input_voltage != "":
            user_input_voltage = float(user_input_voltage)
        else:
            QMessageBox.information(self, "Please enter value", "Measure the voltage value.")
            return
        if data_info[4] == "":
            print("no ccid") 
            data_info[4] = "123456789"
        if data_info[3] == "":
            print("No gsm version")
            data_info[3] = 255
        if data_info[2] == "":
            print("no STN version")
            data_info[2] = "255"
            
            
        '''
            stms_i = stnFlag
            nrfs_st= string of nrf_sd+unplug+gps+acc
            nrfs_i = gps
            gsmv = gsm version
            
            gpsv = we dont currently have gps version
            
        '''
        stm_status_bk = str(data_status[0]+data_status[1]+data_status[3]+data_status[4]+data_status[5]+data_status[6]+
                            data_status[7]+data_status[8]+data_status[9])
        data_to_backend = {"lb":int(self.current_device_no), "pc":str(qr_code(int(self.current_device_no))),
                           "flg":1, "stm":str(data_info[1]), "stmv": int(data_info[0]),
                           "nrf":str(data_info[5] + data_info[6]), "nrfv":int(data_info[-1]),
                            "simcc":str(data_info[4]), "stms_st":stm_status_bk,
                           "stms_i":int(data_status[6]), "nrfs_st": "1111","nrfs_i": int(data_status[8]),
                            "gsmv": data_info[3] ,"pwr": data_status[7],"hbn":int(data_info[-1]),
                            "stnv":str(data_info[2]),"gpsv":"123456789A", "vltDevice":int(user_input_voltage)}
        
        print(data_to_backend)
        r = requests.post('http://carnot-staging.herokuapp.com/devices/log/', data = json.dumps(data_to_backend), 
                          headers = {"ApiKey":"JXn8e6C29jhZ065i8wyQktY33YD3s9zy"})
        #print(r.content)
        y = r.content.decode("utf-8")
        # now we have a string
        if "true" in y:
            QMessageBox.information(self, "Server", "Data saved to backed")
            self.new_device()
        else:
            QMessageBox.critical(self, "Server", "Check internet connection")
    
    def on_save_txt(self):
        data_status = self.livefeed.read_status()
        data_info = self.livefeed.read_info()
        self.local_file = open("carnot_device.csv","a+")
        self.local_file.write("%d, " % int(self.current_device_no))
        self.local_file.write("%s, " % (qr_code(int(self.current_device_no))))
        for i in data_info:
            self.local_file.write("%s, " % i)
        for i in data_status:
            print(i)
            self.local_file.write("%s, " % (data_status))
        self.local_file.write("\r\n")
        self.local_file.close()
class PlottingDataMonitor(QMainWindow):
    def __init__(self, parent=None):
        super(PlottingDataMonitor, self).__init__(parent)

        self.monitor_active = False
        self.com_monitor = None
        self.com_data_q = None
        self.com_error_q = None
        self.livefeed = LiveDataFeed()
        self.temperature_samples = []
        self.timer = QTimer()

        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()

    #        self.showFullScreen()

    def make_data_box(self, name):
        label = QLabel(name)
        qle = QLineEdit()
        qle.setEnabled(False)
        qle.setFrame(False)
        return (label, qle)

    def create_plot(self):
        plot = Qwt.QwtPlot(self)
        plot.setCanvasBackground(Qt.black)
        plot.setAxisTitle(Qwt.QwtPlot.xBottom, "Time")
        plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, 10, 1)
        plot.setAxisTitle(Qwt.QwtPlot.yLeft, "val")
        plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, 30000, 40)

        plot.setAxisAutoScale(Qwt.QwtPlot.yLeft)

        plot.replot()

        curve = Qwt.QwtPlotCurve("")
        #        curve.setRenderHint(Qwt.QwtPlotItem.RenderAntialiased)
        pen = QPen(QColor("limegreen"))
        pen.setWidth(2)
        curve.setPen(pen)
        curve.attach(plot)
        return plot, curve

    def create_status_bar(self):
        self.status_text = QLabel("Monitor idle")
        self.statusBar().addWidget(self.status_text, 1)

    def create_main_frame(self):
        # Port name
        #
        portname_l, self.portname = self.make_data_box("Serial port:")

        portname_layout = QHBoxLayout()
        portname_layout.addWidget(portname_l)
        portname_layout.addWidget(self.portname, 0)
        portname_layout.addStretch(1)
        portname_groupbox = QGroupBox("Serial Port")
        portname_groupbox.setLayout(portname_layout)

        # Plot and thermo
        #
        self.plot, self.curve = self.create_plot()
        #        self.thermo = self.create_thermo()

        plot_layout = QVBoxLayout()
        plot_layout.addWidget(self.plot)
        plot_groupbox = QGroupBox("Value")
        plot_groupbox.setLayout(plot_layout)

        # Main frame and layout
        #
        self.main_frame = QWidget()
        main_layout = QVBoxLayout()
        main_layout.addWidget(portname_groupbox)
        main_layout.addWidget(plot_groupbox)
        main_layout.addStretch(1)
        self.main_frame.setLayout(main_layout)

        self.setCentralWidget(self.main_frame)
        self.set_actions_enable_state()

    def create_menu(self):
        self.file_menu = self.menuBar().addMenu("&File")

        selectport_action = self.create_action(
            "Select serial &Port...", shortcut="Ctrl+P", slot=self.on_select_port, tip="Select a serial port"
        )
        self.start_action = self.create_action(
            "&Start monitor", shortcut="Ctrl+M", slot=self.on_start, tip="Start the data monitor"
        )
        self.stop_action = self.create_action(
            "&Stop monitor", shortcut="Ctrl+T", slot=self.on_stop, tip="Stop the data monitor"
        )
        exit_action = self.create_action("E&xit", slot=self.close, shortcut="Ctrl+X", tip="Exit the application")

        self.start_action.setEnabled(False)
        self.stop_action.setEnabled(False)

        self.add_actions(self.file_menu, (selectport_action, self.start_action, self.stop_action, None, exit_action))

        self.help_menu = self.menuBar().addMenu("&Help")
        about_action = self.create_action("&About", shortcut="F1", slot=self.on_about, tip="About the monitor")

        self.add_actions(self.help_menu, (about_action,))

    def set_actions_enable_state(self):
        if self.portname.text() == "":
            start_enable = stop_enable = False
        else:
            start_enable = not self.monitor_active
            stop_enable = self.monitor_active

        self.start_action.setEnabled(start_enable)
        self.stop_action.setEnabled(stop_enable)

    def on_about(self):
        msg = __doc__
        QMessageBox.about(self, "About the demo", msg.strip())

    def on_select_port(self):
        ports = list(enumerate_serial_ports())
        if len(ports) == 0:
            QMessageBox.critical(self, "No ports", "No serial ports found")
            return

        item, ok = QInputDialog.getItem(self, "Select a port", "Serial port:", ports, 0, False)

        if ok and not item.isEmpty():
            self.portname.setText(item)
            self.set_actions_enable_state()

    def on_stop(self):
        """ Stop the monitor
        """
        if self.com_monitor is not None:
            self.com_monitor.join(0.01)
            self.com_monitor = None

        self.monitor_active = False
        self.timer.stop()
        self.set_actions_enable_state()

        self.status_text.setText("Monitor idle")

    def on_start(self):
        """ Start the monitor: com_monitor thread and the update
            timer
        """
        if self.com_monitor is not None or self.portname.text() == "":
            return

        self.data_q = Queue.Queue()
        self.error_q = Queue.Queue()
        self.com_monitor = ComMonitorThread(self.data_q, self.error_q, full_port_name(str(self.portname.text())), 9600)
        self.com_monitor.start()

        com_error = get_item_from_queue(self.error_q)
        if com_error is not None:
            QMessageBox.critical(self, "ComMonitorThread error", com_error)
            self.com_monitor = None

        self.monitor_active = True
        self.set_actions_enable_state()

        self.timer = QTimer()
        self.connect(self.timer, SIGNAL("timeout()"), self.on_timer)

        update_freq = 20
        self.timer.start(1000.0 / update_freq)

        self.status_text.setText("Monitor running")

    def on_timer(self):
        """ Executed periodically when the monitor update timer
            is fired.
        """
        self.read_serial_data()
        self.update_monitor()

    def update_monitor(self):
        """ Updates the state of the monitor window with new 
            data. The livefeed is used to find out whether new
            data was received since the last update. If not, 
            nothing is updated.
        """
        if self.livefeed.has_new_data:
            data = self.livefeed.read_data()

            self.temperature_samples.append((data["timestamp"], data["temperature"]))
            if len(self.temperature_samples) > 100:
                self.temperature_samples.pop(0)

            xdata = [s[0] for s in self.temperature_samples]
            ydata = [s[1] for s in self.temperature_samples]

            #            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, xdata[0], max(10, xdata[-1]))
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, xdata[0], xdata[0] + 5)
            self.curve.setData(xdata, ydata)
            self.plot.replot()

    def read_serial_data(self):
        """ Called periodically by the update timer to read data
            from the serial port.
        """
        qdata = list(get_all_from_queue(self.data_q))
        if len(qdata) > 0:
            #            print qdata
            data = dict(timestamp=qdata[-1][1], temperature=int(qdata[-1][0]))
            self.livefeed.add_data(data)

    # The following two methods are utilities for simpler creation
    # and assignment of actions
    #
    def add_actions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(self, text, slot=None, shortcut=None, icon=None, tip=None, checkable=False, signal="triggered()"):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        if checkable:
            action.setCheckable(True)
        return action
Esempio n. 14
0
class PlottingDataMonitor(QMainWindow):
    def __init__(self, parent=None):
        super(PlottingDataMonitor, self).__init__(parent)
        
        self.monitor_active = False
        self.com_monitor = None
        self.com_data_q = None
        self.com_error_q = None
        self.livefeed = LiveDataFeed()
        self.temperature_samples = []
        self.timer = QTimer()
        
        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()
        
    def make_data_box(self, name):
        label = QLabel(name)
        qle = QLineEdit()
        qle.setEnabled(False)
        qle.setFrame(False)
        return (label, qle)
        
    def create_plot(self):
        plot = Qwt.QwtPlot(self)
        plot.setCanvasBackground(Qt.black)
        plot.setAxisTitle(Qwt.QwtPlot.xBottom, 'Time')
        plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, 10, 1)
        plot.setAxisTitle(Qwt.QwtPlot.yLeft, 'Temperature')
        plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, 250, 40)
        plot.replot()
        
        curve = Qwt.QwtPlotCurve('')
        curve.setRenderHint(Qwt.QwtPlotItem.RenderAntialiased)
        pen = QPen(QColor('limegreen'))
        pen.setWidth(2)
        curve.setPen(pen)
        curve.attach(plot)
        
        return plot, curve

    def create_thermo(self):
        thermo = Qwt.QwtThermo(self)
        thermo.setPipeWidth(6)
        thermo.setRange(0, 120)
        thermo.setAlarmLevel(80)
        thermo.setAlarmEnabled(True)
        thermo.setFillColor(Qt.green)
        thermo.setAlarmColor(Qt.red)
        thermo.setOrientation(Qt.Horizontal, Qwt.QwtThermo.BottomScale)
        
        return thermo

    def create_knob(self):
        knob = Qwt.QwtKnob(self)
        knob.setRange(0, 20, 0, 1)
        knob.setScaleMaxMajor(10)
        knob.setKnobWidth(50)
        knob.setValue(10)
        return knob

    def create_status_bar(self):
        self.status_text = QLabel('Monitor idle')
        self.statusBar().addWidget(self.status_text, 1)

    def create_main_frame(self):
        # Port name
        #
        portname_l, self.portname = self.make_data_box('COM Port:')
        
        portname_layout = QHBoxLayout()
        portname_layout.addWidget(portname_l)
        portname_layout.addWidget(self.portname, 0)
        portname_layout.addStretch(1)
        portname_groupbox = QGroupBox('COM Port')
        portname_groupbox.setLayout(portname_layout)
        
        # Plot and thermo
        #
        self.plot, self.curve = self.create_plot()
        self.thermo = self.create_thermo()
        
        thermo_l = QLabel('Average')
        thermo_layout = QHBoxLayout()
        thermo_layout.addWidget(thermo_l)
        thermo_layout.addWidget(self.thermo)
        thermo_layout.setSpacing(5)
        
        self.updatespeed_knob = self.create_knob()
        self.connect(self.updatespeed_knob, SIGNAL('valueChanged(double)'),
            self.on_knob_change)
        self.knob_l = QLabel('Update speed = %s (Hz)' % self.updatespeed_knob.value())
        self.knob_l.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
        knob_layout = QVBoxLayout()
        knob_layout.addWidget(self.updatespeed_knob)
        knob_layout.addWidget(self.knob_l)
        
        plot_layout = QVBoxLayout()
        plot_layout.addWidget(self.plot)
        plot_layout.addLayout(thermo_layout)
        plot_layout.addLayout(knob_layout)
        
        plot_groupbox = QGroupBox('Temperature')
        plot_groupbox.setLayout(plot_layout)
        
        # Main frame and layout
        #
        self.main_frame = QWidget()
        main_layout = QVBoxLayout()
        main_layout.addWidget(portname_groupbox)
        main_layout.addWidget(plot_groupbox)
        main_layout.addStretch(1)
        self.main_frame.setLayout(main_layout)
        
        self.setCentralWidget(self.main_frame)
        self.set_actions_enable_state()

    def create_menu(self):
        self.file_menu = self.menuBar().addMenu("&File")
        
        selectport_action = self.create_action("Select COM &Port...",
            shortcut="Ctrl+P", slot=self.on_select_port, tip="Select a COM port")
        self.start_action = self.create_action("&Start monitor",
            shortcut="Ctrl+M", slot=self.on_start, tip="Start the data monitor")
        self.stop_action = self.create_action("&Stop monitor",
            shortcut="Ctrl+T", slot=self.on_stop, tip="Stop the data monitor")
        exit_action = self.create_action("E&xit", slot=self.close, 
            shortcut="Ctrl+X", tip="Exit the application")
        
        self.start_action.setEnabled(False)
        self.stop_action.setEnabled(False)
        
        self.add_actions(self.file_menu, 
            (   selectport_action, self.start_action, self.stop_action,
                None, exit_action))
            
        self.help_menu = self.menuBar().addMenu("&Help")
        about_action = self.create_action("&About", 
            shortcut='F1', slot=self.on_about, 
            tip='About the monitor')
        
        self.add_actions(self.help_menu, (about_action,))

    def set_actions_enable_state(self):
        if self.portname.text() == '':
            start_enable = stop_enable = False
        else:
            start_enable = not self.monitor_active
            stop_enable = self.monitor_active
        
        self.start_action.setEnabled(start_enable)
        self.stop_action.setEnabled(stop_enable)

    def on_about(self):
        msg = __doc__
        QMessageBox.about(self, "About the demo", msg.strip())
    
    def on_select_port(self):
        ports = list(enumerate_serial_ports())
        if len(ports) == 0:
            QMessageBox.critical(self, 'No ports',
                'No serial ports found')
            return
        
        item, ok = QInputDialog.getItem(self, 'Select a port',
                    'Serial port:', ports, 0, False)
        
        if ok and not item.isEmpty():
            self.portname.setText(item)            
            self.set_actions_enable_state()

    def on_stop(self):
        """ Stop the monitor
        """
        if self.com_monitor is not None:
            self.com_monitor.join(0.01)
            self.com_monitor = None

        self.monitor_active = False
        self.timer.stop()
        self.set_actions_enable_state()
        
        self.status_text.setText('Monitor idle')
    
    def on_start(self):
        """ Start the monitor: com_monitor thread and the update
            timer
        """
        if self.com_monitor is not None or self.portname.text() == '':
            return
        
        self.data_q = queue.Queue()
        self.error_q = queue.Queue()
        self.com_monitor = ComMonitorThread(
            self.data_q,
            self.error_q,
            full_port_name(str(self.portname.text())),
            38400)
        self.com_monitor.start()
        
        com_error = get_item_from_queue(self.error_q)
        if com_error is not None:
            QMessageBox.critical(self, 'ComMonitorThread error',
                com_error)
            self.com_monitor = None

        self.monitor_active = True
        self.set_actions_enable_state()
        
        self.timer = QTimer()
        self.connect(self.timer, SIGNAL('timeout()'), self.on_timer)
        
        update_freq = self.updatespeed_knob.value()
        if update_freq > 0:
            self.timer.start(1000.0 / update_freq)
        
        self.status_text.setText('Monitor running')
    
    def on_timer(self):
        """ Executed periodically when the monitor update timer
            is fired.
        """
        self.read_serial_data()
        self.update_monitor()

    def on_knob_change(self):
        """ When the knob is rotated, it sets the update interval
            of the timer.
        """
        update_freq = self.updatespeed_knob.value()
        self.knob_l.setText('Update speed = %s (Hz)' % self.updatespeed_knob.value())

        if self.timer.isActive():
            update_freq = max(0.01, update_freq)
            self.timer.setInterval(1000.0 / update_freq)

    def update_monitor(self):
        """ Updates the state of the monitor window with new 
            data. The livefeed is used to find out whether new
            data was received since the last update. If not, 
            nothing is updated.
        """
        if self.livefeed.has_new_data:
            data = self.livefeed.read_data()
            
            self.temperature_samples.append(
                (data['timestamp'], data['temperature']))
            if len(self.temperature_samples) > 100:
                self.temperature_samples.pop(0)
            
            xdata = [s[0] for s in self.temperature_samples]
            ydata = [s[1] for s in self.temperature_samples]
            
            avg = sum(ydata) / float(len(ydata))
                
            self.plot.setAxisScale(Qwt.QwtPlot.xBottom, xdata[0], max(20, xdata[-1]))
            self.curve.setData(xdata, ydata)
            self.plot.replot()
            
            self.thermo.setValue(avg)
            
    def read_serial_data(self):
        """ Called periodically by the update timer to read data
            from the serial port.
        """
        qdata = list(get_all_from_queue(self.data_q))
        if len(qdata) > 0:
            data = dict(timestamp=qdata[-1][1], 
                        temperature=ord(qdata[-1][0]))
            self.livefeed.add_data(data)
    
    # The following two methods are utilities for simpler creation
    # and assignment of actions
    #
    def add_actions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(  self, text, slot=None, shortcut=None, 
                        icon=None, tip=None, checkable=False, 
                        signal="triggered()"):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        if checkable:
            action.setCheckable(True)
        return action
Esempio n. 15
0
class DataMonitor(QMainWindow):
    def __init__(self, parent=None):
        super(DataMonitor, self).__init__(parent)

        self.monitor_active = False
        self.livefeed = LiveDataFeed()
        self.timer = QTimer()
        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()

    def make_data_box(self, name):
        label = QLabel(name)
        qle = QLineEdit()
        qle.setEnabled(False)
        qle.setFrame(False)
        return (label, qle)

    def create_plot(self):

        plot = Qwt.QwtPlot(self)
        plot.setCanvasBackground(Qt.black)
        plot.setAxisTitle(Qwt.QwtPlot.xBottom, 'Frame')
        plot.setAxisScale(Qwt.QwtPlot.xBottom, 0, 10, 1)
        plot.setAxisTitle(Qwt.QwtPlot.yLeft, 'Number of Cells')
        plot.setAxisScale(Qwt.QwtPlot.yLeft, 0, 200, 40)
        plot.replot()

        curve = Qwt.QwtPlotCurve('')
        curve.setRenderHint(Qwt.QwtPlotItem.RenderAntialiased)
        pen = QPen(QColor('limegreen'))
        pen.setWidth(2)
        curve.setPen(pen)
        curve.attach(plot)
        curve.setSymbol(
            Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse, pen.color(), pen.color(),
                          QSize(10, 10)))

        return plot, curve

    def create_knob(self):
        knob = Qwt.QwtKnob(self)
        knob.setRange(0, 20, 0, 1)
        knob.setScaleMaxMajor(10)
        knob.setKnobWidth(50)
        knob.setValue(2)
        return knob

    def create_status_bar(self):
        self.status_text = QLabel('Monitor idle')
        self.statusBar().addWidget(self.status_text, 1)

    def create_main_frame(self):

        self.plot, self.curve = self.create_plot()
        self.updatespeed_knob = self.create_knob()
        self.connect(self.updatespeed_knob, SIGNAL('valueChanged(double)'),
                     self.on_knob_change)
        self.knob_l = QLabel('Update speed = %s (Hz)' %
                             self.updatespeed_knob.value())
        self.knob_l.setAlignment(Qt.AlignTop | Qt.AlignHCenter)
        knob_layout = QVBoxLayout()
        knob_layout.addWidget(self.updatespeed_knob)
        knob_layout.addWidget(self.knob_l)

        plot_layout = QVBoxLayout()
        plot_layout.addWidget(self.plot)
        plot_layout.addLayout(knob_layout)

        plot_groupbox = QGroupBox('Data Plot')
        plot_groupbox.setLayout(plot_layout)

        # Main frame and layout
        #
        self.main_frame = QWidget()
        main_layout = QVBoxLayout()
        main_layout.addWidget(plot_groupbox)
        main_layout.addStretch(1)
        self.main_frame.setLayout(main_layout)

        self.setCentralWidget(self.main_frame)
        self.set_actions_enable_state()

    def create_menu(self):

        self.file_menu = self.menuBar().addMenu("&File")

        self.start_action = self.create_action("&Start monitor",
                                               shortcut="Ctrl+M",
                                               slot=self.on_start,
                                               tip="Start the data monitor")
        self.stop_action = self.create_action("&Stop monitor",
                                              shortcut="Ctrl+T",
                                              slot=self.on_stop,
                                              tip="Stop the data monitor")
        exit_action = self.create_action("E&xit",
                                         slot=self.close,
                                         shortcut="Ctrl+X",
                                         tip="Exit the application")

        self.start_action.setEnabled(True)
        self.stop_action.setEnabled(False)

        self.add_actions(
            self.file_menu,
            (self.start_action, self.stop_action, None, exit_action))
        self.add_actions(self.file_menu, (None, exit_action))

    def set_actions_enable_state(self):

        start_enable = not self.monitor_active
        stop_enable = self.monitor_active

        self.start_action.setEnabled(start_enable)
        self.stop_action.setEnabled(stop_enable)

    def on_stop(self):

        # Stop the data monitor
        self.monitor_active = False
        self.timer.stop()
        self.set_actions_enable_state()

        self.status_text.setText('Monitor idle')

    def on_start(self):

        #Start the data monitor
        self.data_q = Queue.Queue()
        self.monitor_active = True
        self.set_actions_enable_state()
        self.timer = QTimer()
        self.connect(self.timer, SIGNAL('timeout()'), self.on_timer)

        update_freq = self.updatespeed_knob.value()
        if update_freq > 0:
            self.timer.start(1000.0 / update_freq)

        self.status_text.setText('Monitor running')

    def on_timer(self):
        """ Executed periodically when the monitor update timer
            is fired.
        """
        self.ReadData()
        self.update_monitor()

    def on_knob_change(self):
        """ When the knob is rotated, it sets the update interval
            of the timer.
        """
        update_freq = self.updatespeed_knob.value()
        self.knob_l.setText('Update speed = %s (Hz)' %
                            self.updatespeed_knob.value())

        if self.timer.isActive():
            update_freq = max(0.01, update_freq)
            self.timer.setInterval(1000.0 / update_freq)

    def update_monitor(self):
        """ Updates the state of the monitor window with new 
            data. The livefeed is used to find out whether new
            data was received since the last update. If not, 
            nothing is updated.
        """
        if self.livefeed.has_new_data:
            data = self.livefeed.read_data()

            try:
                xdata = data[:, 0]
                ydata = data[:, 1]

                # scale axis automatically
                self.plot.setAxisScale(Qwt.QwtPlot.xBottom,
                                       xdata.min() * 0.9,
                                       xdata.max() * 1.1)
                self.plot.setAxisScale(Qwt.QwtPlot.yLeft,
                                       ydata.min() * 0.9,
                                       ydata.max() * 1.1)
                self.curve.setData(xdata, ydata)
                self.plot.replot()

            except:
                #print 'No data yet ...'
                test = 1  # just to do something, because otherwise error (ugly, but works ...)

    def ReadData(self):

        #Called periodically by the update timer to read data
        data = np.loadtxt(options.filename, delimiter='\t')
        self.livefeed.add_data(data)

    # The following two methods are utilities for simpler creation
    # and assignment of actions
    #
    def add_actions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(self,
                      text,
                      slot=None,
                      shortcut=None,
                      icon=None,
                      tip=None,
                      checkable=False,
                      signal="triggered()"):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        if checkable:
            action.setCheckable(True)
        return action