def set_groups(self, groups):
     if type(groups) == list:
         self.logger.info("Groups are set correctly for %s %s" % (str(self.usb_info), str(groups)))
         self.groups = groups
     else:
         config.create_error_report(999, "Invalid workgroups format - type must be list: " + str(groups),
                                    self.usb_info, self.logger, is_blocking=False)
Beispiel #2
0
 def flash_firmware(self):
     firmware = self.find_firmware_file()
     if firmware:
         self.logger.info(
             "Prepare to flash device with firmware:{0}.".format(firmware))
         file_size = os.path.getsize(firmware)
         version = "0.0.0"
         ret1 = self.dispatch("M114 A{0}\n".format(version))
         message = "M650 A{0}\n".format(file_size)
         ret2 = self.dispatch(message)
         if 'ok' in ret1 and 'ok' in ret2:
             with open(firmware, 'rb') as f:
                 while True:
                     buf = f.read(64)
                     if not buf: break
                     self.ep_out.write(buf)
                     ret = []
                     while (len(ret) != len(buf)):
                         ret += self.ep_in.read(len(buf), READ_TIMEOUT)
                     assert (''.join([chr(x) for x in ret]) in buf)
                     self.logger.debug(".")
             self.logger.info("Flashing complete.")
             new_version = self.get_firmware_version(
                 os.path.basename(firmware))
             self.dispatch("M114 A{0}\n".format(new_version))
             self.dispatch("M630\n")
             self.dev.reset()
             self.logger.info("Rebooting to new firmware...")
     else:
         config.create_error_report(601,
                                    "Error - no firmware found.",
                                    self.usb_info,
                                    self.logger,
                                    is_blocking=True)
 def start_main_loop(self):
     self.last_flush_time = 0
     self.detector = usb_detect.USBDetector()
     self.http_client = http_client.HTTPClient()
     while not self.stop_flag:
         self.updater.timer_check_for_updates()
         self.time_stamp()
         self.detected_printers = self.detector.get_printers_list()
         if self.virtual_printer_enabled:
             self.detected_printers.append( {"VID" : "ZZZZ", "PID": "ZZZZ", "SNR": "0", "COM": None} )
         self.connect_new_printers()
         for pi in self.printer_interfaces:
             if pi.usb_info not in self.detected_printers:
                 if not pi.error_state == "error":
                     config.create_error_report(99, "Printer is no longer detected as USB device.", pi.usb_info, self.logger, is_blocking=True)
             if not pi.is_alive():
                 if not pi.stop_flag:
                     self.logger.warning("Printer interface of %s had crushed" % pi.usb_info)
                 self.logger.info('Removing %s from printer list' % pi.usb_info)
                 self.printer_interfaces.remove(pi)
         if not self.stop_flag:
             time.sleep(self.MAIN_LOOP_SLEEP)
         now = time.time()
         if now - self.last_flush_time > self.LOG_FLUSH_TIME:
             self.last_flush_time = now
             self.flush_log()
     self.quit()
Beispiel #4
0
 def update(self):
     if self.update_flag:
         self.logger.info('Updating client...')
         update_file_name = config.get_settings(
         )['update']['update_file_name']
         try:
             urllib.urlretrieve(
                 config.get_settings()['update']['update_file_url'] +
                 update_file_name, update_file_name)
         except Exception as e:
             error_message = 'Update failed!\nReason: error while downloading.\nDetails: ' + str(
                 e)
             config.create_error_report(0,
                                        error_message,
                                        None,
                                        self.logger,
                                        is_blocking=True)
             return error_message
         else:
             error = self.extract_update(update_file_name)
             if error:
                 return error
             self.logger.info('...client successfully updated!')
             self.update_flag = False
             log.send_logs()
             log.clear_logs()
 def reading(self):
     while not self.stop_flag:
         line = self.connection.recv()
         if line is None:  # None means error reading from printer, but "" is ok
             self.operational_flag = False
             time.sleep(self.PAUSE_ON_ERROR_READING_PORT)
         elif not line or "wait" in line:
             continue
         elif self.is_ok(line):
             self.ready_for_command = True
             self.operational_flag = True
             self.check_temperature_and_position(line)
         elif line.startswith("T"):  # FIXME T is too ambitious
             self.parse_waiting_temperature_updates(line)
             self.operational_flag = True
         elif self.check_for_resend_requests(line):
             self.logger.debug(line)
             self.operational_flag = True
             self.ready_for_command = True
         elif line.startswith('Error'):
             if not ("checksum" in line or
                     "Checksum" in line or
                     "expected line" in line or
                     "Line Number is not Last Line Number+1" in line or
                     "Format error" in line):
                 is_blocking = self.BOARD_RESET_GCODE in line or "disabling all for safety!" in line
                 self.operational_flag = False
                 config.create_error_report(201, line, self.usb_info, self.logger, is_blocking=is_blocking)
             else:
                 self.logger.debug(line)
         elif line.startswith('DEBUG'):
             self.logger.info(line)
         else:
             self.logger.warning("Special message: " + line.strip())
 def flash_firmware(self):
     firmware = self.find_firmware_file()
     if firmware:
         self.logger.info("Prepare to flash device with firmware:{0}.".format(firmware))
         file_size = os.path.getsize(firmware)
         version = "0.0.0"
         ret1 = self.dispatch("M114 A{0}\n".format(version))
         message = "M650 A{0}\n".format(file_size)
         ret2 = self.dispatch(message)
         if 'ok' in ret1 and 'ok' in ret2:
             with open(firmware, 'rb') as f:
                 while True:
                     buf = f.read(64)
                     if not buf: break
                     self.ep_out.write(buf)
                     ret = []
                     while (len(ret) != len(buf)):
                         ret += self.ep_in.read(len(buf), READ_TIMEOUT)
                     assert (''.join([chr(x) for x in ret]) in buf)
                     self.logger.debug(".")
             self.logger.info("Flashing complete.")
             new_version = self.get_firmware_version(os.path.basename(firmware))
             self.dispatch("M114 A{0}\n".format(new_version))
             self.dispatch("M630\n")
             self.dev.reset()
             self.logger.info("Rebooting to new firmware...")
     else:
         config.create_error_report(601, "Error - no firmware found.", self.usb_info, self.logger, is_blocking=True)
