import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import QThread, pyqtSlot
from PyQt5.QtCore import pyqtSignal as Signal
from PyQt5 import uic
from serial import Serial, SerialException
from threading import Thread


# Load the UI file using loadUiType
UiClass, BaseClass = uic.loadUiType("C:\\Users\\zktmt\\Desktop\\digital_circuit\\src\\week9\\mortor.ui")

class WindowClass(QMainWindow, UiClass):
    def __init__(self):
        super().__init__()
        self.setupUi(self)  # setupUi method comes from UiClass
       
        self.dev = None
        self.receiver = Receiver(self)

        # Connect signals to slots
        self.pushButton_Open.clicked.connect(self.openFunction)
        self.pushButton_Clear.clicked.connect(self.clearFunction)
        self.push_Close.clicked.connect(self.closeFunction)
        self.pushButton_Set.clicked.connect(self.setFunction)
        self.pushButton_Reset.clicked.connect(self.resetFunction)
        self.receiver.rx_data.connect(self.rx_data_append)

    @pyqtSlot()        
    def clearFunction(self):
        self.textEdit.clear()

    @pyqtSlot()
    def openFunction(self):
        current_port = self.comboPort.currentText()
        current_baudrate = int(self.comboBox_Baudrate.currentText())

        if self.dev is None or not self.dev.isOpen():
            try:
                self.dev = Serial(current_port, current_baudrate)
                self.textEdit.append("Device opened")
            except SerialException as e:
                self.textEdit.append(f"Failed to open the device: {e}")
        else:
            self.textEdit.append("Device already opened")


    @pyqtSlot()
    def closeFunction(self):
        if self.dev:
            if self.dev.is_open:
                self.dev.close()
                self.dev = None
                self.textEdit.append("Device closed")
            else:
                self.textEdit.append("Already closed")
        else:
            self.textEdit.append("Already closed")
    
    @pyqtSlot()
    def setFunction(self,value):
        current_velocity = int(self.comboBox_Velocity.currentText())
        current_direction = (self.comboBox_Direction.currentText())
        a=current_direction = (self.comboBox_Direction.currentText())
        time_setting=(self.comboBox_Time.currentText())
        b=(self.comboBox_Time.currentText())
        self.receiver = Receiver(self)

        if current_direction =="정방향":
            current_direction = int(8)
        elif current_direction == "역방향":
            current_direction = int(9)



        if time_setting =='세팅x':
            time_setting =int(10)
        elif time_setting =='5초':
            time_setting =int(11)
        elif time_setting =='10초':
            time_setting =int(12)
        elif time_setting =='15초':
            time_setting =int(13)


        if self.dev:
            try:
                sender = Sender(self.dev, current_velocity,current_direction,time_setting)
                sender.start()
                self.textEdit.append("SET")
                self.textEdit.append(f"Velocity:{current_velocity}  Direction:{a}  Time setting:{b} ")
            except Exception as e:
                self.textEdit.append(f"Failed to set: {e}")

        if value==254:
            self.textEdit.append("작동 중지")
        else:
            self.textEdit.append("작동 중")


    @pyqtSlot()
    def resetFunction(self):
        current_velocity = int(0)
        current_direction = int(0)
        time_setting=int(0)
        if self.dev:
            try:
                sender = Sender(self.dev, current_velocity,current_direction,time_setting)
                sender.start()
                self.textEdit.append("STOP")
            except Exception as e:

                self.textEdit.append(f"Failed to set: {e}")
    @pyqtSlot(bytes)
    def rx_data_append(self, r_data):
        value=int.from_bytes(r_data)
        self.setFunction(value)

class Sender(Thread):
    
    def __init__(self, dev, velocity=None,direction=None, time=None):
        super().__init__()
        self.dev = dev
        self.velocity = velocity
        self.direction = direction
        self.time=time

    def run(self):
        if self.dev is not None:
            try:
                data = bytes([self.velocity]) if self.velocity is not None else b''
                data2 = bytes([self.direction]) if self.direction is not None else b''
                data3 = bytes([self.time]) if self.time is not None else b''
                
                self.dev.write(data)
                self.dev.write(data2)
                self.dev.write(data3)
                print(data,data2,data3)
                
            except SerialException as e:
                print(f"Error writing to serial port: {e}")
                return
        else:
            print("Device not initialized")





class Receiver(QThread):
    rx_data = Signal(bytes)

    def __init__(self, parent=None):
        super(Receiver, self).__init__(parent)
        self.serial_monitor = parent
        self.is_running = True

    def run(self):
        while self.is_running:
            try:
                data4 = self.serial_monitor.dev.read(1)
                if data4:
                    self.rx_data.emit(bytes(data4))
            except SerialException as e:
                print(f"Error reading from serial: {e}")
                break

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWindow = WindowClass()
    mainWindow.show()
    sys.exit(app.exec_()) 시리얼통신으로부터 254라는 숫자를 받으면 텍스트창에 "동작 중지"라는 메세지를 출력하고 싶어. TypeError: WindowClass.setFunction() missing 1 required positional argument: 'value'라는 오류가 발생해