#!/usr/bin/env python3 import threading import serial import queue from xmodem import XMODEM import io import wx class CliThread(threading.Thread): def __init__(self, parent, port, callback): threading.Thread.__init__(self) self.alive = threading.Event() self.q = queue.Queue(100) self.nodeSerial = serial.Serial(port=port, baudrate=9600) self.nodeSerial.write(b'\n') self.alive.set() self.char_callback = callback def close(self): self.alive.clear() self.nodeSerial.close() def command(self, cmd, response): self.q.put(response) self.nodeSerial.write(cmd) def getc(self, size, timeout=1): return self.nodeSerial.read(size) or None def putc(self,data, timeout=1): return self.nodeSerial.write(data) # note that this ignores the timeout def xmodem(self, lines): self.xmodemlines = [] for line in lines: line = line.replace("\n", "").replace("\r", "") self.xmodemlines.append(line + "\r\n") self.q.put(None) self.nodeSerial.write(b'xmodem\n') def run(self): """\ Thread that handles the incoming traffic. Does the basic input transformation (newlines) and generates an SerialRxEvent """ b = '' cmd = [] lines = '' while self.alive.isSet(): for c in self.nodeSerial.read(): c = chr(c) print(c, end='') if self.char_callback != None: wx.CallAfter(self.char_callback, c) b += c if b[0:3] == 'ch>': if (len(cmd) > 0): callback = self.q.get(block=False) if callback != None: wx.CallAfter(callback, lines) lines = [] cmd = [] if c == '\n': if len(cmd) > 0: lines.append(b) if b[0:3] == 'ch>': b = b.replace('\r', '').replace('\n','') cmd = b.split(' ')[1:] lines = [] if len(cmd) > 0: if cmd[0] == 'xmodem': modem = XMODEM(self.getc, self.putc) stream = io.BytesIO(bytes(''.join(self.xmodemlines), 'utf-8')) modem.send(stream) b = ''