Beispiel #7
0
 def monitoring(self):
     self.logger.info("Monitoring thread started")
     while not self.monitoring_stop and not self.stop_flag:
         self.connection.send("M105")
         self.connection.send("M119")
         self.connection.send("M27")
         answer = self.readout()
         if not answer:
             self.operational_flag = False
             message = "Printer not answering in monitoring. Printer lost."
             config.create_error_report(606,
                                        message,
                                        self.usb_info,
                                        self.logger,
                                        is_blocking=True)
             break
         self.parse_temperature(answer)
         self.operational_flag = True
         if self.STATE_READY in answer:
             self.printing_flag = False
         else:
             self.printing_flag = True
             progress_match = self.progress_re.match(answer)
             if progress_match:
                 self.lines_sent = int(progress_match.group(1))
                 self.total_gcodes = int(progress_match.group(2))
                 if self.total_gcodes > 0:
                     self.percent = int(self.lines_sent /
                                        float(self.total_gcodes) * 100)
         time.sleep(0.1)
     self.logger.info("Monitoring thread stopped")
 def pack(self, target, *args, **kwargs):
     if target == 'user_login':
         data = { 'login': {'user': args[0], 'password': args[1]},
                  'platform': platforms.PLATFORM, 'host_mac': self.mac,
                  'local_ip' : self.local_ip, 'version': version.version}
         if 'disposable_token' in kwargs:
             data['login']['disposable_token'] = kwargs['disposable_token']
         path = self.user_login_path
         #self.logger.debug(data)
     elif target == 'printer_login':
         data = { 'user_token': args[0], 'printer': args[1], "version": version.version,
                  "data_time": time.ctime(), "camera": config.get_app().camera_controller.get_current_camera_name() }
         path = self.printer_login_path
     elif target == 'command':
         data = { 'printer_token': args[0], 'report': args[1], 'command_ack': args[2] }
         if not data['command_ack']:
             data.pop('command_ack')
         path = self.command_path
     elif target == 'camera':
         data = { 'user_token': args[0], 'camera_number': args[1], 'camera_name': args[2],
                  'file_data': args[3], 'host_mac': self.mac}
         path = self.camera_path
     elif target == 'cloudsync':
         data = { 'user_token': args[0], 'file_data': args[1]}
         path = self.cloudsync_path
     else:
         config.create_error_report(4, 'No such target for packaging: ' + target, None,
                                    self.logger, is_blocking=False)
         data, path = None, None
     for key, value in kwargs.items():
         data[key] = value
     return path, json.dumps(data)
