2017-06-27 20:23:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								#!/usr/bin/env python2
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# Main code for host side printer firmware
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 21:42:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								# Copyright (C) 2016-2020  Kevin O'Connor <kevin@koconnor.net>
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								#
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# This file may be distributed under the terms of the GNU GPLv3 license.
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 21:42:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import sys, os, gc, optparse, logging, time, threading, collections, importlib
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-06 10:22:14 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import util, reactor, queuelogger, msgproto, homing
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-19 06:18:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								import gcode, configfile, pins, mcu, toolhead, webhooks
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-11 22:21:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								message_ready = "Printer is ready"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								message_startup = """
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-12 23:12:39 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Printer is not ready
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								The klippy host software is attempting to connect.  Please
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								retry in a few moments.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								message_restart = """
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 23:47:40 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Once the underlying issue is corrected, use the "RESTART"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								command to reload the config and restart the host software.
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Printer is halted
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-09 23:50:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								message_protocol_error = """
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								This type of error is frequently caused by running an older
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								version of the firmware on the micro-controller (fix by
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								recompiling and flashing the firmware).
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Once the underlying issue is corrected, use the "RESTART"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								command to reload the config and restart the host software.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Protocol error connecting to printer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								message_mcu_connect_error = """
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-08 22:26:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Once the underlying issue is corrected, use the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								"FIRMWARE_RESTART" command to reset the firmware, reload the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								config, and restart the host software.
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Error configuring printer
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								message_shutdown = """
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-13 14:53:41 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Once the underlying issue is corrected, use the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								"FIRMWARE_RESTART" command to reset the firmware, reload the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								config, and restart the host software.
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Printer is shutdown
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								"""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class Printer:
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-04 20:49:47 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    config_error = configfile.error
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-06 10:22:14 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    command_error = homing.CommandError
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 12:15:19 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def __init__(self, main_reactor, bglogger, start_args):
							 | 
						
					
						
							
								
									
										
										
										
											2017-05-01 13:44:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.bglogger = bglogger
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.start_args = start_args
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 12:15:19 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.reactor = main_reactor
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-02 12:43:40 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.reactor.register_callback(self._connect)
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.state_message = message_startup
							 | 
						
					
						
							
								
									
										
										
										
											2020-04-25 12:41:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.in_shutdown_state = False
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 23:47:40 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.run_result = None
							 | 
						
					
						
							
								
									
										
										
										
											2018-10-07 12:22:10 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.event_handlers = {}
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-19 06:18:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.objects = collections.OrderedDict()
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-04 16:00:23 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Init printer components that must be setup prior to config
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-11 21:21:41 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        for m in [gcode, webhooks]:
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-04 16:00:23 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            m.add_early_printer_objects(self)
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def get_start_args(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self.start_args
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 22:22:17 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def get_reactor(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self.reactor
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def get_state_message(self):
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-23 07:56:50 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.state_message == message_ready:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            category = "ready"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        elif self.state_message == message_startup:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            category = "startup"
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-16 14:08:38 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        elif self.in_shutdown_state:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            category = "shutdown"
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-23 07:56:50 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            category = "error"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self.state_message, category
							 | 
						
					
						
							
								
									
										
										
										
											2020-04-25 12:41:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def is_shutdown(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self.in_shutdown_state
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _set_state(self, msg):
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-11 12:36:09 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.state_message in (message_ready, message_startup):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.state_message = msg
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (msg != message_ready
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            and self.start_args.get('debuginput') is not None):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.request_exit('error_exit')
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 22:22:17 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def add_object(self, name, obj):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if obj in self.objects:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise self.config_error(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                "Printer object '%s' already created" % (name,))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.objects[name] = obj
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-04 20:49:47 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def lookup_object(self, name, default=configfile.sentinel):
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 22:22:17 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if name in self.objects:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return self.objects[name]
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-04 20:49:47 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if default is configfile.sentinel:
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 22:22:17 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            raise self.config_error("Unknown config object '%s'" % (name,))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return default
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-02 12:51:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def lookup_objects(self, module=None):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if module is None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return list(self.objects.items())
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        prefix = module + ' '
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        objs = [(n, self.objects[n])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for n in self.objects if n.startswith(prefix)]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if module in self.objects:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return [(module, self.objects[module])] + objs
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 22:22:17 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        return objs
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-05 14:10:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def load_object(self, config, section, default=configfile.sentinel):
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 21:25:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if section in self.objects:
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-14 12:00:55 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            return self.objects[section]
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-03 12:53:11 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        module_parts = section.split()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        module_name = module_parts[0]
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 21:25:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        py_name = os.path.join(os.path.dirname(__file__),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                               'extras', module_name + '.py')
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-27 13:01:48 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        py_dirname = os.path.join(os.path.dirname(__file__),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                  'extras', module_name, '__init__.py')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if not os.path.exists(py_name) and not os.path.exists(py_dirname):
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-05 14:10:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if default is not configfile.sentinel:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return default
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise self.config_error("Unable to load module '%s'" % (section,))
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 21:25:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        mod = importlib.import_module('extras.' + module_name)
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-03 12:53:11 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        init_func = 'load_config'
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if len(module_parts) > 1:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            init_func = 'load_config_prefix'
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        init_func = getattr(mod, init_func, None)
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-05 14:10:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if init_func is None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if default is not configfile.sentinel:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                return default
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise self.config_error("Unable to load module '%s'" % (section,))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.objects[section] = init_func(config.getsection(section))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self.objects[section]
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-03 12:17:42 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _read_config(self):
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-04 20:49:47 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.objects['configfile'] = pconfig = configfile.PrinterConfig(self)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        config = pconfig.read_main_config()
							 | 
						
					
						
							
								
									
										
										
										
											2017-05-01 13:44:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.bglogger is not None:
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-04 20:49:47 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            pconfig.log_config(config)
							 | 
						
					
						
							
								
									
										
										
										
											2017-04-29 13:57:02 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Create printer components
							 | 
						
					
						
							
								
									
										
										
										
											2020-04-25 13:27:41 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        for m in [pins, mcu]:
							 | 
						
					
						
							
								
									
										
										
										
											2018-07-12 22:26:32 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            m.add_printer_objects(config)
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-04 20:49:47 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        for section_config in config.get_prefix_sections(''):
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-05 14:10:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self.load_object(config, section_config.get_name(), None)
							 | 
						
					
						
							
								
									
										
										
										
											2018-07-12 22:15:45 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        for m in [toolhead]:
							 | 
						
					
						
							
								
									
										
										
										
											2018-07-12 22:26:32 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            m.add_printer_objects(config)
							 | 
						
					
						
							
								
									
										
										
										
											2017-03-12 22:43:05 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Validate that there are no undefined parameters in the config file
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-04 20:49:47 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        pconfig.check_unused_options(config)
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-26 00:13:36 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def _connect(self, eventtime):
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        try:
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-03 12:17:42 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self._read_config()
							 | 
						
					
						
							
								
									
										
										
										
											2019-11-04 23:00:00 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self.send_event("klippy:mcu_identify")
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 11:09:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            for cb in self.event_handlers.get("klippy:connect", []):
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-19 22:49:27 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if self.state_message is not message_startup:
							 | 
						
					
						
							
								
									
										
										
										
											2018-10-18 12:49:26 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    return
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 11:09:55 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                cb()
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-06 14:51:47 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        except (self.config_error, pins.error) as e:
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:57:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            logging.exception("Config error")
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self._set_state("%s%s" % (str(e), message_restart))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 13:46:26 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            return
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-09 23:32:49 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        except msgproto.error as e:
							 | 
						
					
						
							
								
									
										
										
										
											2017-01-09 23:50:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            logging.exception("Protocol error")
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self._set_state("%s%s" % (str(e), message_protocol_error))
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-22 13:20:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            util.dump_mcu_build()
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 13:46:26 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            return
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-09 23:32:49 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        except mcu.error as e:
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            logging.exception("MCU error during connect")
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self._set_state("%s%s" % (str(e), message_mcu_connect_error))
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-22 13:20:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            util.dump_mcu_build()
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 13:46:26 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            return
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-04 18:37:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        except Exception as e:
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 14:30:45 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            logging.exception("Unhandled exception during connect")
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-17 01:59:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self._set_state("Internal error during connect: %s\n%s"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            % (str(e), message_restart,))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 13:46:26 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            return
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 10:55:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self._set_state(message_ready)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for cb in self.event_handlers.get("klippy:ready", []):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if self.state_message is not message_ready:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    return
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                cb()
							 | 
						
					
						
							
								
									
										
										
										
											2019-04-04 18:37:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        except Exception as e:
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 10:55:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            logging.exception("Unhandled exception during ready callback")
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-17 01:59:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self.invoke_shutdown("Internal error during ready callback: %s"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                 % (str(e),))
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-28 13:14:56 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def run(self):
							 | 
						
					
						
							
								
									
										
										
										
											2017-02-06 13:31:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        systime = time.time()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        monotime = self.reactor.monotonic()
							 | 
						
					
						
							
								
									
										
										
										
											2017-09-27 11:43:14 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        logging.info("Start printer at %s (%.1f %.1f)",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                     time.asctime(time.localtime(systime)), systime, monotime)
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-12 19:11:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Enter main reactor loop
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.reactor.run()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        except:
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-06 12:45:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            msg = "Unhandled exception during run"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            logging.exception(msg)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # Exception from a reactor callback - try to shutdown
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.reactor.register_callback((lambda e:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                self.invoke_shutdown(msg)))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.reactor.run()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            except:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                logging.exception("Repeat unhandled exception during run")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # Another exception - try to exit
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.run_result = "error_exit"
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-12 19:11:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Check restart flags
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        run_result = self.run_result
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if run_result == 'firmware_restart':
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for n, m in self.lookup_objects(module='mcu'):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    m.microcontroller_restart()
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 10:55:18 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self.send_event("klippy:disconnect")
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-12 19:11:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        except:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            logging.exception("Unhandled exception during post run")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return run_result
							 | 
						
					
						
							
								
									
										
										
										
											2020-05-05 13:57:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def set_rollover_info(self, name, info, log=True):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if log:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            logging.info(info)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.bglogger is not None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.bglogger.set_rollover_info(name, info)
							 | 
						
					
						
							
								
									
										
										
										
											2017-12-03 18:13:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def invoke_shutdown(self, msg):
							 | 
						
					
						
							
								
									
										
										
										
											2020-04-25 12:41:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.in_shutdown_state:
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-12 15:15:14 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            return
							 | 
						
					
						
							
								
									
										
										
										
											2020-03-24 08:37:36 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        logging.error("Transition to shutdown state: %s", msg)
							 | 
						
					
						
							
								
									
										
										
										
											2020-04-25 12:41:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.in_shutdown_state = True
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self._set_state("%s%s" % (msg, message_shutdown))
							 | 
						
					
						
							
								
									
										
										
										
											2019-01-08 09:15:40 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        for cb in self.event_handlers.get("klippy:shutdown", []):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                cb()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            except:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                logging.exception("Exception during shutdown handler")
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-17 01:59:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        logging.info("Reactor garbage collection: %s",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                     self.reactor.get_gc_stats())
							 | 
						
					
						
							
								
									
										
										
										
											2017-10-12 15:15:14 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def invoke_async_shutdown(self, msg):
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-02 12:43:40 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.reactor.register_async_callback(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            (lambda e: self.invoke_shutdown(msg)))
							 | 
						
					
						
							
								
									
										
										
										
											2018-10-07 12:22:10 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def register_event_handler(self, event, callback):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.event_handlers.setdefault(event, []).append(callback)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def send_event(self, event, *params):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return [cb(*params) for cb in self.event_handlers.get(event, [])]
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def request_exit(self, result):
							 | 
						
					
						
							
								
									
										
										
										
											2019-06-27 18:32:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.run_result is None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.run_result = result
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 23:47:40 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.reactor.end()
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								######################################################################
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								# Startup
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								######################################################################
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-14 11:46:35 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								def arg_dictionary(option, opt_str, value, parser):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    key, fname = "dictionary", value
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if '=' in value:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        mcu_name, fname = value.split('=', 1)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        key = "dictionary_" + mcu_name
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if parser.values.dictionary is None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        parser.values.dictionary = {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    parser.values.dictionary[key] = fname
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								def main():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    usage = "%prog [options] <config file>"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    opts = optparse.OptionParser(usage)
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    opts.add_option("-i", "--debuginput", dest="debuginput",
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    help="read commands from file instead of from tty port")
							 | 
						
					
						
							
								
									
										
										
										
											2019-02-27 13:18:43 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    opts.add_option("-I", "--input-tty", dest="inputtty",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    default='/tmp/printer',
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-20 20:40:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    help="input tty name (default is /tmp/printer)")
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-11 16:26:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    opts.add_option("-a", "--api-server", dest="apiserver",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    help="api server unix domain socket filename")
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    opts.add_option("-l", "--logfile", dest="logfile",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    help="write log to file instead of stderr")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    opts.add_option("-v", action="store_true", dest="verbose",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    help="enable debug messages")
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    opts.add_option("-o", "--debugoutput", dest="debugoutput",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    help="write output to file instead of to serial port")
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-14 11:46:35 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    opts.add_option("-d", "--dictionary", dest="dictionary", type="string",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    action="callback", callback=arg_dictionary,
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    help="file to read for mcu protocol dictionary")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    options, args = opts.parse_args()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if len(args) != 1:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        opts.error("Incorrect number of arguments")
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-11 16:26:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    start_args = {'config_file': args[0], 'apiserver': options.apiserver,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                  'start_reason': 'startup'}
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    debuglevel = logging.INFO
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if options.verbose:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        debuglevel = logging.DEBUG
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if options.debuginput:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        start_args['debuginput'] = options.debuginput
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        debuginput = open(options.debuginput, 'rb')
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-04 15:47:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        start_args['gcode_fd'] = debuginput.fileno()
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-20 20:40:31 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    else:
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-04 15:47:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        start_args['gcode_fd'] = util.create_pty(options.inputtty)
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if options.debugoutput:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        start_args['debugoutput'] = options.debugoutput
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-14 11:46:35 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        start_args.update(options.dictionary)
							 | 
						
					
						
							
								
									
										
										
										
											2020-08-04 15:47:25 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    bglogger = None
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if options.logfile:
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-19 06:18:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        start_args['log_file'] = options.logfile
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-11 20:22:39 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        bglogger = queuelogger.setup_bg_logging(options.logfile, debuglevel)
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        logging.basicConfig(level=debuglevel)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    logging.info("Starting Klippy...")
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    start_args['software_version'] = util.get_git_version()
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-19 06:18:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    start_args['cpu_info'] = util.get_cpu_info()
							 | 
						
					
						
							
								
									
										
										
										
											2017-05-01 13:44:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if bglogger is not None:
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-03 12:13:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        versions = "\n".join([
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "Args: %s" % (sys.argv,),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "Git version: %s" % (repr(start_args['software_version']),),
							 | 
						
					
						
							
								
									
										
										
										
											2020-06-19 06:18:58 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "CPU: %s" % (start_args['cpu_info'],),
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-03 12:13:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "Python: %s" % (repr(sys.version),)])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        logging.info(versions)
							 | 
						
					
						
							
								
									
										
										
										
											2019-09-01 18:09:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    elif not options.debugoutput:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        logging.warning("No log file specified!"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        " Severe timing issues may result!")
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 22:23:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    gc.disable()
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # Start Printer() class
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 23:47:40 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    while 1:
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-03 12:13:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if bglogger is not None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            bglogger.clear_rollover_info()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            bglogger.set_rollover_info('versions', versions)
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 21:42:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        gc.collect()
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 22:23:44 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        main_reactor = reactor.Reactor(gc_checking=True)
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 12:15:19 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        printer = Printer(main_reactor, bglogger, start_args)
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-30 23:47:40 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        res = printer.run()
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if res in ['exit', 'error_exit']:
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            break
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        time.sleep(1.)
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 12:15:19 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        main_reactor.finalize()
							 | 
						
					
						
							
								
									
										
										
										
											2020-09-16 21:42:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        main_reactor = printer = None
							 | 
						
					
						
							
								
									
										
										
										
											2017-08-21 17:19:43 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        logging.info("Restarting printer")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        start_args['start_reason'] = res
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-11 20:22:39 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if bglogger is not None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        bglogger.stop()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-16 15:15:17 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if res == 'error_exit':
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        sys.exit(-1)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-05-25 11:37:40 -04:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								if __name__ == '__main__':
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    main()
							 |