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 connectToPrinter(self, selectedPrinter): r""" connectToPrinter method Establishes Connection to selected printer returns False if connection fails """ if self._dummyPlug is True: self.connected = True return True self.connectedPrinter = selectedPrinter logger.info('\n...Connecting to %s with serial number %s', str(selectedPrinter['Product']), str(selectedPrinter['Serial Number'])) self.ep_out = self.connectedPrinter['Interfaces'][0]['EP Out'] self.ep_in = self.connectedPrinter['Interfaces'][0]['EP In'] # Verify that the end points exist assert self.ep_out is not None assert self.ep_in is not None self.dev = self.ep_out.device self.dev.set_configuration() self.dev.reset() time.sleep(0.5) #self.dev.set_configuration() self.cfg = self.dev.get_active_configuration() self.intf = self.cfg[(0, 0)] self.connected = True return True
def flashFirmware(self, fileName, firmwareString='20.0.0'): r""" flashFirmware method Flash new firmware """ if self.isTransferring(): logger.debug('File Transfer Thread active, please wait for transfer thread to end') return None """ if ('linux' or 'darwin') in platform.system().lower(): fileName = fileName.translate(None,''.join("'")) elif ('win32' or 'cygwin') in platform.system().lower(): fileName = fileName.translate(None,''.join('"'))\ """ if os.path.isfile(fileName) is False: logger.warning("Flash firmware: File does not exist") return logger.info("Flashing new firmware File: %s", fileName) self.setFirmwareString('0.0.0') # Clear FW Version self._transfThread = transferThread.FileTransferThread(self._beeCon, fileName, 'Firmware', firmwareString) self._transfThread.start() return
def connectToPrinter(self, selectedPrinter): r""" connectToPrinter method Establishes Connection to selected printer returns False if connection fails """ self.connectedPrinter = selectedPrinter logger.info('\n...Connecting to %s with serial number %s', str(selectedPrinter['Product']), str(selectedPrinter['Serial Number'])) if self._dummyPlug is True: self.connected = True return True self.ep_out = self.connectedPrinter['Interfaces'][0]['EP Out'] self.ep_in = self.connectedPrinter['Interfaces'][0]['EP In'] # Verify that the end points exist assert self.ep_out is not None assert self.ep_in is not None self.dev = self.ep_out.device self.dev.set_configuration() self.dev.reset() time.sleep(0.5) #self.dev.set_configuration() self.cfg = self.dev.get_active_configuration() self.intf = self.cfg[(0, 0)] self.connected = True return True
def stop(self): self._stopLog = True logger.info('Cancelling log thread') 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 getTransferCompletionState(self): r""" getTransferCompletionState method Returns current transfer completion percentage """ if self._transfThread.isAlive(): p = self._transfThread.getTransferCompletionState() logger.info("Transfer State: %s" % str(p)) return p return None
def getStatus(self): r""" getStatus method returns the current status of the printer """ mode = self.getPrinterMode() if mode == 'Bootloader': logger.info('Printer in Bootloader mode') return 'Bootloader' if mode is None or (mode != 'Firmware' and mode != 'Bootloader'): logger.warning('GetStatus: can only get status in firmware') return None if self.isTransferring(): logger.debug('File Transfer Thread active, please wait for transfer thread to end') return None resp = '' status = '' done = False with self._commandLock: while not done: while 's:' not in resp.lower(): resp += self._beeCon.sendCmd("M625\n") time.sleep(1) if 's:3' in resp.lower(): status = 'Ready' done = True elif 's:4' in resp.lower(): status = 'Moving' done = True elif 's:5' in resp.lower(): status = 'SD_Print' done = True elif 's:6' in resp.lower(): status = 'Transfer' done = True elif 's:7' in resp.lower() or 'pause' in resp.lower(): status = 'Pause' self._paused = True done = True elif 's:9' in resp.lower() or '_shutdown' in resp.lower(): status = 'Shutdown' self._shutdown = True done = True return status
def run(self): super(LogThread, self).run() ######################### # Temperature Log ######################### if self._logJog == 'TemperatureLog': self._logFile = open(self._logFileName,'w') #self._logFile.write("T,B\n") self._logFile.close() self._logFile = open(self._logFileName,"a") if self._samples > 0: self.finiteTemperatureLog() else: self.continuousTemperatureLog() self._logFile.close() self.beeCon.sendCmd("M300\n") self.beeCon.sendCmd("M300\n") ######################### # Print Log ######################### elif self._logJog == 'PrintLog': self._logFile = open(self._logFileName,'w') #logFile.write("Time,Current T,Target T,PWM Output,kp,ki,kd,pterm,iterm,dterm,Block T,Block Vent,Blower,Z\n") self._logFile.close() self._logFile = open(self._logFileName,"a") self.printingLog() self._logFile.close() ######################### # Printer Status Log ######################### elif self._logJog == 'StatusLog': self._logFile = open(self._logFileName,'w') #logFile.write("Time,Current T,Target T,PWM Output,kp,ki,kd,pterm,iterm,dterm,Block T,Block Vent,Blower,Z\n") self._logFile.close() self._logFile = open(self._logFileName,"a") if self._samples > 0: self.finiteStatusLog() else: self.continuousStatusLog() self._logFile.close() logger.info('Exiting log thread') return
def run(self): super(LogThread, self).run() ######################### # Temperature Log ######################### if self._logJog == 'TemperatureLog': self._logFile = open(self._logFileName, 'w') #self._logFile.write("T,B\n") self._logFile.close() self._logFile = open(self._logFileName, "a") if self._samples > 0: self.finiteTemperatureLog() else: self.continuousTemperatureLog() self._logFile.close() self.beeCon.sendCmd("M300\n") self.beeCon.sendCmd("M300\n") ######################### # Print Log ######################### elif self._logJog == 'PrintLog': self._logFile = open(self._logFileName, 'w') #logFile.write("Time,Current T,Target T,PWM Output,kp,ki,kd,pterm,iterm,dterm,Block T,Block Vent,Blower,Z\n") self._logFile.close() self._logFile = open(self._logFileName, "a") self.printingLog() self._logFile.close() ######################### # Printer Status Log ######################### elif self._logJog == 'StatusLog': self._logFile = open(self._logFileName, 'w') #logFile.write("Time,Current T,Target T,PWM Output,kp,ki,kd,pterm,iterm,dterm,Block T,Block Vent,Blower,Z\n") self._logFile.close() self._logFile = open(self._logFileName, "a") if self._samples > 0: self.finiteStatusLog() else: self.continuousStatusLog() self._logFile.close() logger.info('Exiting log thread') return
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 continuousStatusLog(self): logger.info("Starting loging Status to {} at {} records per second".format(self._logFileName,self._freq)) self._t = 0 while not self._stopLog: reply = self.beeCon.sendCmd("M1029\n") parsedLine = parsers.parseLogReply(reply,self._printer) if parsedLine is not None: self._logFile.write("{},{}".format(self._t, parsedLine)) if not self._hideLog: logger.info(parsedLine) time.sleep(self._freq) self._t += self._freq return
def continuousStatusLog(self): logger.info( "Starting loging Status to {} at {} records per second".format( self._logFileName, self._freq)) self._t = 0 while not self._stopLog: reply = self.beeCon.sendCmd("M1029\n") parsedLine = parsers.parseLogReply(reply, self._printer) if parsedLine is not None: self._logFile.write("{},{}".format(self._t, parsedLine)) if not self._hideLog: logger.info(parsedLine) time.sleep(self._freq) self._t += self._freq return
def finiteStatusLog(self): logger.info("Starting loging Status {} samples to {} at {} records per second".format(self._samples,self._logFileName,self._freq)) self._t = 0 for i in range(0,self._samples): reply = self.beeCon.sendCmd("M1029\n") parsedLine = parsers.parseLogReply(reply,self._printer) if parsedLine is not None: self._logFile.write("{},{}".format(self._t, parsedLine)) if not self._hideLog: logger.info("{}/{} {}".format(i,self._samples,parsedLine)) if self._stopLog: break time.sleep(self._freq) self._t += self._freq return
def goToBootloader(self): r""" goToBootloader method Resets the printer to Bootloader """ if self.isTransferring(): logger.debug('File Transfer Thread active, please wait for transfer thread to end') return None if self._beeCon.transfering: logger.info('File transfer in progress... Can not change to Bootloader\n') return None logger.info('Changing to Bootloader...\n') mode = self.getPrinterMode() if mode == 'Bootloader': logger.info('Printer Already in Bootloader\n') return False with self._commandLock: self._beeCon.sendCmd('M609\n') self._beeCon.reconnect() mode = self.getPrinterMode() return mode
def printingLog(self): beeCmd = self.beeCon.getCommandIntf() while beeCmd.getStatus() is None: logger.info("Waiting for print to start") time.sleep(self._freq) logger.info( "Starting loging temperatures during print to {} at {} records per second" .format(self._logFileName, self._freq)) self._stopLog = False self._t = 0 i = 0 while not self._stopLog: st = beeCmd.getStatus() if st is not None: if 'SD_Print' not in st: self._stopLog = True reply = beeCmd.sendCmd("M1029\n") parsedLine = parsers.parseLogReply(reply) if parsedLine is not None: i = i + 1 self._logFile.write("{},{}".format(self._t, parsedLine)) if not self._hideLog: logger.info("{}: {}".format(i, parsedLine)) time.sleep(self._freq) self._t += self._freq return
def printingLog(self): beeCmd = self.beeCon.getCommandIntf() while beeCmd.getStatus() is None: logger.info("Waiting for print to start") time.sleep(self._freq) logger.info("Starting loging temperatures during print to {} at {} records per second".format(self._logFileName,self._freq)) self._stopLog = False self._t = 0 i = 0 while not self._stopLog: st = beeCmd.getStatus() if st is not None: if 'SD_Print' not in st: self._stopLog = True reply = beeCmd.sendCmd("M1029\n") parsedLine = parsers.parseLogReply(reply) if parsedLine is not None: i = i + 1 self._logFile.write("{},{}".format(self._t,parsedLine)) if not self._hideLog: logger.info("{}: {}".format(i,parsedLine)) time.sleep(self._freq) self._t += self._freq return
def waitForHeatingAndPrint(self, temperature): r""" waitForHeatingAndPrint method Waits for setpoint temperature and starts printing the transferred file """ # Get commands interface beeCmd = self.beeCon.getCommandIntf() while beeCmd.getNozzleTemperature() < temperature: time.sleep(1) if self.cancelTransfer: beeCmd.cancelHeating() self.cancelTransfer = False return sdFileName = 'ABCDE' # If a different SD Filename is provided if self.optionalString is not None: sdFileName = self.optionalString # REMOVE SPECIAL CHARS sdFileName = re.sub('[\W_]+', '', sdFileName) # CHECK FILENAME if len(sdFileName) > 8: sdFileName = sdFileName[:7] firstChar = sdFileName[0] if firstChar.isdigit(): nameChars = list(sdFileName) nameChars[0] = 'a' sdFileName = "".join(nameChars) logger.info('Heating Done... Beginning print\n') self.beeCon.sendCmd('M33 %s\n' % sdFileName) return
def finiteStatusLog(self): logger.info( "Starting loging Status {} samples to {} at {} records per second". format(self._samples, self._logFileName, self._freq)) self._t = 0 for i in range(0, self._samples): reply = self.beeCon.sendCmd("M1029\n") parsedLine = parsers.parseLogReply(reply, self._printer) if parsedLine is not None: self._logFile.write("{},{}".format(self._t, parsedLine)) if not self._hideLog: logger.info("{}/{} {}".format(i, self._samples, parsedLine)) if self._stopLog: break time.sleep(self._freq) self._t += self._freq return
def parseLogReply(replyLine,printer='BEETHEFIRST PLUS'): logLine = None if ('\n' in replyLine): replyLines = replyLine.split('ok Q:') re1 = '.*?' # Non-greedy match on filler re2 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 1 re3 = '.*?' # Non-greedy match on filler re4 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 2 re5 = '.*?' # Non-greedy match on filler re6 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 3 re7 = '.*?' # Non-greedy match on filler re8 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 4 re9 = '.*?' # Non-greedy match on filler re10 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 5 re11 = '.*?' # Non-greedy match on filler re12 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 6 re13 = '.*?' # Non-greedy match on filler re14 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 7 re15 = '.*?' # Non-greedy match on filler re16 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 8 re17 = '.*?' # Non-greedy match on filler re18 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 9 re19 = '.*?' # Non-greedy match on filler re20 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 10 re21 = '.*?' # Non-greedy match on filler re22 = '(\\d+)' # Integer Number 1 if printer == 'BEETHEFIRST PLUS': re23 = '.*?' # Non-greedy match on filler re24 = '(\\d+)' # Integer Number 2 re25 = '.*?' # Non-greedy match on filler re26 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 11 rg = re.compile( re1 + re2 + re3 + re4 + re5 + re6 + re7 + re8 + re9 + re10 + re11 + re12 + re13 + re14 + re15 + re16 + re17 + re18 + re19 + re20 + re21 + re22 + re23 + re24 + re25 + re26, re.IGNORECASE | re.DOTALL) elif printer == 'BEETHEFIRST': re23 = '.*?' # Non-greedy match on filler re24 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 11 rg = re.compile( re1 + re2 + re3 + re4 + re5 + re6 + re7 + re8 + re9 + re10 + re11 + re12 + re13 + re14 + re15 + re16 + re17 + re18 + re19 + re20 + re21 + re22 + re23 + re24, re.IGNORECASE | re.DOTALL) else: logger.info('Unknown Printer') m = rg.search(replyLines[0]) # m = rg.search(reply) if m: float1 = m.group(1) float2 = m.group(2) float3 = m.group(3) float4 = m.group(4) float5 = m.group(5) float6 = m.group(6) float7 = m.group(7) float8 = m.group(8) float9 = m.group(9) float10 = m.group(10) int1 = m.group(11) if printer == 'BEETHEFIRST PLUS': int2 = m.group(12) float11 = m.group(13) logLine = "{},{},{},{},{},{},{},{},{},{},{},{},{}\n".format(float1, float2, float3, float4, float5, float6, float7, float8, float9, float10, int1, int2, float11) elif printer == 'BEETHEFIRST': float11 = m.group(12) logLine = "{},{},{},{},{},{},{},{},{},{},{},{}\n".format(float1, float2, float3, float4, float5, float6, float7, float8, float9, float10, int1, float11) return logLine
def multiBlockFileTransfer(self): r""" multiBlockFileTransfer method Transfers Gcode File using multi block transfers """ # Get commands interface beeCmd = self.beeCon.getCommandIntf() # Create File beeCmd.initSD() sdFileName = "ABCDE" # If a different SD Filename is provided if self.optionalString is not None: sdFileName = self.optionalString # REMOVE SPECIAL CHARS sdFileName = re.sub('[\W_]+', '', sdFileName) # CHECK FILENAME if len(sdFileName) > 8: sdFileName = sdFileName[:7] firstChar = sdFileName[0] if firstChar.isdigit(): nameChars = list(sdFileName) nameChars[0] = 'a' sdFileName = "".join(nameChars) # Get Number of blocks to transfer blockBytes = beeCmd.MESSAGE_SIZE * beeCmd.BLOCK_SIZE nBlocks = int(math.ceil(float(self.fileSize) / float(blockBytes))) logger.info("Number of Blocks: %d", nBlocks) # CREATE SD FILE resp = beeCmd.createFile(sdFileName) if not resp: return # Start transfer blocksTransferred = 0 self.bytesTransferred = 0 startTime = time.time() # Load local file with open(self.filePath, 'rb') as f: beeCmd.transmissionErrors = 0 while blocksTransferred < nBlocks and not self.cancelTransfer: startPos = self.bytesTransferred #endPos = self.bytesTransferred + blockBytes #bytes2write = endPos - startPos #if blocksTransferred == (nBlocks-1): # endPos = self.fileSize blockTransferred = False while blockTransferred is False: blockBytesTransferred = self.sendBlock(startPos, f) if blockBytesTransferred is None: logger.info("transferGFile: Transfer aborted") return False else: blockTransferred = True self.bytesTransferred += blockBytesTransferred blocksTransferred += 1 #logger.info("transferGFile: Transferred %s / %s blocks %d / %d bytes", # str(blocksTransferred), str(nBlocks), endPos, self.fileSize) if self.cancelTransfer: logger.info('multiBlockFileTransfer: File Transfer canceled') logger.info('multiBlockFileTransfer: %s / %s bytes transferred', str(self.bytesTransferred), str(self.fileSize)) self.transferring = False beeCmd.cancelHeating() #self.cancelTransfer = False return logger.info( "multiBlockFileTransfer: Transfer completed. Errors Resolved: %s", str(beeCmd.transmissionErrors)) elapsedTime = time.time() - startTime avgSpeed = self.fileSize // elapsedTime logger.info("multiBlockFileTransfer: Elapsed time: %d seconds", elapsedTime) logger.info( "multiBlockFileTransfer: Average Transfer Speed: %.2f bytes/second", avgSpeed) return
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 run(self): super(FileTransferThread, self).run() if self.transferType.lower() == 'firmware': self.transferring = True logger.info('Starting Firmware Transfer') self.transferFirmwareFile() # Update Firmware String self.beeCon.sendCmd('M114 A%s' % self.optionalString, 'ok') self.transferring = False elif self.transferType.lower() == 'gcode': self.transferring = True logger.info('Starting GCode Transfer') self.multiBlockFileTransfer() self.transferring = False elif self.transferType.lower() == 'print': self.transferring = True self.beeCon.setMonitorConnection(False) logger.info('Starting GCode Transfer') self.multiBlockFileTransfer() logger.info('File Transfer Finished... Heating...\n') self.beeCon.setMonitorConnection(True) self.transferring = False if not self.cancelTransfer: self.waitForHeatingAndPrint(self.temperature) self.heating = False else: logger.info('Unknown Transfer Type') logger.info('Exiting transfer thread') return
def multiBlockFileTransfer(self): r""" multiBlockFileTransfer method Transfers Gcode File using multi block transfers """ # Get commands interface beeCmd = self.beeCon.getCommandIntf() # Create File beeCmd.initSD() sdFileName = "ABCDE" # If a different SD Filename is provided if self.optionalString is not None: sdFileName = self.optionalString # REMOVE SPECIAL CHARS sdFileName = re.sub('[\W_]+', '', sdFileName) # CHECK FILENAME if len(sdFileName) > 8: sdFileName = sdFileName[:7] firstChar = sdFileName[0] if firstChar.isdigit(): nameChars = list(sdFileName) nameChars[0] = 'a' sdFileName = "".join(nameChars) # Get Number of blocks to transfer blockBytes = beeCmd.MESSAGE_SIZE * beeCmd.BLOCK_SIZE nBlocks = int(math.ceil(float(self.fileSize)/float(blockBytes))) logger.info("Number of Blocks: %d", nBlocks) # CREATE SD FILE resp = beeCmd.createFile(sdFileName) if not resp: return # Start transfer blocksTransferred = 0 self.bytesTransferred = 0 startTime = time.time() # Load local file with open(self.filePath, 'rb') as f: beeCmd.transmissionErrors = 0 while blocksTransferred < nBlocks and not self.cancelTransfer: startPos = self.bytesTransferred #endPos = self.bytesTransferred + blockBytes #bytes2write = endPos - startPos #if blocksTransferred == (nBlocks-1): # endPos = self.fileSize blockTransferred = False while blockTransferred is False: blockBytesTransferred = self.sendBlock(startPos, f) if blockBytesTransferred is None: logger.info("transferGFile: Transfer aborted") return False else: blockTransferred = True self.bytesTransferred += blockBytesTransferred blocksTransferred += 1 #logger.info("transferGFile: Transferred %s / %s blocks %d / %d bytes", # str(blocksTransferred), str(nBlocks), endPos, self.fileSize) if self.cancelTransfer: logger.info('multiBlockFileTransfer: File Transfer canceled') logger.info('multiBlockFileTransfer: %s / %s bytes transferred', str(self.bytesTransferred),str(self.fileSize)) self.transferring = False beeCmd.cancelHeating() #self.cancelTransfer = False return logger.info("multiBlockFileTransfer: Transfer completed. Errors Resolved: %s", str(beeCmd.transmissionErrors)) elapsedTime = time.time() - startTime avgSpeed = self.fileSize//elapsedTime logger.info("multiBlockFileTransfer: Elapsed time: %d seconds", elapsedTime) logger.info("multiBlockFileTransfer: Average Transfer Speed: %.2f bytes/second", avgSpeed) return
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 parseLogReply(replyLine, printer='BEETHEFIRST PLUS'): logLine = None if ('\n' in replyLine): replyLines = replyLine.split('ok Q:') re1 = '.*?' # Non-greedy match on filler re2 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 1 re3 = '.*?' # Non-greedy match on filler re4 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 2 re5 = '.*?' # Non-greedy match on filler re6 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 3 re7 = '.*?' # Non-greedy match on filler re8 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 4 re9 = '.*?' # Non-greedy match on filler re10 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 5 re11 = '.*?' # Non-greedy match on filler re12 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 6 re13 = '.*?' # Non-greedy match on filler re14 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 7 re15 = '.*?' # Non-greedy match on filler re16 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 8 re17 = '.*?' # Non-greedy match on filler re18 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 9 re19 = '.*?' # Non-greedy match on filler re20 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 10 re21 = '.*?' # Non-greedy match on filler re22 = '(\\d+)' # Integer Number 1 if printer == 'BEETHEFIRST PLUS': re23 = '.*?' # Non-greedy match on filler re24 = '(\\d+)' # Integer Number 2 re25 = '.*?' # Non-greedy match on filler re26 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 11 rg = re.compile( re1 + re2 + re3 + re4 + re5 + re6 + re7 + re8 + re9 + re10 + re11 + re12 + re13 + re14 + re15 + re16 + re17 + re18 + re19 + re20 + re21 + re22 + re23 + re24 + re25 + re26, re.IGNORECASE | re.DOTALL) elif printer == 'BEETHEFIRST': re23 = '.*?' # Non-greedy match on filler re24 = '([+-]?\\d*\\.\\d+)(?![-+0-9\\.])' # Float 11 rg = re.compile( re1 + re2 + re3 + re4 + re5 + re6 + re7 + re8 + re9 + re10 + re11 + re12 + re13 + re14 + re15 + re16 + re17 + re18 + re19 + re20 + re21 + re22 + re23 + re24, re.IGNORECASE | re.DOTALL) else: logger.info('Unknown Printer') m = rg.search(replyLines[0]) # m = rg.search(reply) if m: float1 = m.group(1) float2 = m.group(2) float3 = m.group(3) float4 = m.group(4) float5 = m.group(5) float6 = m.group(6) float7 = m.group(7) float8 = m.group(8) float9 = m.group(9) float10 = m.group(10) int1 = m.group(11) if printer == 'BEETHEFIRST PLUS': int2 = m.group(12) float11 = m.group(13) logLine = "{},{},{},{},{},{},{},{},{},{},{},{},{}\n".format( float1, float2, float3, float4, float5, float6, float7, float8, float9, float10, int1, int2, float11) elif printer == 'BEETHEFIRST': float11 = m.group(12) logLine = "{},{},{},{},{},{},{},{},{},{},{},{}\n".format( float1, float2, float3, float4, float5, float6, float7, float8, float9, float10, int1, float11) return logLine
def run(self): super(FileTransferThread, self).run() if self.transferType.lower() == 'firmware': self.transferring = True logger.info('Starting Firmware Transfer') self.transferFirmwareFile() # Update Firmware String self.beeCon.sendCmd('M114 A%s' % self.optionalString, 'ok') self.transferring = False elif self.transferType.lower() == 'gcode': self.transferring = True logger.info('Starting GCode Transfer') self.multiBlockFileTransfer() self.transferring = False elif self.transferType.lower() == 'print': # If no file path is given, print last file. Otherwise transfer file to printer if self.filePath is not None: self.transferring = True self.beeCon.setMonitorConnection(False) logger.info('Starting GCode Transfer') self.multiBlockFileTransfer() logger.info('File Transfer Finished... Heating...\n') self.beeCon.setMonitorConnection(True) self.transferring = False if not self.cancelTransfer: self.waitForHeatingAndPrint(self.temperature) self.heating = False else: logger.info('Unknown Transfer Type') logger.info('Exiting transfer thread') return
def run(self): super(FileTransferThread, self).run() if self.transferType.lower() == 'firmware': self.transferring = True logger.info('Starting Firmware Transfer') self.transferFirmwareFile() # Update Firmware String beeCmd = self.beeCon.getCommandIntf() beeCmd.setFirmwareString(self.optionalString) self.transferring = False elif self.transferType.lower() == 'gcode': self.transferring = True self.beeCon.setMonitorConnection(False) logger.info('Starting GCode Transfer') self.multiBlockFileTransfer() self.beeCon.setMonitorConnection(True) self.transferring = False elif self.transferType.lower() == 'print': self.transferring = True self.beeCon.setMonitorConnection(False) logger.info('Starting GCode Transfer') self.multiBlockFileTransfer() logger.info('File Transfer Finished... Heating...\n') self.beeCon.setMonitorConnection(True) self.transferring = False if not self.cancelTransfer: self.waitForHeatingAndPrint(self.temperature) self.heating = False else: logger.info('Unknown Transfer Type') logger.info('Exiting transfer thread') return