Beispiel #9
0
 def cancel(self):
     if not self.cancel_download():
         if self.profile.get('no_DTR') and self.in_heating:
             message = "This printer model can't cancel during heating."
             config.create_error_report(257,
                                        message,
                                        self.usb_info,
                                        self.logger,
                                        is_blocking=False)
             return False
         else:
             self.stop_flag = True
             if self.print_thread:
                 self.print_thread.cancel()
             self.print_thread.join()
             self.read_thread.join()
             self.temperature_request_thread.join()
             self.reset()
             self.stop_flag = False
             try:
                 self.init()
                 self.logger.info("Successful cancel")
             except RuntimeError:
                 message = "Can't reconnect to printer after cancel."
                 config.create_error_report(255,
                                            message,
                                            self.usb_info,
                                            self.logger,
                                            is_blocking=True)
 def check_operational_state(self):
     if not self.printer or self.stop_flag:
         pass
     elif self.printer.stop_flag:
         pass
     elif self.printer.is_operational(
     ):  #TODO check this operation for thread safety
         self.last_operational_time = time.time()
         self.error_state = None
         self.last_errors = []
     elif not self.error_state:
         message = "Printer is not operational"
         config.create_error_report(77,
                                    message,
                                    self.usb_info,
                                    self.logger,
                                    is_blocking=False)
     elif self.error_state != "error" and self.last_operational_time + self.READY_TIMEOUT < time.time(
     ):
         message = "Not operational timeout reached"
         config.create_error_report(78,
                                    message,
                                    self.usb_info,
                                    self.logger,
                                    is_blocking=True)
 def send_now(self, line):
     with self.send_now_lock:
         if self.print_thread and self.print_thread.is_alive():
             self.print_thread.send_now_buffer.append(line)
         else:
             with self.homing_lock:
                 self.homing_thread.join()
             while not self.ready_for_command:
                 if self.stop_flag:
                     return
                 if not self.operational_flag:
                     return
                 time.sleep(PrintThread.OK_WAITING_STEP)
             self.ready_for_command = False
             if self.connection.send(line):
                 self.analyze_sent_line(line)
                 # we need to wait for processing of current command, to avoid errors in print_thread
                 while not self.ready_for_command:
                     if self.stop_flag:
                         return
                     if not self.operational_flag:
                         return
                     time.sleep(PrintThread.OK_WAITING_STEP)
             else:
                 self.ready_for_command = True
                 config.create_error_report(
                     "Unable to write to serial port",
                     250,
                     self.usb_info,
                     self.logger,
                     is_blocking=False)
 def send_now(self, line):
     with self.send_now_lock:
         if self.print_thread and self.print_thread.is_alive():
             self.print_thread.send_now_buffer.append(line)
         else:
             with self.homing_lock:
                 self.homing_thread.join()
             while not self.ready_for_command:
                 if self.stop_flag:
                     return
                 if not self.operational_flag:
                     return
                 time.sleep(PrintThread.OK_WAITING_STEP)
             self.ready_for_command = False
             if self.connection.send(line):
                 self.analyze_sent_line(line)
                 # we need to wait for processing of current command, to avoid errors in print_thread
                 while not self.ready_for_command:
                     if self.stop_flag:
                         return
                     if not self.operational_flag:
                         return
                     time.sleep(PrintThread.OK_WAITING_STEP)
             else:
                 self.ready_for_command = True
                 config.create_error_report("Unable to write to serial port", 250,
                                            self.usb_info, self.logger, is_blocking=False)
 def execute_server_command(self, server_message):
     number, command, payload = server_message['number'], server_message[
         'command'], server_message.get('payload')
     self.logger.info("Executing command number %i : %s" %
                      (number, str(command)))
     method = getattr(self.printer, command)
     arguments = []
     if payload:
         arguments.append(payload)
     if server_message.get('is_link'):
         arguments.append(True)
     try:
         result = method(*arguments)
         # to reduce needless return True, we assume that when method had return None, that is success
         result = result or result == None
     except Exception as e:
         config.create_error_report(
             109,
             "Error while executing command %s, number %d.\t%s" %
             (command, number, e.message),
             self.usb_info,
             self.logger,
             is_blocking=False)
         result = False
     ack = {"number": number, "result": result}
     return ack
 def start_download(self):
     self.logger.info("Downloading from " + self.url)
     self.tmp_file = tempfile.NamedTemporaryFile(mode='wb', delete=False, prefix='3dprinteros-', suffix='.gcode')
     resume_byte_pos = 0
     retry = 0
     while retry < self.MAX_RETRIES and not self.base_sender.stop_flag and not self.cancel_flag:
         if retry:
             self.logger.warning("Download retry/resume N%d" % retry)
         self.logger.info("Connecting to " + self.url)
         resume_header = {'Range': 'bytes=%d-' % resume_byte_pos}
         try:
             request = requests.get(self.url, headers = resume_header, stream=True, timeout = self.timeout)
         except Exception as e:
             request = None
             config.create_error_report(65, "Unable to open download link: " + str(e),
                                        self.base_sender.usb_info, self.logger, is_blocking=False)
         else:
             self.increase_timeout()
             self.logger.info("Successful connection to " + self.url)
             download_length = int(request.headers.get('content-length', 0))
             if download_length:
                 downloaded_size = self.downloading_loop(request, download_length)
                 resume_byte_pos += downloaded_size
                 self.logger.info("Downloaded %d bytes" % resume_byte_pos)
                 if downloaded_size == download_length:
                     self.tmp_file.close()
                     return self.tmp_file.name
         finally:
             if request:
                 request.close()
             retry += 1
             time.sleep(1)
     self.tmp_file.close()
 def monitoring(self):
     self.logger.info("Monitoring thread started")
     while not self.monitoring_stop and not self.stop_flag:
         self.connection.send("M105")
         self.connection.send("M119")
         self.connection.send("M27")
         answer = self.readout()
         if not answer:
             self.operational_flag = False
             message = "Printer not answering in monitoring. Printer lost."
             config.create_error_report(606, message, self.usb_info, self.logger, is_blocking=True)
             break
         self.parse_temperature(answer)
         self.operational_flag = True
         if self.STATE_READY in answer:
             self.printing_flag = False
         else:
             self.printing_flag = True
             progress_match = self.progress_re.match(answer)
             if progress_match:
                 self.lines_sent = int(progress_match.group(1))
                 self.total_gcodes = int(progress_match.group(2))
                 if self.total_gcodes > 0:
                     self.percent = int(self.lines_sent / float(self.total_gcodes) * 100)
         time.sleep(0.1)
     self.logger.info("Monitoring thread stopped")
 def check_server_command(self, server_message):
     if self.last_error:
         if server_message.get('command'):
             self.logger.error(
                 "! Server returns command on request containing an error - this is error."
             )
             return {
                 "number": server_message.get('number'),
                 "result": False
             }
     error = server_message.get('error')
     if error:
         self.logger.warning("@ Error in server message:%s\t%s" %
                             (str(error['code']), error['message']))
     command = server_message.get('command')
     if command:
         method = getattr(self.printer, command, None)
         if type(server_message.get('number')) != int:
             message = "Error in number field of server's message: " + str(
                 server_message)
             config.create_error_report(41,
                                        message,
                                        self.logger,
                                        is_blocking=False)
         elif not method:
             config.create_error_report(40,
                                        "Unknown command:'%s' " %
                                        str(command),
                                        self.usb_info,
                                        self.logger,
                                        is_blocking=False)
         else:
             return self.execute_server_command(server_message)
 def pack(self, target, *args, **kwargs):
     if target == 'user_login':
         data = { 'login': {'user': args[0], 'password': args[1]}, "platform": sys.platform,
                  'host_mac': self.MACHINE_ID, "version": version.version }
         path = self.user_login_path
     elif target == 'printer_login':
         data = { 'user_token': args[0], 'printer': args[1], "version": version.version,
                  "data_time": time.ctime(), "camera": config.get_app().camera_controller.get_current_camera_name()}
         path = self.printer_login_path
     elif target == 'command':
         data = { 'printer_token': args[0], 'report': args[1], 'command_ack': args[2] }
         if not data['command_ack']:
             data.pop('command_ack')
         path = self.command_path
     elif target == 'camera':
         data = { 'user_token': args[0], 'camera_number': args[1], 'camera_name': args[2],
                  'file_data': args[3], 'host_mac': self.MACHINE_ID }
         path = self.camera_path
     elif target == 'cloudsync':
         data = { 'user_token': args[0], 'file_data': args[1] }
         path = self.cloudsync_path
     else:
         config.create_error_report(4, 'No such target for packaging: ' + target, None,
                                    self.logger, is_blocking=False)
         data, path = None, None
     for key, value in kwargs.items():
         data[key] = value
     return path, json.dumps(data)
 def connect(self):
     self.logger.debug("{ Connecting...")
     fails = 0
     while not self.parent.stop_flag:
         try:
             if self.HTTPS_MODE:
                 connection = httplib.HTTPSConnection(self.URL, port = 443, timeout = self.timeout)
             else:
                 connection = httplib.HTTPConnection(self.URL, port = 80, timeout = self.timeout)
             connection.connect()
             self.local_ip = connection.sock.getsockname()[0]
             self.mac = self.get_mac_add_or_serial_number()
         except Exception as e:
             config.create_error_report(5, "Error during HTTP connection: " + str(e),
                                        self.parent_usb_info, self.logger, is_blocking=False)
             self.logger.debug("...failed }")
             self.logger.warning("Warning: connection to %s failed." % self.URL)
             if self.timeout < self.MAX_TIMEOUT:
                 self.timeout += self.BASE_TIMEOUT
             time.sleep(1)
             fails += 1
             if fails > self.MAX_FAILS:
                 return
         else:
             self.logger.debug("...success }")
             self.logger.info("Connecting from: %s\t%s" % (self.local_ip, self.mac))
             return connection
 def unbuffered_gcodes(self, gcodes):
     # TODO: Add report for not support this
     config.create_error_report(705,
                                "This printer don't support Gcodes",
                                self.usb_info,
                                self.logger,
                                is_blocking=False)
     return None
 def unpause(self):
     # FIXME: Its ugly, need move to BirdwingConnector or better MakerBotAPI
     if self.pause_flag and "resume" in self.available_methods:
         self.makerbot.unpause_print()
         self.pause_flag = False
     else:
         config.create_error_report(704, "For now, cannot use command resume.",
                                    self.usb_info, self.logger, is_blocking=False)
         return False
