def read(self, timeout=2000, readLen=512): r""" read method reads existing data from the communication buffer arguments: timeout - optional communication timeout (default = 500ms) returns: sret - string with data read from the buffer """ resp = "" with self._connectionRLock: if self._dummyPlug is True: return "ok Q:0" try: self.write("") ret = self.ep_in.read(readLen, timeout) resp = ''.join([chr(x) for x in ret]) except usb.core.USBError as e: logger.error("USB read data exception: %s", str(e)) except Exception as ex: logger.error("Read error - Connection lost: " + str(ex)) return resp
def initSD(self): r""" initSD method inits Sd card """ if self.isTransferring(): logger.debug('File Transfer Thread active, please wait for transfer thread to end') return None with self._commandLock: # Init SD self._beeCon.write("M21\n") tries = 10 resp = "" while (tries > 0) and ("ok" not in resp.lower()): try: resp += self._beeCon.read() tries -= 1 except Exception as ex: logger.error("Error initializing SD Card: %s", str(ex)) return tries
def dispatch(self, message): r""" dispatch method writes data to the communication buffers and read existing data arguments: message - data to be writen returns: sret - string with data read from the buffer """ timeout = Conn.READ_TIMEOUT resp = "No response" with self._connectionLock: if self._dummyPlug is True: return "ok Q:0" try: time.sleep(0.009) self.ep_out.write(message) time.sleep(0.009) except usb.core.USBError as e: logger.error("USB dispatch (write) data exception: %s", str(e)) try: ret = self.ep_in.read(Conn.DEFAULT_READ_LENGTH, timeout) resp = ''.join([chr(x) for x in ret]) except usb.core.USBError as e: logger.error("USB dispatch (read) data exception: %s", str(e)) return resp
def write(self, message, timeout=500): r""" write method writes a message to the communication buffer arguments: message - data to be writen timeout - optional communication timeout (default = 500ms) returns: byteswriten - bytes writen to the buffer """ bytes_written = 0 with self._connectionRLock: if self._dummyPlug is True: return len(message) else: try: bytes_written = self.ep_out.write(message, timeout) except usb.core.USBError as e: logger.error("USB write data exception: %s", str(e)) except Exception as ex: logger.error("Write error - Connection lost: " + str(ex)) return bytes_written
def getNozzleTemperature(self): r""" getNozzleTemperature method reads current nozzle temperature returns: nozzle temperature """ if self.isTransferring(): logger.debug('File Transfer Thread active, please wait for transfer thread to end') return None with self._commandLock: # get Temperature resp = self._beeCon.sendCmd("M105\n") try: splits = resp.split(" ") tPos = splits[0].find("T:") t = float(splits[0][tPos+2:]) return t except Exception as ex: logger.error("Error getting nozzle temperature: %s", str(ex)) return 0
def transferSDFile(self, fileName, sdFileName=None): r""" transferSDFile method Transfers GCode file to printer internal memory """ if self.isTransferring(): logger.debug('File Transfer Thread active, please wait for transfer thread to end') return None if os.path.isfile(fileName) is False: logger.warning("Gcode Transfer: File does not exist") return logger.info("Transfer GCode File: %s" % fileName) try: with self._commandLock: self._beeCon.read() if sdFileName is not None: self._transfThread = transferThread.FileTransferThread(self._beeCon, fileName, 'gcode', sdFileName) else: self._transfThread = transferThread.FileTransferThread(self._beeCon, fileName, 'gcode') self._transfThread.start() except Exception as ex: logger.error("Error starting the print operation: %s", str(ex)) return False return
def close(self): r""" Closes active connection with printer """ if self.ep_out is not None: with self._connectionLock: try: # release the device usb.util.dispose_resources(self.dev) self.ep_out = None self.ep_in = None self.intf = None self.cfg = None #usb.util.release_interface(self.dev, self.intf) #not needed after dispose self.connected = False except usb.core.USBError as e: logger.error( "USB exception while closing connection to printer: %s", str(e)) except Exception as ex: logger.error("Close connection error - Connection lost: " + str(ex)) return
def sendBlockMsg(self, msg): r""" sendBlockMsg method sends a block message to the printer. arguments: msg - message to be writen returns: True if message transferred successfully False if an error occurred and communication was reestablished None if an error occurred and could not reestablish communication with printer """ #resp = self.beeCon.dispatch(msg) msgLen = len(msg) bWriten = self.beeCon.write(msg) if msgLen != bWriten: logger.info("Bytes lost") return False time.sleep(0.001) tries = 10 resp = "" while (tries > 0) and ("tog" not in resp): try: resp += self.beeCon.read() tries -= 1 except Exception as ex: logger.error(str(ex)) tries = -1 if tries > 0: return True else: cleaningTries = 5 clean = False self.transmissionErrors += 1 while cleaningTries > 0 and clean is False: beeCmd = self.beeCon.getCommandIntf() clean = beeCmd.cleanBuffer() time.sleep(0.5) self.beeCon.reconnect() cleaningTries -= 1 if cleaningTries <= 0: return None if clean is False: return None return False
def waitForStatus(self, cmd, s, timeout=None, possibleDisconnection=False): r""" waitForStatus method writes command to the printer and waits for status the response arguments: cmd - commmand to send s - string to be found in the response timeout - optional communication timeout (seconds) returns: resp - string with data read from the buffer """ c_time = time.time() resp = "" with self._connectionLock: if self._dummyPlug is True: return "ok Q:0 S:" + str(s) self.write(cmd) str2find = "S:" + str(s) while "ok" not in resp: resp += self.read() # Checks timeout if timeout is not None: e_time = time.time() if e_time - c_time > timeout: if possibleDisconnection: return break while str2find not in resp: try: self.write("M625\n") time.sleep(0.5) resp += self.read() except Exception as ex: logger.error("Exception while waiting for %s response: %s", str2find, str(ex)) return resp
def waitForStatus(self, cmd, s, timeout=None): r""" waitForStatus method writes command to the printer and waits for status the response arguments: cmd - commmand to send s - string to be found in the response timeout - optional communication timeout (seconds) returns: resp - string with data read from the buffer """ c_time = time.time() resp = "" with self._connectionLock: if self._dummyPlug is True: return "ok Q:0 S:" + str(s) self.write(cmd) str2find = "S:" + str(s) while "ok" not in resp: resp += self.read() # Checks timeout if timeout is not None: e_time = time.time() if e_time-c_time > timeout: break while str2find not in resp: try: self.write("M625\n") time.sleep(0.5) resp += self.read() except Exception as ex: logger.error("Exception while waiting for %s response: %s", str2find, str(ex)) return resp
def createFile(self, fileName): r""" createFile method Creates a file in the SD card root directory arguments: fileName - file name """ if self.isTransferring(): logger.debug('File Transfer Thread active, please wait for transfer thread to end') return None # Init SD self.initSD() with self._commandLock: fn = fileName if len(fileName) > 8: fn = fileName[:8] cmdStr = "M30 " + fn + "\n" resp = self._beeCon.sendCmd(cmdStr) tries = 10 while tries > 0: if "file created" in resp.lower(): logger.info("SD file created") break elif "error" in resp.lower(): logger.error("Error creating file") return False else: resp = self._beeCon.sendCmd("\n") logger.debug("Create file in SD: " + resp) tries -= 1 if tries <= 0: return False return True
def close(self): r""" Closes active connection with printer """ if self.ep_out is not None: with self._connectionLock: try: # release the device usb.util.dispose_resources(self.dev) self.ep_out = None self.ep_in = None self.intf = None self.cfg = None #usb.util.release_interface(self.dev, self.intf) #not needed after dispose self.connected = False except usb.core.USBError as e: logger.error("USB exception while closing connection to printer: %s", str(e)) except Exception as ex: logger.error("Close connection error - Connection lost: " + str(ex)) return
def cleanBuffer(self): r""" cleanBuffer method Cleans communication buffer and establishes communications """ if self.isTransferring(): logger.debug('File Transfer Thread active, please wait for transfer thread to end') return None with self._commandLock: logger.debug("Cleaning") cleanStr = 'M625;' + 'a'*(self.MESSAGE_SIZE-6) + '\n' self._beeCon.write(cleanStr, 50) tries = self.BLOCK_SIZE + 1 resp = self._beeCon.read() acc_resp = "" while "ok" not in acc_resp.lower() and tries > 0: try: self._beeCon.write(cleanStr) resp = self._beeCon.read() acc_resp += resp #print(resp) tries -= 1 except Exception as ex: logger.error("Read timeout %s", str(ex)) tries = 0 #print(resp) return tries
def dispatch(self, message): r""" dispatch method writes data to the communication buffers and read existing data arguments: message - data to be writen returns: sret - string with data read from the buffer """ timeout = Conn.READ_TIMEOUT resp = "No response" with self._connectionLock: if self._dummyPlug is True: return "ok Q:0" try: time.sleep(0.009) self.ep_out.write(message) time.sleep(0.009) except usb.core.USBError as e: logger.error("USB dispatch (write) data exception: %s", str(e)) except Exception as ex: logger.error("Dispatch write error - Connection lost: " + str(ex)) try: ret = self.ep_in.read(Conn.DEFAULT_READ_LENGTH, timeout) resp = ''.join([chr(x) for x in ret]) except usb.core.USBError as e: logger.error("USB dispatch (read) data exception: %s", str(e)) except Exception as ex: logger.error("Dispatch read error - Connection lost: " + str(ex)) return resp
def printFile(self, filePath, printTemperature=200, sdFileName=None): r""" printFile method Transfers a file to the printer and starts printing returns True if print starts successfully """ if self.isTransferring(): logger.error('File Transfer Thread active, please wait for transfer thread to end') return False # check if file exists if os.path.isfile(filePath) is False: logger.error("transferGCode: File does not exist") return False try: if self.getPrinterMode() == 'Bootloader': self.goToFirmware() if printTemperature is not None: #self.home() self.startHeating(printTemperature+5) time.sleep(1) with self._commandLock: self._beeCon.read() self._transfThread = transferThread.FileTransferThread( self._beeCon, filePath, 'print', sdFileName, printTemperature) self._transfThread.start() except Exception as ex: logger.error("Error starting the print operation: %s", str(ex)) return False return True
def transferFirmwareFile(self): r""" transferFirmwareFile method Transfers Firmware File to printer """ cTime = time.time() # Get current time message = "M650 A" + str( self.fileSize) + "\n" # Prepare Start Transfer Command string self.beeCon.write(message) # Send Start Transfer Command # Before continue wait for the reply from the Start Command transfer resp = '' while 'ok' not in resp: # Once the printer is ready it replies 'ok' resp += self.beeCon.read() resp = '' with open(self.filePath, 'rb') as f: # Open file to start transfer while True: # while loop buf = f.read(64) # Read 64 bytes from file if not buf: break # if nothing left to read, transfer finished bytesWriten = self.beeCon.write( buf) # Send 64 bytes to the printer #time.sleep(0.0000001) # Small delay helps remove sporadic errors time.sleep(0.001) # The printer will forward the received data # we then collect the received data and compare it to identify transfer errors ret = [] while len(ret) != len( buf): # wait for the 64 bytes to be received try: ret += self.beeCon.ep_in.read(len(buf), 1000) except usb.core.USBError as e: if "timed out" in str(e.args): pass bRet = bytearray(ret) # convert the received data to bytes if not bRet == buf: # Compare the data received with data sent # If data received/sent are different cancel transfer and reset the printer manually logger.error( 'Firmware Flash error, please reset the printer') return #sys.stdout.write('.') # print dot to console #sys.stdout.flush() # used only to provide a simple indication as the process in running self.bytesTransferred += len(buf) eTime = time.time() avgSpeed = self.fileSize // (eTime - cTime) logger.info("Flashing completed in %d seconds", eTime - cTime) logger.info("Average Transfer Speed %.2f bytes/second", avgSpeed) self.bytesTransferred = 0 self.fileSize = 0 return True
def transferFirmwareFile(self): r""" transferFirmwareFile method Transfers Firmware File to printer """ cTime = time.time() # Get current time message = "M650 A" + str(self.fileSize) + "\n" # Prepare Start Transfer Command string self.beeCon.write(message) # Send Start Transfer Command # Before continue wait for the reply from the Start Command transfer resp = '' while 'ok' not in resp: # Once the printer is ready it replies 'ok' resp += self.beeCon.read() resp = '' with open(self.filePath, 'rb') as f: # Open file to start transfer while True: # while loop buf = f.read(64) # Read 64 bytes from file if not buf: break # if nothing left to read, transfer finished bytesWriten = self.beeCon.write(buf) # Send 64 bytes to the printer #time.sleep(0.0000001) # Small delay helps remove sporadic errors time.sleep(0.001) # The printer will forward the received data # we then collect the received data and compare it to identify transfer errors ret = [] while len(ret) != len(buf): # wait for the 64 bytes to be received try: ret += self.beeCon.ep_in.read(len(buf), 1000) except usb.core.USBError as e: if "timed out" in str(e.args): pass bRet = bytearray(ret) # convert the received data to bytes if not bRet == buf: # Compare the data received with data sent # If data received/sent are different cancel transfer and reset the printer manually logger.error('Firmware Flash error, please reset the printer') return #sys.stdout.write('.') # print dot to console #sys.stdout.flush() # used only to provide a simple indication as the process in running self.bytesTransferred += len(buf) eTime = time.time() avgSpeed = self.fileSize//(eTime - cTime) logger.info("Flashing completed in %d seconds", eTime-cTime) logger.info("Average Transfer Speed %.2f bytes/second", avgSpeed) self.bytesTransferred = 0 self.fileSize = 0 return True