def add_file(self, destination, path, file_object, links=None, allow_overwrite=False, printer_profile=None, analysis=None, display=None): if printer_profile is None: printer_profile = self._printer_profile_manager.get_current_or_default() for hook in self._preprocessor_hooks.values(): try: hook_file_object = hook(path, file_object, links=links, printer_profile=printer_profile, allow_overwrite=allow_overwrite) except: self._logger.exception("Error when calling preprocessor hook {}, ignoring".format(hook)) continue if hook_file_object is not None: file_object = hook_file_object queue_entry = self._analysis_queue_entry(destination, path) if queue_entry is not None: self._analysis_queue.dequeue(queue_entry) path_in_storage = self._storage(destination).add_file(path, file_object, links=links, printer_profile=printer_profile, allow_overwrite=allow_overwrite, display=display) queue_entry = self._analysis_queue_entry(destination, path_in_storage, printer_profile=printer_profile, analysis=analysis) if queue_entry: self._analysis_queue.enqueue(queue_entry, high_priority=True) _, name = self._storage(destination).split_path(path_in_storage) eventManager().fire(Events.FILE_ADDED, dict(storage=destination, path=path_in_storage, name=name, type=get_file_type(name))) eventManager().fire(Events.UPDATED_FILES, dict(type="printables")) return path_in_storage
def _handleErrors(self, line): # No matter the state, if we see an error, goto the error state and store the error for reference. if line.startswith('Error:'): #Oh YEAH, consistency. # Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n" # But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!" # So we can have an extra newline in the most common case. Awesome work people. if self._regex_minMaxError.match(line): line = line.rstrip() + self._readline() #Skip the communication errors, as those get corrected. line_lower = line.lower() if 'checksum mismatch' in line_lower \ or 'wrong checksum' in line_lower \ or 'line number is not last line number' in line_lower \ or 'expected line' in line_lower \ or 'no line number with checksum' in line_lower \ or 'no checksum with line number' in line_lower \ or 'format error' in line_lower \ or 'missing checksum' in line_lower: pass elif not self.isError(): self._errorValue = line[6:] self._changeState(self.STATE_ERROR) eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) return line
def startPrint(self): if not self.isOperational() or self.isPrinting(): return if self._currentFile is None: raise ValueError("No file selected for printing") wasPaused = self.isPaused() try: self._currentFile.start() self._changeState(self.STATE_PRINTING) eventManager().fire("PrintStarted", self._currentFile.getFilename()) if self.isSdFileSelected(): if wasPaused: self.sendCommand("M26 S0") self._currentFile.setFilepos(0) self.sendCommand("M24") else: self._sendNext() except: self._errorValue = getExceptionString() self._changeState(self.STATE_ERROR) eventManager().fire("Error", self.getErrorString())
def unselectFile(self): if self.isBusy(): return self._currentFile = None eventManager().fire("FileSelected", None) self._callback.mcFileSelected(None, None, False)
def mcStateChange(self, state): """ Callback method for the comm object, called if the connection state changes. """ oldState = self._state self._state = state # forward relevant state changes to gcode manager if self._comm: if oldState == self._comm.STATE_PRINTING: if self._selectedFile is not None: if state == self._comm.STATE_OPERATIONAL: self._fileManager.printSucceeded(self._selectedFile["filename"], self._comm.getPrintTime()) elif state == self._comm.STATE_CLOSED or state == self._comm.STATE_ERROR or state == self._comm.STATE_CLOSED_WITH_ERROR: self._fileManager.printFailed(self._selectedFile["filename"], self._comm.getPrintTime()) self._fileManager.resumeAnalysis() # printing done, put those cpu cycles to good use if state == self._comm.STATE_PRINTING: self._fileManager.pauseAnalysis() # do not analyse gcode while printing elif state == self._comm.STATE_CONNECTING: eventManager().fire(Events.CONNECTING) elif state == self._comm.STATE_CLOSED: eventManager().fire(Events.DISCONNECTED) elif state == self._comm.STATE_ERROR: # Event has already been fired by comm since it has the error info. # here we close the comm object self._comm.close(True) self._comm = None elif state == self._comm.STATE_CLOSED_WITH_ERROR: # It's already closed so we only need to set it null so we can connect again self._comm = None self.refreshStateData()
def _analyze(self, entry, high_priority=False): path = entry.absolute_path if path is None or not os.path.exists(path): return self._current = entry self._current_highprio = high_priority self._current_progress = 0 try: start_time = time.time() self._logger.info("Starting analysis of {}".format(entry)) eventManager().fire(Events.METADATA_ANALYSIS_STARTED, {"name": entry.name, "path": entry.path, "origin": entry.location, "type": entry.type, # TODO deprecated, remove in 1.4.0 "file": entry.path}) try: result = self._do_analysis(high_priority=high_priority) except TypeError: result = self._do_analysis() self._logger.info("Analysis of entry {} finished, needed {:.2f}s".format(entry, time.time() - start_time)) self._finished_callback(self._current, result) finally: self._current = None self._current_progress = None
def f(movie): delete_unrendered_timelapse(name) payload = dict(gcode=gcode if gcode is not None else "unknown", movie=movie, movie_basename=os.path.basename(movie), movie_prefix=name) eventManager().fire(Events.MOVIE_DONE, payload)
def continue_rendering(): if self._capture_success == 0: # no images - either nothing was attempted to be captured or all attempts ran into an error if self._capture_errors > 0: # this is the latter case _create_render_fail_handler(self._file_prefix, gcode=self._gcode_file)("n/a", returncode=0, stdout="", stderr="", reason="no_frames") # in any case, don't continue return # check if we have post roll configured if self._post_roll > 0: # capture post roll, wait for THAT to finish, THEN render eventManager().fire(Events.POSTROLL_START, dict(postroll_duration=self.calculate_post_roll(), postroll_length=self.post_roll, postroll_fps=self.fps)) self._post_roll_start = time.time() if do_create_movie: self._on_post_roll_done = create_wait_for_captures(reset_and_create) else: self._on_post_roll_done = reset_image_number self.process_post_roll() else: # no post roll? perfect, render self._post_roll_start = None if do_create_movie: wait_for_captures(reset_and_create) else: reset_image_number()
def startPrint(self): if not self.isOperational() or self.isPrinting(): return if self._currentFile is None: raise ValueError("No file selected for printing") self._heatupWaitStartTime = 0 self._heatupWaitTimeLost = 0.0 self._pauseWaitStartTime = 0 self._pauseWaitTimeLost = 0.0 try: self._currentFile.start() wasPaused = self.isPaused() self._changeState(self.STATE_PRINTING) eventManager().fire(Events.PRINT_STARTED, { "file": self._currentFile.getFilename(), "filename": os.path.basename(self._currentFile.getFilename()), "origin": self._currentFile.getFileLocation() }) if self.isSdFileSelected(): if wasPaused: self.sendCommand("M26 S0") self._currentFile.setFilepos(0) self.sendCommand("M24") else: self._sendNext() except: self._logger.exception("Error while trying to start printing") self._errorValue = getExceptionString() self._changeState(self.STATE_ERROR) eventManager().fire(Events.ERROR, {"error": self.getErrorString()})
def add_file(self, destination, path, file_object, links=None, allow_overwrite=False, printer_profile=None, analysis=None): if printer_profile is None: printer_profile = self._printer_profile_manager.get_current_or_default() for hook in self._preprocessor_hooks.values(): try: hook_file_object = hook(path, file_object, links=links, printer_profile=printer_profile, allow_overwrite=allow_overwrite) except: self._logger.exception("Error when calling preprocessor hook {}, ignoring".format(hook)) continue if hook_file_object is not None: file_object = hook_file_object file_path = self._storage(destination).add_file(path, file_object, links=links, printer_profile=printer_profile, allow_overwrite=allow_overwrite) absolute_path = self._storage(destination).path_on_disk(file_path) if analysis is None: file_type = get_file_type(absolute_path) if file_type: queue_entry = QueueEntry(file_path, file_type[-1], destination, absolute_path, printer_profile) self._analysis_queue.enqueue(queue_entry, high_priority=True) else: self._add_analysis_result(destination, path, analysis) eventManager().fire(Events.UPDATED_FILES, dict(type="printables")) return file_path
def processStl(self, absolutePath, destination, uploadCallback=None): from octoprint.slicers.cura import CuraFactory cura = CuraFactory.create_slicer() gcodePath = genGcodeFileName(absolutePath) config = settings.get("cura", "config") slicingStart = time.time() def stlProcessed(stlPath, gcodePath, error=None): if error: eventManager().fire("SlicingFailed", {"stl": self._getBasicFilename( stlPath), "gcode": self._getBasicFilename(gcodePath), "reason": error}) if os.path.exists(stlPath): os.remove(stlPath) else: slicingStop = time.time() eventManager().fire("SlicingDone", {"stl": self._getBasicFilename( stlPath), "gcode": self._getBasicFilename(gcodePath), "time": "%.2f" % (slicingStop - slicingStart)}) self.processGcode(gcodePath, destination, uploadCallback) eventManager().fire("SlicingStarted", {"stl": self._getBasicFilename( absolutePath), "gcode": self._getBasicFilename(gcodePath)}) cura.process_file( config, gcodePath, absolutePath, stlProcessed, [absolutePath, gcodePath])
def startPrint(self): if not super(PrinterVirtual, self).startPrint(): return if not self.isOperational() or self.isPrinting(): return if self._currentFile is None: raise ValueError("No file selected for printing") if self._printJob and self._printJob.isAlive(): raise Exception("A Print Job is still running") self._changeState(self.STATE_PRINTING) eventManager().fire(Events.PRINT_STARTED, { "file": self._currentFile['filename'], "filename": os.path.basename(self._currentFile['filename']), "origin": self._currentFile['origin'] }) #First we simulate heatup self.setTemperature("tool0", 210) self.setTemperature("bed", 60) self.mcHeatingUpUpdate(True) def heatupDone(): if not self._shutdown: self.mcHeatingUpUpdate(False) self._printJob = JobSimulator(self, self._currentFile) self._printJob.start() t = threading.Timer(self._settings['heatingUp'], heatupDone) t.start()
def selectFile(self, filename, sd, printAfterSelect=False): if not super(PrinterVirtual, self).selectFile(filename, sd, printAfterSelect): return False if sd: raise('Printing from SD card is not supported for the Virtual Driver') if not os.path.exists(filename) or not os.path.isfile(filename): raise IOError("File %s does not exist" % filename) filesize = os.stat(filename).st_size eventManager().fire(Events.FILE_SELECTED, { "file": filename, "origin": FileDestinations.LOCAL }) self._setJobData(filename, filesize, sd) self._stateMonitor.setState({"text": self.getStateString(), "flags": self._getStateFlags()}) self._currentFile = { 'filename': filename, 'size': filesize, 'origin': FileDestinations.LOCAL, 'start_time': None, 'progress': None, 'position': None } if self._printAfterSelect: self.startPrint() return True
def on_comm_print_job_paused(self): payload = self._payload_for_print_job_event(position=self._comm.pause_position.as_dict() if self._comm and self._comm.pause_position else None) if payload: eventManager().fire(Events.PRINT_PAUSED, payload) self.script("afterPrintPaused", context=dict(event=payload), must_be_set=False)
def on_comm_print_job_resumed(self): payload = self._payload_for_print_job_event() if payload: eventManager().fire(Events.PRINT_RESUMED, payload) self.script("beforePrintResumed", context=dict(event=payload), must_be_set=False)
def unselectFile(self): if self.isBusy(): return self._currentFile = None eventManager().fire(Events.FILE_DESELECTED) self._callback.mcFileSelected(None, None, False)
def close(self, isError = False): printing = self.isPrinting() or self.isPaused() if self._serial is not None: try: self._serial.close() except OSError as e: #log it but continue self._logger.error('Error closing serial port: %s' % e) if isError: self._changeState(self.STATE_CLOSED_WITH_ERROR) else: self._changeState(self.STATE_CLOSED) self._serial = None if settings().get(["feature", "sdSupport"]): self._sdFileList = [] if printing: payload = None if self._currentFile is not None: payload = { "file": self._currentFile.getFilename(), "filename": os.path.basename(self._currentFile.getFilename()), "origin": self._currentFile.getFileLocation() } eventManager().fire(Events.PRINT_FAILED, payload) eventManager().fire(Events.DISCONNECTED)
def startPrint(self): if not self.isOperational() or self.isPrinting(): return if self._currentFile is None: raise ValueError("No file selected for printing") try: self._currentFile.start() self._lastLayerHeight = 0.0; self._currentLayer = 0; #self._currentLayer = 1; #sefl._lastLayerHeight; #self._callback.mcLayerChange(self._tentativeLayer) wasPaused = self.isPaused() self._changeState(self.STATE_PRINTING) eventManager().fire(Events.PRINT_STARTED, { "file": self._currentFile.getFilename(), "filename": os.path.basename(self._currentFile.getFilename()), "origin": self._currentFile.getFileLocation() }) if self.isSdFileSelected(): if wasPaused: self.sendCommand("M26 S0") self._currentFile.setFilepos(0) self.sendCommand("M24") else: self._sendNext() except: self._errorValue = getExceptionString() self._changeState(self.STATE_ERROR) eventManager().fire(Events.ERROR, {"error": self.getErrorString()})
def __init__(self, post_roll=0, fps=25): self._logger = logging.getLogger(__name__) self._image_number = None self._in_timelapse = False self._gcode_file = None self._post_roll = post_roll self._on_post_roll_done = None self._capture_dir = settings().getBaseFolder("timelapse_tmp") self._movie_dir = settings().getBaseFolder("timelapse") self._snapshot_url = settings().get(["webcam", "snapshot"]) self._ffmpeg_threads = settings().get(["webcam", "ffmpegThreads"]) self._fps = fps self._render_thread = None self._capture_mutex = threading.Lock() self._capture_queue = Queue.Queue() self._capture_queue_active = True self._capture_queue_thread = threading.Thread(target=self._capture_queue_worker) self._capture_queue_thread.daemon = True self._capture_queue_thread.start() # subscribe events eventManager().subscribe(Events.PRINT_STARTED, self.on_print_started) eventManager().subscribe(Events.PRINT_FAILED, self.on_print_done) eventManager().subscribe(Events.PRINT_DONE, self.on_print_done) eventManager().subscribe(Events.PRINT_RESUMED, self.on_print_resumed) for (event, callback) in self.event_subscriptions(): eventManager().subscribe(event, callback)
def _sendNext(self): with self._sendNextLock: line = self._currentFile.getNext() if line is None: if self.isStreaming(): self._sendCommand("M29") remote = self._currentFile.getRemoteFilename() payload = { "local": self._currentFile.getLocalFilename(), "remote": remote, "time": self.getPrintTime() } self._currentFile = None self._changeState(self.STATE_OPERATIONAL) self._callback.mcFileTransferDone(remote) eventManager().fire(Events.TRANSFER_DONE, payload) self.refreshSdFiles() else: payload = { "file": self._currentFile.getFilename(), "filename": os.path.basename(self._currentFile.getFilename()), "origin": self._currentFile.getFileLocation(), "time": self.getPrintTime(), "layerCount": self._currentLayer } self._callback.mcPrintjobDone() self._changeState(self.STATE_OPERATIONAL) eventManager().fire(Events.PRINT_DONE, payload) return self._sendCommand(line, True) self._callback.mcProgress()
def setPause(self, pause): if self.isStreaming(): return if not pause and self.isPaused(): self._changeState(self.STATE_PRINTING) if self.isSdFileSelected(): self.sendCommand("M24") else: self._sendNext() eventManager().fire(Events.PRINT_RESUMED, { "file": self._currentFile.getFilename(), "filename": os.path.basename(self._currentFile.getFilename()), "origin": self._currentFile.getFileLocation() }) elif pause and self.isPrinting(): self._changeState(self.STATE_PAUSED) if self.isSdFileSelected(): self.sendCommand("M25") # pause print eventManager().fire(Events.PRINT_PAUSED, { "file": self._currentFile.getFilename(), "filename": os.path.basename(self._currentFile.getFilename()), "origin": self._currentFile.getFileLocation() })
def rampdown(self): self.disconnect() eventManager().unsubscribe(Events.METADATA_ANALYSIS_FINISHED, self.onMetadataAnalysisFinished); self._callbacks = [] self._stateMonitor.stop() self._stateMonitor._worker.join() self._fileManager.rampdown()
def _addTemperatureData(self, temp, bedTemp): data = { "time": int(time.time()) } if temp is not None: for tool in temp.keys(): data["tool%d" % tool] = { "actual": temp[tool][0], "target": temp[tool][1] } if bedTemp is not None and isinstance(bedTemp, tuple): data["bed"] = { "actual": bedTemp[0], "target": bedTemp[1] } self._temps.append(data) self._temp = temp self._bedTemp = bedTemp eventManager().fire(Events.TEMPERATURE_CHANGE, data) self._stateMonitor.addTemperature(data)
def selectFile(self, filename, sd, printAfterSelect=False): if not self.isConnected() or self.isBusy() or self.isStreaming(): self._logger.info("Cannot load file: printer not connected or currently busy") return False self._setProgressData(0, None, None, None, 1) self._setCurrentZ(None) if not os.path.exists(filename) or not os.path.isfile(filename): raise IOError("File %s does not exist" % filename) filesize = os.stat(filename).st_size eventManager().fire(Events.FILE_SELECTED, { "file": filename, "origin": FileDestinations.SDCARD if sd else FileDestinations.LOCAL }) self._setJobData(filename, filesize, sd) self.refreshStateData() self._currentFile = { 'filename': filename, 'size': filesize, 'origin': FileDestinations.SDCARD if sd else FileDestinations.LOCAL, 'start_time': None, 'progress': None, 'position': None } if printAfterSelect: self.startPrint() return True
def f(movie, returncode=255, stdout="Unknown error", stderr="Unknown error"): event_payload = {"gcode": gcode if gcode is not None else "unknown", "movie": movie, "movie_basename": os.path.basename(movie)} payload = dict(event_payload) payload.update(dict(returncode=returncode, error=stderr)) eventManager().fire(Events.MOVIE_FAILED, payload)
def mcProgress(self): """ Callback method for the comm object, called upon any change in progress of the printjob. Triggers storage of new values for printTime, printTimeLeft and the current progress. """ #Calculate estimated print time left printTime = self.getPrintTime() progress = self.getPrintProgress() estimatedTimeLeft = None if self._estimatedPrintTime: if printTime and progress: if progress < 1.0: estimatedTimeLeft = self._estimatedPrintTime * ( 1.0 - progress ) elaspedTimeVariance = printTime - ( self._estimatedPrintTime - estimatedTimeLeft ) adjustedEstimatedTime = self._estimatedPrintTime + elaspedTimeVariance estimatedTimeLeft = ( adjustedEstimatedTime * ( 1.0 - progress) ) / 60 else: estimatedTimeLeft = 0 else: estimatedTimeLeft = self._estimatedPrintTime / 60 value = self._formatPrintingProgressData(progress, self.getPrintFilepos(), printTime, estimatedTimeLeft, self.getCurrentLayer()) eventManager().fire(Events.PRINTING_PROGRESS, value) self._setProgressData(progress, self.getPrintFilepos(), printTime, estimatedTimeLeft, self.getCurrentLayer())
def f(movie): global current_render_job event_payload = {"gcode": gcode if gcode is not None else "unknown", "movie": movie, "movie_basename": os.path.basename(movie)} current_render_job = event_payload eventManager().fire(Events.MOVIE_RENDERING, event_payload)
def __init__(self, postRoll=0): self._logger = logging.getLogger(__name__) self._imageNumber = None self._inTimelapse = False self._gcodeFile = None self._postRoll = postRoll self._postRollStart = None self._onPostRollDone = None self._captureDir = settings().getBaseFolder("timelapse_tmp") self._movieDir = settings().getBaseFolder("timelapse") self._snapshotUrl = settings().get(["webcam", "snapshot"]) self._fps = 25 self._renderThread = None self._captureMutex = threading.Lock() # subscribe events eventManager().subscribe(Events.PRINT_STARTED, self.onPrintStarted) eventManager().subscribe(Events.PRINT_FAILED, self.onPrintDone) eventManager().subscribe(Events.PRINT_DONE, self.onPrintDone) eventManager().subscribe(Events.PRINT_RESUMED, self.onPrintResumed) for (event, callback) in self.eventSubscriptions(): eventManager().subscribe(event, callback)
def __init__(self): self.broadcastTraffic = 0 #Number of clients that wish to receive serial link traffic self.doIdleTempReports = True #Let's the client know if periodic temperature reports should be queries to the printer self._comm = None self._selectedFile = None self._printAfterSelect = False self._currentZ = None self._progress = None self._printTime = None self._printTimeLeft = None self._currentLayer = None self._currentPrintJobId = None self._profileManager = printerProfileManager() self._fileManager= printFileManagerMap[self._fileManagerClass.name]() self._fileManager.registerCallback(self) self._state = self.STATE_NONE self._logger = logging.getLogger(__name__) self._temp = {} self._bedTemp = None self._temps = deque([], 300) self._shutdown = False self._messages = deque([], 300) # callbacks self._callbacks = [] #self._lastProgressReport = None self._stateMonitor = StateMonitor( ratelimit= 1.0, updateCallback= self._sendCurrentDataCallbacks, addTemperatureCallback= self._sendAddTemperatureCallbacks, addLogCallback= self._sendAddLogCallbacks, addMessageCallback= self._sendAddMessageCallbacks ) self._stateMonitor.reset( state={"text": self.getStateString(), "flags": self._getStateFlags()}, jobData={ "file": { "name": None, "size": None, "origin": None, "date": None }, "estimatedPrintTime": None, "filament": { "length": None, "volume": None } }, progress={"completion": None, "filepos": None, "printTime": None, "printTimeLeft": None}, currentZ=None ) eventManager().subscribe(Events.METADATA_ANALYSIS_FINISHED, self.onMetadataAnalysisFinished);
def on_comm_state_change(self, state): """ Callback method for the comm object, called if the connection state changes. """ oldState = self._state state_string = None if self._comm is not None: state_string = self._comm.getStateString() # forward relevant state changes to gcode manager if oldState == comm.MachineCom.STATE_PRINTING: if self._selectedFile is not None: if state == comm.MachineCom.STATE_CLOSED or state == comm.MachineCom.STATE_ERROR or state == comm.MachineCom.STATE_CLOSED_WITH_ERROR: self._fileManager.log_print(FileDestinations.SDCARD if self._selectedFile["sd"] else FileDestinations.LOCAL, self._selectedFile["filename"], time.time(), self._comm.getPrintTime(), False, self._printerProfileManager.get_current_or_default()["id"]) self._analysisQueue.resume() # printing done, put those cpu cycles to good use elif state == comm.MachineCom.STATE_PRINTING: self._analysisQueue.pause() # do not analyse files while printing if state == comm.MachineCom.STATE_CLOSED or state == comm.MachineCom.STATE_CLOSED_WITH_ERROR: if self._comm is not None: self._comm = None self._setProgressData(completion=0) self._setCurrentZ(None) self._setJobData(None, None, None) self._printerProfileManager.deselect() eventManager().fire(Events.DISCONNECTED) self._setState(state, state_string=state_string)
def _work(self): import makerbot_driver.MachineFactory s = settings() retries = self.CONNECT_MAX_RETRIES try: while True: if self.isConnected(): self._comm.close() if retries < 0: self._changeState(self.STATE_ERROR) self._errorValue = "Error Connecting" self._logger.error('Error connecting to printer.') self._comm = None break else: try: result = makerbot_driver.MachineFactory().build_from_port(self._port, condition= self._state_condition) self._comm = result.s3g self._profile = result.profile self._gcodeParser = result.gcodeparser version_info = self._comm.get_advanced_version() #Update maps from https://www.thingiverse.com/thing:32084/#files, place them on ext/makerbot_driver/EEPROM #We should update some of the profile values with stuff retrieved from the EEPROM stepsPerMM = self._comm.read_named_value_from_EEPROM('AXIS_STEPS_PER_MM') # This dissapeared in Sailfish 7.3 #axisLengths = self._comm.read_named_value_from_EEPROM('AXIS_LENGTHS_MM') #self._profile.values['axes']['X']['platform_length'] = axisLengths[0] #self._profile.values['axes']['Y']['platform_length'] = axisLengths[1] #self._profile.values['axes']['Z']['platform_length'] = axisLengths[2] #self._profile.values['axes']['A']['platform_length'] = axisLengths[3] self._profile.values['axes']['X']['steps_per_mm'] = stepsPerMM[0]/1000000.0 self._profile.values['axes']['Y']['steps_per_mm'] = stepsPerMM[1]/1000000.0 self._profile.values['axes']['Z']['steps_per_mm'] = stepsPerMM[2]/1000000.0 self._profile.values['axes']['A']['steps_per_mm'] = -stepsPerMM[3]/1000000.0 if "B" in self._profile.values['axes']: self._profile.values['axes']['B']['steps_per_mm'] = -stepsPerMM[4]/1000000.0 #self._profile.values['axes']['B']['platform_length'] = axisLengths[4] self._firmwareVersion = version_info['Version'] self._logger.info('Connected to Machine running version: %d, variant: 0x%x' % (self._firmwareVersion, version_info['SoftwareVariant']) ) self._changeState(self.STATE_OPERATIONAL) eventManager().fire(Events.CONNECTED, {"port": self._port, "baudrate": self._baudrate}) s.set(['serial', 'port'], self._port) s.save() break except makerbot_driver.errors.TransmissionError as e: retries -= 1 if retries > 0: self._logger.info('TransmissionError - Retrying. Retries left %d...' % retries) time.sleep(.2) except makerbot_driver.errors.UnknownResponseError as e: retries -= 1 if retries > 0: self._logger.info('UnknownResponseError - Retrying. Retries left %d...' % retries) time.sleep(.2) except makerbot_driver.errors.BuildCancelledError: self._logger.info("Build cancelled detected. No problem") if retries >=0: toolHeadCount = len(self._profile.values['tools']) while self._comm: try: for i in range(0, toolHeadCount): self._temp[i] = (self._comm.get_toolhead_temperature(i), self._comm.get_toolhead_target_temperature(i)) self._bedTemp = (self._comm.get_platform_temperature(0), self._comm.get_platform_target_temperature(0)) self.mcTempUpdate(self._temp, self._bedTemp) except makerbot_driver.BufferOverflowError: pass except makerbot_driver.TransmissionError: self._logger.error('Unfortunatelly an unrecoverable error occurred between the printer and the box') self.disconnect() break except makerbot_driver.BuildCancelledError: self._logger.warn('Build cancelled detected.') if self._printJob: self._logger.warn('Cancelling current job.') self._printJob.cancel() except makerbot_driver.ProtocolError: # It has been observed that sometimes the response comes back empty but # in a valid package. This was in a Flash Forge running Sailfish 7.7 self._logger.warn('Badly formatted response. skipping...') except SerialException as e: raise e except Exception as e: # we shouldn't kill the thread as this is only an informational # thread import traceback print traceback.format_exc() self._logger.warn(getExceptionString()) time.sleep(self.UPDATE_INTERVAL) except SerialException as e: self._logger.error(e) self._errorValue = "Serial Link failed" self._changeState(self.STATE_ERROR) eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) self.disconnect()
def downloadPrintFile(self, printFileId, sendResponse): em = eventManager() def progressCb(progress): self.publishEvent('progress_download_printfile', { "type": "progress", "id": printFileId, "progress": progress }) def successCb(destFile, fileInfo): if fileInfo is True: #This means the files was already on the device data = { "type": "success", "id": printFileId, "filename": printerManager().fileManager._getBasicFilename(destFile) } self.publishEvent('f¡nished_download_printfile', data) em.fire(Events.CLOUD_DOWNLOAD, data) else: data = { "type": "success", "id": printFileId, "filename": printerManager().fileManager._getBasicFilename(destFile), "info": fileInfo["info"], "printer": fileInfo["printer"], "material": fileInfo["material"], "quality": fileInfo["quality"], "image": fileInfo["image"], "created": fileInfo["created"] } self.publishEvent('f¡nished_download_printfile', data) def errorCb(destFile, error): if error == 'cancelled': data = {"type": "cancelled", "id": printFileId} self.publishEvent('f¡nished_download_printfile', data) em.fire(Events.CLOUD_DOWNLOAD, data) else: data = {"type": "error", "id": printFileId, "reason": error} em.fire(Events.CLOUD_DOWNLOAD, data) self.publishEvent('f¡nished_download_printfile', data) if destFile and os.path.exists(destFile): os.remove(destFile) if astroprintCloud().download_print_file(printFileId, progressCb, successCb, errorCb): sendResponse({'success': 'no error'}) return sendResponse('error', True) return