Beispiel #21
0
 def pause(self):
     # if self.print_thread:
     #     if not self.print_thread.paused:
     #         self.print_thread.send("M25", add_checksum=False)
     #         self.print_thread.paused = True
     #         return True
     message = "This feature do not supported"
     config.create_error_report(902, message, self.usb_info, self.logger, is_blocking=False)
     return False
Beispiel #22
0
 def cancel(self):
     # TODO: Not working on Cloud, REPORT ME
     message = "Cancel is not supported by BOSCH Dremel"
     config.create_error_report(605,
                                message,
                                self.usb_info,
                                self.logger,
                                is_blocking=False)
     return False
Beispiel #23
0
 def load_gcodes(self, gcodes):
     if self.operational_flag and not self.is_printing():
         return self.upload_gcodes_and_print(gcodes)
     else:
         config.create_error_report(604,
                                    "Printer already printing.",
                                    self.usb_info,
                                    self.logger,
                                    is_blocking=False)
         return False
 def unpause(self):
     # FIXME: Its ugly, need move to BirdwingConnector or better MakerBotAPI
     if self.pause_flag and "resume" in self.available_methods:
         self.makerbot.unpause_print()
         self.pause_flag = False
     else:
         config.create_error_report(704,
                                    "For now, cannot use command resume.",
                                    self.usb_info,
                                    self.logger,
                                    is_blocking=False)
         return False
 def load_json(self, jdata):
     try:
         data = json.loads(jdata)
     except ValueError:
         config.create_error_report(2, "Received data is not valid json: "
                                    + jdata, self.parent_usb_info, self.logger, is_blocking=False)
     else:
         if data and type(data) == dict:
             return data
         else:
             config.create_error_report(3, "Error parsing http message, data should be not empty dictionary: " +
                                        str(data), self.parent_usb_info, self.logger, is_blocking=False)
 def load_json(self, jdata):
     try:
         data = json.loads(jdata)
     except ValueError:
         config.create_error_report(2, "Received data is not valid json: "
                                    + jdata, self.parent_usb_info, self.logger, is_blocking=False)
     else:
         if data and type(data) == dict:
             return data
         else:
             config.create_error_report(3, "Error parsing http message, data should be not empty dictionary: " +
                                        str(data), self.parent_usb_info, self.logger, is_blocking=False)
 def set_groups(self, groups):
     if type(groups) == list:
         self.logger.info("Groups are set correctly for %s %s" %
                          (str(self.usb_info), str(groups)))
         self.groups = groups
     else:
         config.create_error_report(
             999,
             "Invalid workgroups format - type must be list: " +
             str(groups),
             self.usb_info,
             self.logger,
             is_blocking=False)
 def send(self, line, add_checksum=True):
     if add_checksum:
         line = self.add_line_number_and_checksum(line)
     # we need to do this before sending to avoid bugs when resent request change line number before +1
     self.sender.ready_for_command.clear()
     if self.sender.connection.send(line):
         if add_checksum:
             self.lines_sent += 1
         self.sender.analyze_sent_line(line)
     else:
         self.sender.ready_for_command.set()
         config.create_error_report(250, "Unable to write to serial port",
                                    self.sender.usb_info, self.logger, is_blocking=False)
 def load_gcodes(self, gcode_file):
     if not self.printing_flag:
         if not self.makerbot.put_file(gcode_file, self.REMOTE_URL_PATH_FILE):
             config.create_error_report(701, "Cannot upload file to printer",
                                        self.usb_info, self.logger, is_blocking=True)
             return
         if not self.makerbot.start_printing_file(self.REMOTE_URL_PATH_FILE):
             config.create_error_report(702, "Cannot start print",
                                        self.usb_info, self.logger, is_blocking=True)
             return
         self.logger.info("Success start print")
     else:
         return False
