Esempio n. 1
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()