class MainWindow(QMainWindow): def __init__(self, test=Constants.test, parent=None): # UI init super(MainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.voltageTimer = QTimer() self.voltageTimer.start( Constants.updateRate) # update every 0.15 second self.guiTimer = QTimer() self.guiTimer.start(0) self.cm = plt.get_cmap('cool') self.alarm = Alarm(Constants.alarmParams, parent=self) self.judge = Judge(Constants.DATA_DIR) self.warning = Warning(parent=self) self.recorder = None self.setting = Setting(self.alarm.getInitialState()) self.time = None self.measure = None self.predict = {'predict': 1, 'cnt': 0, 'curr_predict': None} # check it is test mode or not (arduino don't need to connect) try: self.arduino = Arduino() except: print('using monk arduino') self.arduino = ArduinoTest() # Connection self.voltageTimer.timeout.connect(self.voltageUpdate) self.ui.actionRecord_Data.triggered.connect(self.recordData) self.ui.actionSetting.triggered.connect(self.showSetting) self.setting.finished.connect(self.settingClose) self.guiTimer.timeout.connect(self.guiUpdate) # ShortCut self.ui.actionRecord_Data.setShortcut("Ctrl+D") self.ui.actionSetting.setShortcut("Ctrl+S") # Check is there are the data valid or not self.judgeStatusCheck() # Show the main window self.show() # Show and locate the warning message manually self.warning.showWarning() def voltageUpdate(self): data = self.arduino.get_pressure() if data: self.time = str(datetime.datetime.now()) self.measure = data self.updatePosture() # record the data is data recorder is open if self.recorder is not None and self.recorder.recording: posture_id = self.recorder.ui.ComboClass.currentIndex() self.recorder.measure[posture_id].append( (self.time, self.measure)) def updatePosture(self): curr_predict = self.judge.predict(self.measure) if curr_predict == self.predict['curr_predict']: self.predict['cnt'] += 1 else: self.predict['curr_predict'] = curr_predict self.predict['cnt'] = 1 # update the predict only when it is greater than consecutive factor # to prevent the prediction change in a very short time if self.predict['cnt'] >= Constants.consecutiveFactor: self.predict['predict'] = self.predict['curr_predict'] # update the alarm status if self.predict['predict'] not in Constants.goodPosture: self.alarm.tick() else: self.alarm.reset() def recordData(self): self.recorder = DataRecorder(self) self.recorder.finished.connect(self.recordDataClose) def judgeStatusCheck(self): # Check the data is available or not only when it is not in testing mode # Show the data recorder window if there are no data if not Constants.test and self.judge.clf is None: QMessageBox.warning( self, 'warning', 'Please record some data to initialize the service') self.recordData() def recordDataClose(self, val): if val == 1: self.dumpStoringData() self.recorder.finished.disconnect(self.recordDataClose) self.recorder = None self.judge.initialize() self.judgeStatusCheck() def dumpStoringData(self): # dump the recording data when data recorder is done. (press ok) for class_id, data in self.recorder.measure.items(): filename = join(Constants.DATA_DIR, 'class' + str(class_id) + '.txt') with open(filename, 'w+') as file: for time, measure in data: txt = list(map(str, measure)) row = '\t'.join([time] + txt) file.write(row + '\n') def guiUpdate(self): # convert a list of float to 0 ~ 255 in stylesheet format def getFormatColor(raw_color): res = 'rgb(' res += ', '.join([str(int(i * 255)) for i in raw_color]) res += ')' return res # convert volt into color def getColorMap(volts, cm): res = [] for v in volts: color = cm(int(v / 5.15 * 255)) res.append(getFormatColor(color)) return res # update the pressure heatmap if self.measure is not None: colors = getColorMap(self.measure, self.cm) self.ui.bottomLeft.setStyleSheet('QWidget { background: %s }' % colors[0]) self.ui.bottomBack.setStyleSheet('QWidget { background: %s }' % colors[1]) self.ui.bottomRight.setStyleSheet('QWidget { background: %s }' % colors[2]) self.ui.backLeft.setStyleSheet('QWidget { background: %s }' % colors[3]) self.ui.backRight.setStyleSheet('QWidget { background: %s }' % colors[4]) self.ui.backDown.setStyleSheet('QWidget { background: %s }' % colors[5]) # update the posture image filename = str(Posture(self.predict['predict'])) + '.png' self.ui.imageHolder.setPixmap( QPixmap(join(Constants.IMG_DIR, filename))) self.ui.imageHolder.show() def showSetting(self): self.setting.initialize(self.alarm.getInitialState()) def settingClose(self, val): if val == 1: # When close the window with committing the change self.alarm.updateParams = self.setting.getSetting()