# cPy - qt gui application communicating with Esp32 through USB
# Copyright by Anthony Vogelaar, Perth Scotland
# rev 0.10  2026-04-02  initial release

import  subprocess;         subprocess.run('clear')
import	time
from	serial	            import	Serial
from    PySide6.QtWidgets   import  (QApplication, QWidget, QTextEdit)
from    PySide6.QtGui       import  QTextCursor

# ============================ UsbSerial ===============================

class UsbSerial:
    
    def __init__(self, port='/dev/ttyUSB0', baud=115200):
        self.comm    = Serial(port=port, baudrate=baud, timeout=0, exclusive=True)
        self.buff_rx = b''
        
        
    # write string s <LF> terminated
    def writeLn(self, s):
        if s[-1] != '\n': s += '\n'
        self.comm.write(s.encode())
        
        
    # return received line as string or None
    def readLn(self):
        res = None
        while ch := self.comm.read():
            if ch == b'\r': continue
            if ch == b'\n':
                if self.buff_rx: 
                    res, self.buff_rx = self.buff_rx,b''
                    return res.decode()
            else: self.buff_rx += ch

# ============================= Qt GUI ===============================
#             
class Gui(QWidget):

    # GUI setup
    def __init__(self):
        self.app = QApplication()                       # Qt framework
        super().__init__()                              # instantiate QWidget = GUI
        self.resize(200, 200)
        self.memo = QTextEdit(self)
        self.memo.setGeometry(10, 10, 180, 180)
        self.memo.setReadOnly(True)
        self.memo.setStyleSheet('background-color: MediumAquamarine')
        self.show()


    # add string s to memo
    def memoAdd(self, s):
        txt = self.memo.toPlainText()
        if txt: txt += '\n'
        self.memo.setText(txt + s)
        self.memo.moveCursor(QTextCursor.End)


    # refresh Qt loop, call @ 20 Hz
    def refresh(self):
        self.app.processEvents()

# ============================= main ================================

# present string received from Esp32 on kit's LCD, Qt GUI and in Shell
def main():
    comm = UsbSerial()
    gui = Gui()
    while True:
        if s_rx := comm.readLn():
            gui.memoAdd(s_rx)                       # show s_rx in GUI
            comm.writeLn(s_rx)						# echo it to Esp32
            print(s_rx)                             # show s_rx in shell
        gui.refresh()                               # refresh Qt loop
        time.sleep(0.05)                            # 20 Hz loop
    
    
main()

# ============================== end ================================