Beispiel #30
0
 def load_gcodes(self, gcodes):
     self.logger.info("Loading gcodes in ThreadedSender")
     with self.thread_start_lock:
         if (self.print_thread and self.print_thread.is_alive()):
             self.logger.info("Joining printing thread...")
             self.print_thread.join(timeout=self.PRINT_JOIN_TIMEOUT)
             if self.print_thread.is_alive():
                 message = "Can't start print cause already printing"
                 config.create_error_report(260, message, self.usb_info, self.logger, is_blocking=False)
                 return False
         self.print_thread = SDCardPrintThread(self)
         self.print_thread.load_gcodes(gcodes)
         self.print_thread.start()
         self.logger.info("Print thread started")
 def load_gcodes(self, gcodes):
     self.logger.info("Loading gcodes in ThreadedSender")
     with self.thread_start_lock:
         if (self.print_thread and self.print_thread.is_alive()):
             self.logger.info("Joining printing thread...")
             self.print_thread.join(timeout=self.PRINT_JOIN_TIMEOUT)
             if self.print_thread.is_alive():
                 message = "Can't start print cause already printing"
                 config.create_error_report(260, message, self.usb_info, self.logger, is_blocking=False)
                 return False
         self.print_thread = PrintThread(self)
         self.print_thread.load_gcodes(gcodes)
         self.print_thread.start()
         self.logger.info("Print thread started")
 def reading(self):
     last_ok_time = time.time()
     while not self.stop_flag:
         line = self.connection.recv()
         if self.parse_printer_answers(line):
             last_ok_time = time.time()
             if self.last_gcode_was_blocking_heating and not self.in_heating: # dropping in_heating flag
                 self.last_gcode_was_blocking_heating = False                 # after ok on next gcode
         elif not self.in_heating:
             self.in_heating = self.last_gcode_was_blocking_heating # assuming last ok was for blocking heating
             if last_ok_time > time.time() + self.OK_TIMEOUT:
                 message = "Warning! Timeout while waiting for ok. Must be printer error."
                 config.create_error_report(251, message, self.usb_info, self.logger, is_blocking=False)
                 last_ok_time = time.time()
 def pause(self):
     if self.print_thread:
         if not self.print_thread.paused:
             if self.in_heating:
                 message = "Can't pause during heating."
                 config.create_error_report(254, message, self.usb_info, self.logger, is_blocking=False)
                 return False
             self.print_thread.paused = True
             self.was_in_relative_before_pause = self.in_relative_pos_mode
             if not self.in_relative_pos_mode:
                 self.send_now("G91")
             self.send_now("G1 Z+%d E-%d" % (self.pause_lift_height, self.pause_extrude_length))
             return True
     return False
Beispiel #34
0
 def start_main_loop(
     self
 ):  #TODO cleanup from network and virtual code. main loop code should be short.
     self.detector = usb_detect.USBDetector()
     self.network_printers_detector = network_detect.NetworkDetector()
     self.last_time = 0
     while not self.stop_flag:
         self.updater.timer_check_for_updates()
         try:
             self.detected_printers = self.detector.get_printers_list()
         except Exception:
             self.logger.exception("USB detector error: ")
         else:
             if self.network_detect_flag:
                 self.network_printers = self.network_printers_detector.get_printers(
                 )
                 self.network_detect_flag = False
             for printer in self.network_printers:
                 if printer not in self.detected_printers:
                     self.detected_printers.append(printer)
             if self.virtual_printer_enabled:
                 self.detected_printers.append(
                     self.VIRTUAL_PRINTER_USB_INFO)
             self.connect_new_printers()
             for pi in self.printer_interfaces:
                 if pi.usb_info not in self.detected_printers:
                     if not pi.error_state == "error":
                         config.create_error_report(
                             99,
                             "Printer is no longer detected as USB device.",
                             pi.usb_info,
                             self.logger,
                             is_blocking=True)
                 if not pi.is_alive():
                     if not pi.stop_flag:
                         self.logger.warning(
                             "Printer interface of %s had crushed" %
                             pi.usb_info)
                     self.logger.info('Removing %s from printer list' %
                                      pi.usb_info)
                     self.printer_interfaces.remove(pi)
         if not self.stop_flag:
             time.sleep(self.MAIN_LOOP_SLEEP)
         now = time.time()
         if self.last_time + self.IDLE_RECORD_TIMEOUT > now:
             self.last_time = now
             self.logger.debug(
                 time.strftime("%d %b %Y %H:%M:%S", time.localtime()))
     self.quit()
 def run(self):
     self.logger.info('Starting downloading')
     downloaded_filename = self.start_download()
     if downloaded_filename:
         with open(downloaded_filename, 'rb') as f:
             self.base_sender.load_gcodes(f.read())
         self.logger.info('Gcodes loaded to memory, deleting temp file')
         try:
             os.remove(downloaded_filename)
         except:
             pass
     elif not self.cancel_flag:
         config.create_error_report(67, "Can't download gcodes",
                                    self.base_sender.usb_info, self.logger, is_blocking=False)
     self.logger.info('Downloading finished')
 def check_operational_state(self):
     if not self.printer or self.stop_flag:
         pass
     elif self.printer.stop_flag:
         pass
     elif self.printer.is_operational(): #TODO check this operation for thread safety
         self.last_operational_time = time.time()
         self.error_state = None
         self.last_errors = []
     elif not self.error_state:
         message = "Printer is not operational"
         config.create_error_report(77, message, self.usb_info, self.logger, is_blocking=False)
     elif self.error_state != "error" and self.last_operational_time + self.READY_TIMEOUT < time.time():
         message = "Not operational timeout reached"
         config.create_error_report(78, message, self.usb_info, self.logger, is_blocking=True)
 def connect_to_printer(self):
     printer_sender = __import__(self.printer_profile['sender'])
     self.logger.info("Connecting with profile: " + str(self.printer_profile))
     try:
         printer = printer_sender.Sender(self.printer_profile, self.usb_info)
     except RuntimeError as e:
         message = "Can't connect to printer %s %s\nReason: %s" %\
                   (self.printer_profile['name'], str(self.usb_info), e.message)
         config.create_error_report(119, message, self.usb_info, self.logger, is_blocking=True)
     except Exception as e:
         message = "Unexpected error while connecting to %s: %s" % (self.printer_profile['name'], str(e))
         config.create_error_report(129, message, self.usb_info, self.logger, is_blocking=True)
     else:
         self.logger.info("Successful connection to %s!" % (self.printer_profile['name']))
         return printer
