def startup_ping(ss, cmd): if cmd is None: trace("Ping Arduino") ss.write(sserial.ping()) return if sserial.is_ping(cmd) == True: trace("Arduino reply: %s"%(cmd.str())) return trace("Arduino ignore %s"%(cmd.str()))
def startup_xtest(ss, cmd): if cmd is None: trace("X test Arduino") ss.write(sserial.notSupported(ord('X'))) return if sserial.is_not_supported(cmd) == True: trace("Arduino reply: %s" % (cmd.str())) return trace("Arduino ignore %s" % (cmd.str()))
def startup_xtest(ss, cmd): if cmd is None: trace("X test Arduino") ss.write(sserial.notSupported(ord('X'))) return if sserial.is_not_supported(cmd) == True: trace("Arduino reply: %s"%(cmd.str())) return trace("Arduino ignore %s"%(cmd.str()))
def startup_ping(ss, cmd): if cmd is None: trace("Ping Arduino") ss.write(sserial.ping()) return if sserial.is_ping(cmd) == True: trace("Arduino reply: %s" % (cmd.str())) return trace("Arduino ignore %s" % (cmd.str()))
def detect(ss, cmd, temperature, humidity): if cmd is None: ss.write(sserial.queryTH()) return (0, 0) if sserial.is_resp_th(cmd) == True: t,h = cmd.arg1() if t != temperature or h != humidity: trace("Arduino Detect: (%d*C %d%%) => (%d*C %d%%)"%(temperature, humidity, t, h)) return (t, h) trace("Arduino ignore %s"%(cmd.str())) return (0, 0)
def detect(ss, cmd, temperature, humidity): if cmd is None: ss.write(sserial.queryTH()) return (0, 0) if sserial.is_resp_th(cmd) == True: t, h = cmd.arg1() if t != temperature or h != humidity: trace("Arduino Detect: (%d*C %d%%) => (%d*C %d%%)" % (temperature, humidity, t, h)) return (t, h) trace("Arduino ignore %s" % (cmd.str())) return (0, 0)
def __init__(self): super().__init__() self.setupUi(self) self.myserial = SimpleSerial() self.save_thread = Save_receive_thread() self.update_coms() self.data_comboBox.setCurrentText("8") self.receive_textBrowser.setStyleSheet("background-color: black;") self.receive_textBrowser.setTextColor(QColor(0, 255, 0)) #connect signal and slot self.open_pushButton.clicked.connect(self.open_serial) self.send_pushButton.clicked.connect(self.serial_send_data) self.receive_clear_pushButton.clicked.connect(self.clear_receive_area) self.send_clear_pushButton.clicked.connect(self.clear_send_area) self.com_comboBox.clicked.connect(self.update_coms)
def serve(ss, cmd, tt, te, tr, ht, he, hr, s, ot, oh): # process the events from Arduino. if cmd is not None: if sserial.is_not_supported(cmd) == True: trace("Ignore command %s"%(cmd.str())) return (s, ot, oh) elif sserial.is_unknown(cmd) == True: trace("Ignore command %s"%(cmd.str())) return (s, ot, oh) elif sserial.is_heater_closed(cmd) == True: trace("Arduino close the heater for warm enough.") return ('detect', ot, oh) if sserial.is_heater_opened(cmd) == True: trace("Arduino open heater ok, %d*C %d%%, target is %d*C"%(ot, oh, tt)) return (s, ot, oh) if sserial.is_fan_closed(cmd) == True: trace("Arduino close the fan for humidity ok.") return ('detect', ot, oh) if sserial.is_fan_opened(cmd) == True: trace("Arduino open fan ok, %d*C %d%%, target is %d%%"%(ot, oh, ht)) return (s, ot, oh) # use state machine to drive new event. if s == 'init': startup_ping(ss, cmd) return ('xtest', 0, 0) if s == 'xtest': startup_xtest(ss, cmd) return ('detect', 0, 0) if s == 'detect': (t, h) = detect(ss, cmd, ot, oh) if t == 0 and h == 0: return ('detect', ot, oh) if t < tt - tr: return ('heat', t, h) if h >= ht + hr: return ('fan', t, h) return ('detect', t, h) if s == 'heat': (t, h) = detect(ss, cmd, ot, oh) if t == 0 and h == 0: return ('heat', ot, oh) if t < tt: #trace("Notify Arduino to open heater.") ss.write(sserial.openHeater(tt, te)) return ('heat', t, h) trace("Warm enough, no need to heat, %d*C %d%%"%(t, h)) return ('detect', t, h) if s == 'fan': (t, h) = detect(ss, cmd, ot, oh) if t == 0 and h == 0: return ('fan', ot, oh) if h >= ht: #trace("Notify Arduino to open fan.") ss.write(sserial.openFan(ht, he)) return ('fan', t, h) trace("Humidity ok, no need to fan, %d*C %d%%"%(t, h)) return ('detect', t, h) return ('init', 0, 0)
# start heater when <=(target-trigger) # stop heater when overflow, texpire in seconds. (tt, te, tr, ht, he, hr, s, t, h) = ( 21, # tt, temperature target 30, # te, temperature expire 2, # tr, temperature trigger 75, # ht, humidity target 30, # he, humidity expire 15, # hr, humidity trigger 'init', # s, state 0, # t, temperature 0 # h, humifity ) ss = sserial.open("/dev/ttyUSB0", 115200) while True: try: cmd = None if s != 'init' and ss.available(3) == True: cmd = ss.read() if cmd is not None: if sserial.is_resp_th2(cmd): t2, h2 = cmd.arg1() report("space", { "temperature": t2, "humidity": h2}) continue # input and output the states. (s, t, h) = serve(ss, cmd, tt, te, tr, ht, he, hr, s, t, h)
def serve(ss, cmd, tt, te, tr, ht, he, hr, s, ot, oh): # process the events from Arduino. if cmd is not None: if sserial.is_not_supported(cmd) == True: trace("Ignore command %s" % (cmd.str())) return (s, ot, oh) elif sserial.is_unknown(cmd) == True: trace("Ignore command %s" % (cmd.str())) return (s, ot, oh) elif sserial.is_heater_closed(cmd) == True: trace("Arduino close the heater for warm enough.") return ('detect', ot, oh) if sserial.is_heater_opened(cmd) == True: trace("Arduino open heater ok, %d*C %d%%, target is %d*C" % (ot, oh, tt)) return (s, ot, oh) if sserial.is_fan_closed(cmd) == True: trace("Arduino close the fan for humidity ok.") return ('detect', ot, oh) if sserial.is_fan_opened(cmd) == True: trace("Arduino open fan ok, %d*C %d%%, target is %d%%" % (ot, oh, ht)) return (s, ot, oh) # use state machine to drive new event. if s == 'init': startup_ping(ss, cmd) return ('xtest', 0, 0) if s == 'xtest': startup_xtest(ss, cmd) return ('detect', 0, 0) if s == 'detect': (t, h) = detect(ss, cmd, ot, oh) if t == 0 and h == 0: return ('detect', ot, oh) if t < tt - tr: return ('heat', t, h) if h >= ht + hr: return ('fan', t, h) return ('detect', t, h) if s == 'heat': (t, h) = detect(ss, cmd, ot, oh) if t == 0 and h == 0: return ('heat', ot, oh) if t < tt: #trace("Notify Arduino to open heater.") ss.write(sserial.openHeater(tt, te)) return ('heat', t, h) trace("Warm enough, no need to heat, %d*C %d%%" % (t, h)) return ('detect', t, h) if s == 'fan': (t, h) = detect(ss, cmd, ot, oh) if t == 0 and h == 0: return ('fan', ot, oh) if h >= ht: #trace("Notify Arduino to open fan.") ss.write(sserial.openFan(ht, he)) return ('fan', t, h) trace("Humidity ok, no need to fan, %d*C %d%%" % (t, h)) return ('detect', t, h) return ('init', 0, 0)
# start heater when <=(target-trigger) # stop heater when overflow, texpire in seconds. (tt, te, tr, ht, he, hr, s, t, h) = ( 21, # tt, temperature target 30, # te, temperature expire 2, # tr, temperature trigger 75, # ht, humidity target 30, # he, humidity expire 15, # hr, humidity trigger 'init', # s, state 0, # t, temperature 0 # h, humifity ) ss = sserial.open("/dev/ttyUSB0", 115200) while True: try: cmd = None if s != 'init' and ss.available(3) == True: cmd = ss.read() if cmd is not None: if sserial.is_resp_th2(cmd): t2, h2 = cmd.arg1() report("space", {"temperature": t2, "humidity": h2}) continue # input and output the states. (s, t, h) = serve(ss, cmd, tt, te, tr, ht, he, hr, s, t, h)
class MyMainWindow(QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.myserial = SimpleSerial() self.save_thread = Save_receive_thread() self.update_coms() self.data_comboBox.setCurrentText("8") self.receive_textBrowser.setStyleSheet("background-color: black;") self.receive_textBrowser.setTextColor(QColor(0, 255, 0)) #connect signal and slot self.open_pushButton.clicked.connect(self.open_serial) self.send_pushButton.clicked.connect(self.serial_send_data) self.receive_clear_pushButton.clicked.connect(self.clear_receive_area) self.send_clear_pushButton.clicked.connect(self.clear_send_area) self.com_comboBox.clicked.connect(self.update_coms) def mousePressEvent(self, event): print("hhhhhhhhhh") def update_coms(self): self.coms = self.myserial.get_com_list() self.com_comboBox.clear() self.com_comboBox.addItems(self.coms) print(self.coms) def serial_send_data(self, data): if self.myserial.IS_OPEN == True: data_str = self.send_textEdit.toPlainText() if self.send_hex_checkBox.isChecked(): data_str = data_str.replace(" ", "") print(data_str) try: data_bytes = bytes.fromhex(data_str) except: QMessageBox.warning(self, "输入错误!", "请正确输入16进制数据!\n数字范围:0~f\n数字个数:偶数个", QMessageBox.Yes) print("hex error!") return else: try: data_bytes = bytes(data_str, encoding="ascii") except: try: data_bytes = bytes(data_str, encoding="gbk") except: print("send error!") if self.send_new_line_checkBox.isChecked(): data_bytes += b"\r\n" self.myserial.send(data_bytes) def clear_receive_area(self): self.receive_textBrowser.setText("") self.receive_data_len = 0 self.label_10.setText(str(self.receive_data_len)) def clear_send_area(self): self.send_textEdit.setText("") def update_receive_area(self, data): if (self.save_checkBox.isChecked()): self.save_thread.get_new_data(data) self.receive_data_len += len(data) if self.receive_hex_radioButton.isChecked(): str_data = "" for i in data: str_data += str("%02x" % i) + " " self.receive_textBrowser.append(str_data) else: try: self.receive_textBrowser.append(str(data, encoding="ascii")) except: try: self.receive_textBrowser.append(str(data, encoding="gbk")) except: str_data = "" for i in data: str_data += hex(i)[2:] + " " self.receive_textBrowser.append(str_data) self.label_10.setText(str(self.receive_data_len)) def update_com_paras(self): self.port = self.com_comboBox.currentText() self.baudrate = int(self.baudrate_comboBox.currentText()) self.parity = self.parity_comboBox.currentText() if self.parity == "无校验": self.parity = "N" elif self.parity == "奇校验": self.parity = "E" elif self.parity == "偶校验": self.parity = "O" else: print("parity error!: ", self.parity) self.stopbits = float(self.stopbit_comboBox.currentText()) self.bytesize = int(self.data_comboBox.currentText()) self.com_paras_dic = { "port": self.port, "baudrate": self.baudrate, "parity": self.parity, "stopbits": self.stopbits, "bytesize": self.bytesize } print(self.com_paras_dic) def open_serial(self): # print(self.open_pushButton.text()) print("open id: ", threading.current_thread().ident) if self.open_pushButton.text() == "打开串口": self.update_com_paras() self.myserial.open(**self.com_paras_dic) if self.myserial.IS_OPEN == True: self.com_comboBox.setEnabled(False) self.data_comboBox.setEnabled(False) self.stopbit_comboBox.setEnabled(False) self.parity_comboBox.setEnabled(False) self.baudrate_comboBox.setEnabled(False) self.receive_data_len = 0 self.serial_thread = Serial_receive_thread() self.serial_thread.start_receive_data(self.myserial) self.serial_thread.signal_have_data.connect( self.update_receive_area) self.serial_thread.signal_receive_error.connect( self.close_serial) self.open_pushButton.setText("关闭串口") self.statusBar().showMessage("串口打开成功!", 5000) else: self.statusBar().showMessage("串口打开失败!", 5000) else: self.close_serial() def close_serial(self): self.myserial.close() self.com_comboBox.setEnabled(True) self.data_comboBox.setEnabled(True) self.stopbit_comboBox.setEnabled(True) self.parity_comboBox.setEnabled(True) self.baudrate_comboBox.setEnabled(True) self.statusBar().showMessage("串口关闭成功!", 5000) self.open_pushButton.setText("打开串口")