Beispiel #38
0
 def send(self, line, add_checksum=True):
     if add_checksum:
         line = self.add_line_number_and_checksum(line)
     # we need to do this before sending to avoid bugs when resent request change line number before +1
     self.sender.ready_for_command.clear()
     if self.sender.connection.send(line):
         if add_checksum:
             self.lines_sent += 1
         self.sender.analyze_sent_line(line)
     else:
         self.sender.ready_for_command.set()
         config.create_error_report(250,
                                    "Unable to write to serial port",
                                    self.sender.usb_info,
                                    self.logger,
                                    is_blocking=False)
 def connect(self):
     self.logger.debug("{ Connecting...")
     try:
         if self.HTTPS_MODE:
             connection = httplib.HTTPSConnection(self.URL, port = 443, timeout = CONNECTION_TIMEOUT)
         else:
             connection = httplib.HTTPConnection(self.URL, port = 80, timeout = CONNECTION_TIMEOUT)
         connection.connect()
     except Exception as e:
         config.create_error_report(5, "Error during HTTP connection: " + str(e),
                                    self.parent_usb_info, self.logger, is_blocking=False)
         self.logger.debug("...failed }")
         self.logger.warning("Warning: connection to %s failed." % self.URL)
     else:
         self.logger.debug("...success }")
         return connection
 def send(self, line, add_checksum=True, force_line_number=None):
     if add_checksum and not self.no_checksums:
         if not force_line_number is None:
             line = self.add_line_number_and_checksum(line, force_line_number=force_line_number)
         else:
             line = self.add_line_number_and_checksum(line)
     # we need to do this before sending to avoid bugs when resent request change line number before +1
     self.sender.ready_for_command = False
     if add_checksum and not force_line_number:
         self.lines_sent += 1
     if self.sender.connection.send(line):
         self.sender.analyze_sent_line(line)
     else:
         self.sender.ready_for_command = True
         config.create_error_report("Unable to write to serial port", 250,
                                    self.sender.usb_info, self.logger, is_blocking=False)
 def connect_to_server(self): #TODO REMOVE THIS UGLY METHOD - connection must server command, like gcodes or pause
     self.logger.info("Connecting to server with printer: %s" % str(self.usb_info))
     self.http_client = http_client.HTTPClient(self, keep_connection_flag=True)
     while not self.stop_flag:
         external_errors = self.get_my_errors()
         if filter(lambda error: error['is_blocking'], external_errors):
             self.stop_flag = True
             return False
         message = ['printer_login', self.user_token, self.usb_info]
         kw_message = {}
         if self.printer_type_selection_request:
             kw_message['select_printer_type'] = self.printer_type_selection_request
         self.logger.debug('Printer login request:\n%s\n%s ' % (str(message), str(kw_message)))
         answer = self.http_client.pack_and_send(*message, **kw_message)
         if answer:
             error = answer.get('error')
             self.printer_name = answer.get('name', '')
             if error:
                 self.logger.warning("Error while login %s:" % str((self.user_token, self.usb_info)))
                 self.logger.warning(str(error['code']) + " " + error["message"])
                 if str(error['code']) == '8':
                     self.show_printer_type_selector = True
                     time.sleep(1)
                     continue
                 else:
                     config.create_error_report(26, "Server had returned error: %s" % str(error))
                     return False
             elif answer.get('printer_profile') == "":
                 config.create_error_report(62, "Server return message with empty printer_profile field: %s" % str(error))
             else:
                 groups = answer.get('current_groups', [])
                 self.set_groups(groups)
                 self.printer_type_selection_request = None
                 self.show_printer_type_selector = False
                 self.printer_rename_request = False
                 self.logger.info('Successfully connected to server.')
                 self.printer_token = answer['printer_token']
                 self.logger.info('Received answer: ' + str(answer))
                 self.printer_profile = json.loads(answer["printer_profile"])
                 custom_timeout = self.printer_profile.get("operational_timeout", None)
                 if custom_timeout:
                     self.READY_TIMEOUT = custom_timeout
                 self.logger.debug('Setting profile: ' + str(self.printer_profile))
                 return True
         else:
             self.logger.warning("Error on printer login. No connection or answer from server.")
             time.sleep(0.1)
 def cancel(self):
     if self.cancel_download():
         return
     self.stop_flag = True
     if self.print_thread:
         self.print_thread.cancel()
         self.print_thread.join()
     self.read_thread.join()
     self.temperature_request_thread.join()
     self.reset()
     self.stop_flag = False
     try:
         self.init()
         self.logger.info("Successful cancel")
     except RuntimeError:
         message = "Can't reconnect to printer after cancel."
         config.create_error_report(255, message, self.usb_info, self.logger, is_blocking=True)
 def update(self):
     if self.update_flag:
         self.logger.info('Updating client...')
         update_file_name = config.get_settings()['update']['update_file_name']
         try:
             urllib.urlretrieve(config.get_settings()['update']['update_file_url'] + update_file_name, update_file_name)
         except Exception as e:
             error_message = 'Update failed!\nReason: error while downloading.\nDetails: ' + str(e)
             config.create_error_report(0, error_message, None, self.logger, is_blocking=True)
             return error_message
         else:
             error = self.extract_update(update_file_name)
             if error:
                 return error
             self.logger.info('...client successfully updated!')
             self.update_flag = False
             log.send_logs()
             log.clear_logs()
 def downloading_loop(self, request, download_length):
     # Taking +1 byte with each chunk to compensate file length tail less than 100 bytes when dividing by 100
     percent_length = download_length / 100 + 1
     total_size = 0
     try:
         for chunk in request.iter_content(percent_length):
             if self.cancel_flag or self.base_sender.stop_flag:
                 self.logger.info('Download canceled')
                 break
             self.tmp_file.write(chunk)
             self.percent += 1
             total_size += len(chunk)
             self.logger.info('File downloading : %d%%' % self.percent)
     except Exception as e:
         config.create_error_report(66, 'Error while downloading: ' + str(e.message),
                                    self.base_sender.usb_info, self.logger, is_blocking=False)
     finally:
         return total_size
Beispiel #45
0
 def reading(self):
     last_ok_time = time.time()
     while not self.stop_flag:
         line = self.connection.recv()
         if self.parse_printer_answers(line):
             last_ok_time = time.time()
             if self.last_gcode_was_blocking_heating and not self.in_heating:  # dropping in_heating flag
                 self.last_gcode_was_blocking_heating = False  # after ok on next gcode
         elif not self.in_heating:
             self.in_heating = self.last_gcode_was_blocking_heating  # assuming last ok was for blocking heating
             if last_ok_time > time.time() + self.OK_TIMEOUT:
                 message = "Warning! Timeout while waiting for ok. Must be printer error."
                 config.create_error_report(251,
                                            message,
                                            self.usb_info,
                                            self.logger,
                                            is_blocking=False)
                 last_ok_time = time.time()
Beispiel #46
0
 def close(self):
     self.logger.info("Makerbot sender is closing...")
     self.stop_flag = True
     if threading.current_thread() != self.sending_thread:
         self.sending_thread.join(10)
         if self.sending_thread.isAlive():
             config.create_error_report(301, "Failed to join printing thread in makerbot_printer",
                                        self.usb_info, self.logger, is_blocking=True)
     if self.parser:
         if self.parser.s3g:
             try:
                 self.parser.s3g.abort_immediately()
             except Exception:
                 pass
             time.sleep(0.1)
             self.parser.s3g.close()
     self.is_running = False
     self.logger.info("...done closing makerbot sender.")
Beispiel #47
0
 def log_strange_acks(self, line):
     if self.print_thread:
         if "Done printing file" in line:
             self.print_thread.print_thread_flag = False
             self.print_thread.lines_sent = self.print_thread.total_gcodes
         elif "SD printing" in line:
             progress_match = self.progress_re.match(line)
             if progress_match:
                 self.print_thread.lines_sent = int(progress_match.group(1))
                 self.print_thread.total_gcodes = int(progress_match.group(2))
                 if self.print_thread.total_gcodes > 0:
                     if self.print_thread.lines_sent >= self.print_thread.total_gcodes:
                         self.print_thread.print_thread_flag = False
     elif "error" in line or "failed" in line:
         self.operational_flag = False
         config.create_error_report(900, line, self.usb_info, self.logger, is_blocking=True)
     else:
         self.logger.warning("Received strange answer: " + line.strip())
Beispiel #48
0
 def run(self):
     self.logger.info('Starting downloading')
     downloaded_filename = self.start_download()
     if downloaded_filename:
         with open(downloaded_filename, 'rb') as f:
             self.base_sender.load_gcodes(f.read())
         self.logger.info('Gcodes loaded to memory, deleting temp file')
         try:
             os.remove(downloaded_filename)
         except:
             pass
     elif not self.cancel_flag:
         config.create_error_report(67,
                                    "Can't download gcodes",
                                    self.base_sender.usb_info,
                                    self.logger,
                                    is_blocking=False)
     self.logger.info('Downloading finished')
Beispiel #49
0
 def parse_printer_answers(self, line):
     if line is None:  # None means error reading from printer, but "" is ok
         self.operational_flag = False
         time.sleep(self.PAUSE_ON_ERROR_READING_PORT)
     elif not line or "wait" in line:
         if self.extra_oks:
             self.extra_oks -= 1
             self.ready_for_command.set()
         return  # return is needed here for faster the parsing
     elif self.is_ok(line):
         self.operational_flag = True
         self.check_temperature_and_position(line)
         if self.ready_for_command.is_set():
             self.extra_oks += 1
             self.logger.info(
                 "Warning: double ok was received. Extra oks counter is now: %d"
                 % self.extra_oks)
         self.ready_for_command.set()
         return self.last_line_sent != self.GET_TEMP_GCODE  # M105 should not be affect anti-stuck code mechanism
     elif line[0] == "T" or (len(line) > 1 and line[1] == "T"):
         self.parse_waiting_temperature_updates(line)
         self.operational_flag = True
     elif self.check_for_resend_requests(line):
         self.logger.debug(line)
         self.logger.info("Last_line: " + self.last_line_sent)
         self.operational_flag = True
         self.ready_for_command.set()
     elif line.startswith('Error'):
         self.logger.debug(line)
         self.logger.info("Last_line: " + self.last_line_sent)
         if not ("checksum" in line or "Checksum" in line or "expected line"
                 in line or "Line Number is not Last Line Number+1" in line
                 or "Format error" in line):
             is_blocking = self.BOARD_RESET_GCODE in line or "disabling all for safety!" in line
             self.operational_flag = False
             config.create_error_report(201,
                                        line,
                                        self.usb_info,
                                        self.logger,
                                        is_blocking=is_blocking)
     elif line.startswith('DEBUG'):
         self.logger.info(line)
     else:
         self.log_strange_acks(line)
Beispiel #50
0
 def start_download(self):
     self.logger.info("Downloading from " + self.url)
     self.tmp_file = tempfile.NamedTemporaryFile(mode='wb',
                                                 delete=False,
                                                 prefix='3dprinteros-',
                                                 suffix='.gcode')
     resume_byte_pos = 0
     retry = 0
     while retry < self.MAX_RETRIES and not self.base_sender.stop_flag and not self.cancel_flag:
         if retry:
             self.logger.warning("Download retry/resume N%d" % retry)
         self.logger.info("Connecting to " + self.url)
         resume_header = {'Range': 'bytes=%d-' % resume_byte_pos}
         try:
             request = requests.get(self.url,
                                    headers=resume_header,
                                    stream=True,
                                    timeout=self.timeout)
         except Exception as e:
             request = None
             config.create_error_report(65,
                                        "Unable to open download link: " +
                                        str(e),
                                        self.base_sender.usb_info,
                                        self.logger,
                                        is_blocking=False)
         else:
             self.increase_timeout()
             self.logger.info("Successful connection to " + self.url)
             download_length = int(request.headers.get('content-length', 0))
             if download_length:
                 downloaded_size = self.downloading_loop(
                     request, download_length)
                 resume_byte_pos += downloaded_size
                 self.logger.info("Downloaded %d bytes" % resume_byte_pos)
                 if downloaded_size == download_length:
                     self.tmp_file.close()
                     return self.tmp_file.name
         finally:
             if request:
                 request.close()
             retry += 1
             time.sleep(1)
     self.tmp_file.close()
 def execute_server_command(self, server_message):
     number, command, payload = server_message['number'], server_message['command'], server_message.get('payload')
     self.logger.info("Executing command number %i : %s" % (number, str(command)))
     method = getattr(self.printer, command)
     arguments = []
     if payload:
         arguments.append(payload)
     if server_message.get('is_link'):
         arguments.append(True)
     try:
         result = method(*arguments)
         # to reduce needless return True, we assume that when method had return None, that is success
         result = result or result == None
     except Exception as e:
         config.create_error_report(109, "Error while executing command %s, number %d.\t%s" %
                                    (command, number, e.message), self.usb_info, self.logger, is_blocking=False)
         result = False
     ack = { "number": number, "result": result }
     return ack
 def check_server_command(self, server_message):
     if self.last_error:
         if server_message.get('command'):
             self.logger.error("! Server returns command on request containing an error - this is error.")
             return { "number": server_message.get('number'), "result": False }
     error = server_message.get('error')
     if error:
         self.logger.warning("@ Error in server message:%s\t%s" % (str(error['code']), error['message']))
     command = server_message.get('command')
     if command:
         method = getattr(self.printer, command, None)
         if type(server_message.get('number')) != int:
             message = "Error in number field of server's message: " + str(server_message)
             config.create_error_report(41, message, self.logger, is_blocking=False)
         elif not method:
             config.create_error_report(40, "Unknown command:'%s' " % str(command),
                                        self.usb_info, self.logger, is_blocking=False)
         else:
             return self.execute_server_command(server_message)
Beispiel #53
0
 def execute(self, command):
     buffer_overflow_counter = 0
     retry_count = 0
     while not self.stop_flag:
         if buffer_overflow_counter > self.BUFFER_OVERFLOWS_BETWEEN_STATE_UPDATE:
             self.logger.info('Makerbot BufferOverflow on ' + text)
             buffer_overflow_counter = 0
             self.read_state()
         try:
             command_is_gcode = isinstance(command, str)
             self.execution_lock.acquire()
             if command_is_gcode:
                 if self.cancel_flag:
                     self.cancel_flag = False
                     break
                 text = command
                 self.printing_flag = True
                 self.parser.execute_line(command)
                 self.set_target_temps(command)
                 #self.logger.debug("Executing: " + command)
                 result = None
             else:
                 text = command.__name__
                 result = command()
         except (makerbot_driver.BufferOverflowError):
             buffer_overflow_counter += 1
             time.sleep(self.BUFFER_OVERFLOW_WAIT)
         except serial.serialutil.SerialException:
             self.logger.warning("Makerbot is retrying %i %s" % (retry_count, text))
             retry_count += 1
             if retry_count > self.MAX_RETRY_BEFORE_ERROR:
                 config.create_error_report(302, "Makerbot can't continue because max retry of %s" % text,
                                            self.usb_info, self.logger, is_blocking=True)
                 self.close()
         except Exception as e:
             config.create_error_report(303, "Makerbot can't continue because of: %s %s" % (str(e), e.message),
                                        self.usb_info, self.logger, is_blocking=True)
             self.close()
         else:
             return result
         finally:
             self.execution_lock.release()
 def send(self, line, add_checksum=True, force_line_number=None):
     if add_checksum and not self.no_checksums:
         if not force_line_number is None:
             line = self.add_line_number_and_checksum(
                 line, force_line_number=force_line_number)
         else:
             line = self.add_line_number_and_checksum(line)
     # we need to do this before sending to avoid bugs when resent request change line number before +1
     self.sender.ready_for_command = False
     if add_checksum and not force_line_number:
         self.lines_sent += 1
     if self.sender.connection.send(line):
         self.sender.analyze_sent_line(line)
     else:
         self.sender.ready_for_command = True
         config.create_error_report("Unable to write to serial port",
                                    250,
                                    self.sender.usb_info,
                                    self.logger,
                                    is_blocking=False)
Beispiel #55
0
 def pause(self):
     if self.print_thread:
         if not self.print_thread.paused:
             if self.in_heating:
                 message = "Can't pause during heating."
                 config.create_error_report(254,
                                            message,
                                            self.usb_info,
                                            self.logger,
                                            is_blocking=False)
                 return False
             self.print_thread.paused = True
             self.was_in_relative_before_pause = self.in_relative_pos_mode
             if not self.in_relative_pos_mode:
                 self.send_now("G91")
             self.send_now(
                 "G1 Z+%d E-%d" %
                 (self.pause_lift_height, self.pause_extrude_length))
             return True
     return False
 def send(self, path, data):
     while True:
         if not self.connection:
             self.connection = self.connect()
         if self.connection:
             answer = self.request("POST", self.connection, path, data)
             if not self.keep_connection_flag:
                 self.connection.close()
                 self.connection = None
             if answer:
                 self.fails = 0
                 return self.load_json(answer)
         self.fails += 1
         time.sleep(1)
         if self.fails > self.MAX_HTTP_FAILS:
             self.fails = 0
             if self.connection:
                 self.connection.close()
                 self.connection = None
             config.create_error_report(9, 'HTTP error: max request retry.', None, self.logger, is_blocking=False)
             break