Multiple printers (#85)
* screen/printer_select/splash_screen: Updates to allow changing between moonraker instances * Updates to multiple printers * settings: Display printer endpoints * Update macros to be on a per-printer basis * files: Changes to clear out file cache on printer switch * job_status: Redo page for action bar * splash_screen: Change icon * websocket: Actually close the websocket * printer: Fix error case * splash_screen: show buttons update * readme update
This commit is contained in:
parent
dd08d3d9c8
commit
5e31e3cfa6
25
README.md
25
README.md
@ -1,21 +1,9 @@
|
|||||||
# KlipperScreen
|
# KlipperScreen
|
||||||
KlipperScreen is an idea based from [OctoScreen](https://github.com/Z-Bolt/OctoScreen/), but instead of needing OctoPrint or to compile go, KlipperScreen is python based and interacts directly with [Moonraker](https://github.com/arksine/moonraker), Klipper's API service.
|
|
||||||
|
|
||||||
Current feature list:
|
KlipperScreen is touchscreen GUI for Klipper based 3D printers. KlipperScreen interfaces with [Klipper](https://github.com/KevinOConner/klipper) via [Moonraker](https://github.com/arksine/moonraker).
|
||||||
- [x] Homing
|
|
||||||
- [x] Preheating
|
Multiple printers update is here! Please check the configuration information for specifying several printers.
|
||||||
- [x] Job Status and control
|
|
||||||
- [x] Temperature control
|
|
||||||
- [x] Extrude control
|
|
||||||
- [x] Fan control
|
|
||||||
- [x] Disable steppers
|
|
||||||
- [x] Configure Z Offset using PROBE_CALIBRATE
|
|
||||||
- [x] Print tuning (Z Babystepping, Speed Control, Flow Control)
|
|
||||||
- [x] Manual bed leveling assist
|
|
||||||
- [x] Using thumbnails from prusa on job status page
|
|
||||||
- [x] Scale UI based off of resolution
|
|
||||||
- [ ] Better system panel
|
|
||||||
- [ ] Wifi selection
|
|
||||||
|
|
||||||
[Changelog](docs/changelog.md)
|
[Changelog](docs/changelog.md)
|
||||||
|
|
||||||
@ -43,3 +31,8 @@ Main Menu
|
|||||||
|
|
||||||
Job Status
|
Job Status
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
### Inspiration
|
||||||
|
KlipperScreen was inspired by [OctoScreen](https://github.com/Z-Bolt/OctoScreen/) and the need for a touchscreen GUI that
|
||||||
|
will natively work with [Klipper](https://github.com/KevinOConner/klipper) and [Moonraker](https://github.com/arksine/moonraker).
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
#### 2021 03 05
|
||||||
|
* Multiple printers are now available in the main branch.
|
||||||
|
|
||||||
#### 2021 02 22
|
#### 2021 02 22
|
||||||
* Add configurable z_babystep intervals
|
* Add configurable z_babystep intervals
|
||||||
* Add QUAD_GANTRY_LEVEL and Z_TILT_ADJUST to Homing menu
|
* Add QUAD_GANTRY_LEVEL and Z_TILT_ADJUST to Homing menu
|
||||||
|
@ -75,6 +75,7 @@ class KlippyWebsocket(threading.Thread):
|
|||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.closing = True
|
self.closing = True
|
||||||
|
self.ws.close()
|
||||||
|
|
||||||
def is_connected(self):
|
def is_connected(self):
|
||||||
return self.connected
|
return self.connected
|
||||||
|
@ -88,7 +88,7 @@ class KlipperScreenConfig:
|
|||||||
printer[8:]: {
|
printer[8:]: {
|
||||||
"moonraker_host": self.config.get(printer, "moonraker_host", fallback="127.0.0.1"),
|
"moonraker_host": self.config.get(printer, "moonraker_host", fallback="127.0.0.1"),
|
||||||
"moonraker_port": self.config.get(printer, "moonraker_port", fallback="7125"),
|
"moonraker_port": self.config.get(printer, "moonraker_port", fallback="7125"),
|
||||||
"moonraker_api_key": self.config.get(printer, "moonraker_api_key", fallback="")
|
"moonraker_api_key": self.config.get(printer, "moonraker_api_key", fallback=False)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if len(printers) <= 0:
|
if len(printers) <= 0:
|
||||||
@ -138,6 +138,7 @@ class KlipperScreenConfig:
|
|||||||
return ["\n".join(user_def), None if saved_def == None else "\n".join(saved_def)]
|
return ["\n".join(user_def), None if saved_def == None else "\n".join(saved_def)]
|
||||||
|
|
||||||
def get_config_file_location(self, file):
|
def get_config_file_location(self, file):
|
||||||
|
logging.info("Passed config file: %s" % file)
|
||||||
if not path.exists(file):
|
if not path.exists(file):
|
||||||
file = "%s/%s" % (os.getcwd(), self.configfile_name)
|
file = "%s/%s" % (os.getcwd(), self.configfile_name)
|
||||||
if not path.exists(file):
|
if not path.exists(file):
|
||||||
@ -219,16 +220,17 @@ class KlipperScreenConfig:
|
|||||||
save_config.add_section(opt['section'])
|
save_config.add_section(opt['section'])
|
||||||
save_config.set(opt['section'], name, str(curval))
|
save_config.set(opt['section'], name, str(curval))
|
||||||
|
|
||||||
if "displayed_macros" in self.config.sections():
|
macro_sections = [i for i in self.config.sections() if i.startswith("displayed_macros")]
|
||||||
for item in self.config.options('displayed_macros'):
|
for macro_sec in macro_sections:
|
||||||
value = self.config['displayed_macros'].getboolean(item, fallback=True)
|
for item in self.config.options(macro_sec):
|
||||||
|
value = self.config[macro_sec].getboolean(item, fallback=True)
|
||||||
if value == False or (self.defined_config != None and
|
if value == False or (self.defined_config != None and
|
||||||
"displayed_macros" in self.defined_config.sections() and
|
macro_sec in self.defined_config.sections() and
|
||||||
self.defined_config['displayed_macros'].getboolean(item, fallback=True) == False and
|
self.defined_config[macro_sec].getboolean(item, fallback=True) == False and
|
||||||
self.defined_config['displayed_macros'].getboolean(item, fallback=True) != value):
|
self.defined_config[macro_sec].getboolean(item, fallback=True) != value):
|
||||||
if "displayed_macros" not in save_config.sections():
|
if macro_sec not in save_config.sections():
|
||||||
save_config.add_section("displayed_macros")
|
save_config.add_section(macro_sec)
|
||||||
save_config.set("displayed_macros", item, str(value))
|
save_config.set(macro_sec, item, str(value))
|
||||||
|
|
||||||
save_output = self._build_config_string(save_config).split("\n")
|
save_output = self._build_config_string(save_config).split("\n")
|
||||||
for i in range(len(save_output)):
|
for i in range(len(save_output)):
|
||||||
|
@ -14,11 +14,6 @@ from gi.repository import Gtk, Gdk, GLib
|
|||||||
RESCAN_INTERVAL = 4
|
RESCAN_INTERVAL = 4
|
||||||
|
|
||||||
class KlippyFiles(Thread):
|
class KlippyFiles(Thread):
|
||||||
callbacks = []
|
|
||||||
filelist = []
|
|
||||||
files = {}
|
|
||||||
metadata_timeout = {}
|
|
||||||
timeout = None
|
|
||||||
thumbnail_dir = "/tmp/.KS-thumbnails"
|
thumbnail_dir = "/tmp/.KS-thumbnails"
|
||||||
|
|
||||||
def __init__(self, screen, *args, **kwargs):
|
def __init__(self, screen, *args, **kwargs):
|
||||||
@ -26,6 +21,12 @@ class KlippyFiles(Thread):
|
|||||||
self.loop = None
|
self.loop = None
|
||||||
self._poll_task = None
|
self._poll_task = None
|
||||||
self._screen = screen
|
self._screen = screen
|
||||||
|
self.callbacks = []
|
||||||
|
self.files = {}
|
||||||
|
self.filelist = []
|
||||||
|
self.metadata_timeout = {}
|
||||||
|
|
||||||
|
logging.info("")
|
||||||
|
|
||||||
if not os.path.exists(self.thumbnail_dir):
|
if not os.path.exists(self.thumbnail_dir):
|
||||||
os.makedirs(self.thumbnail_dir)
|
os.makedirs(self.thumbnail_dir)
|
||||||
@ -43,9 +44,11 @@ class KlippyFiles(Thread):
|
|||||||
with suppress(asyncio.CancelledError):
|
with suppress(asyncio.CancelledError):
|
||||||
loop.run_until_complete(self._poll_task)
|
loop.run_until_complete(self._poll_task)
|
||||||
finally:
|
finally:
|
||||||
|
logging.info("Closing loop")
|
||||||
loop.close()
|
loop.close()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
logging.info("Trying to stop loop2")
|
||||||
self.loop.call_soon_threadsafe(self.loop.stop)
|
self.loop.call_soon_threadsafe(self.loop.stop)
|
||||||
|
|
||||||
async def _poll(self):
|
async def _poll(self):
|
||||||
@ -117,10 +120,6 @@ class KlippyFiles(Thread):
|
|||||||
if callback in self.callbacks:
|
if callback in self.callbacks:
|
||||||
self.callbacks.pop(self.callbacks.index(callback))
|
self.callbacks.pop(self.callbacks.index(callback))
|
||||||
|
|
||||||
def add_timeout(self):
|
|
||||||
if self.timeout == None:
|
|
||||||
self.timeout = GLib.timeout_add(4000, self.ret_files)
|
|
||||||
|
|
||||||
def file_exists(self, filename):
|
def file_exists(self, filename):
|
||||||
return True if filename in self.filelist else False
|
return True if filename in self.filelist else False
|
||||||
|
|
||||||
@ -141,18 +140,13 @@ class KlippyFiles(Thread):
|
|||||||
return False
|
return False
|
||||||
return "thumbnails" in self.files[filename] and len(self.files[filename]) > 0
|
return "thumbnails" in self.files[filename] and len(self.files[filename]) > 0
|
||||||
|
|
||||||
def remove_timeout(self):
|
|
||||||
if self.timeout != None:
|
|
||||||
self.timeout = None
|
|
||||||
|
|
||||||
def request_metadata(self, filename):
|
def request_metadata(self, filename):
|
||||||
if filename not in self.filelist:
|
if filename not in self.filelist:
|
||||||
return False
|
return False
|
||||||
self._screen._ws.klippy.get_file_metadata(filename, self._callback)
|
self._screen._ws.klippy.get_file_metadata(filename, self._callback)
|
||||||
|
|
||||||
async def ret_files(self, retval=True):
|
async def ret_files(self, retval=True):
|
||||||
if not self._screen._ws.klippy.get_file_list(self._callback):
|
self._screen._ws.klippy.get_file_list(self._callback)
|
||||||
self.timeout = None
|
|
||||||
|
|
||||||
def ret_file_data (self, filename):
|
def ret_file_data (self, filename):
|
||||||
print("Getting file info for %s" % (filename))
|
print("Getting file info for %s" % (filename))
|
||||||
|
@ -7,6 +7,9 @@ from ks_includes.KlippyGcodes import KlippyGcodes
|
|||||||
|
|
||||||
|
|
||||||
class Printer:
|
class Printer:
|
||||||
|
data = {}
|
||||||
|
devices = {}
|
||||||
|
power_devices = {}
|
||||||
state_callbacks = {
|
state_callbacks = {
|
||||||
"disconnected": None,
|
"disconnected": None,
|
||||||
"error": None,
|
"error": None,
|
||||||
@ -16,6 +19,7 @@ class Printer:
|
|||||||
"startup": None,
|
"startup": None,
|
||||||
"shutdown": None
|
"shutdown": None
|
||||||
}
|
}
|
||||||
|
tools = []
|
||||||
|
|
||||||
def __init__(self, printer_info, data):
|
def __init__(self, printer_info, data):
|
||||||
self.state = "disconnected"
|
self.state = "disconnected"
|
||||||
@ -148,6 +152,8 @@ class Printer:
|
|||||||
return section in list(self.config)
|
return section in list(self.config)
|
||||||
|
|
||||||
def get_config_section_list(self, search=""):
|
def get_config_section_list(self, search=""):
|
||||||
|
if not hasattr(self, "config"):
|
||||||
|
return []
|
||||||
return [i for i in list(self.config) if i.startswith(search)]
|
return [i for i in list(self.config) if i.startswith(search)]
|
||||||
|
|
||||||
def get_config_section(self, section):
|
def get_config_section(self, section):
|
||||||
|
@ -12,7 +12,7 @@ class ScreenPanel:
|
|||||||
title_spacing = 50
|
title_spacing = 50
|
||||||
control = {}
|
control = {}
|
||||||
|
|
||||||
def __init__(self, screen, title, back=True):
|
def __init__(self, screen, title, back=True, action_bar=True, printer_name=True):
|
||||||
self._screen = screen
|
self._screen = screen
|
||||||
self._config = screen._config
|
self._config = screen._config
|
||||||
self._files = screen.files
|
self._files = screen.files
|
||||||
@ -24,34 +24,41 @@ class ScreenPanel:
|
|||||||
self.layout = Gtk.Layout()
|
self.layout = Gtk.Layout()
|
||||||
self.layout.set_size(self._screen.width, self._screen.height)
|
self.layout.set_size(self._screen.width, self._screen.height)
|
||||||
|
|
||||||
action_bar_width = self._gtk.get_action_bar_width()
|
action_bar_width = self._gtk.get_action_bar_width() if action_bar == True else 0
|
||||||
|
|
||||||
self.control_grid = self._gtk.HomogeneousGrid()
|
if action_bar == True:
|
||||||
self.control_grid.set_size_request(action_bar_width - 2, self._screen.height)
|
self.control_grid = self._gtk.HomogeneousGrid()
|
||||||
self.control_grid.get_style_context().add_class('action_bar')
|
self.control_grid.set_size_request(action_bar_width - 2, self._screen.height)
|
||||||
|
self.control_grid.get_style_context().add_class('action_bar')
|
||||||
|
|
||||||
button_scale = self._gtk.get_header_image_scale()
|
button_scale = self._gtk.get_header_image_scale()
|
||||||
logging.debug("Button scale: %s" % button_scale)
|
logging.debug("Button scale: %s" % button_scale)
|
||||||
if back == True:
|
|
||||||
self.control['back'] = self._gtk.ButtonImage('back', None, None, button_scale[0], button_scale[1])
|
|
||||||
self.control['back'].connect("clicked", self._screen._menu_go_back)
|
|
||||||
self.control_grid.attach(self.control['back'], 0, 0, 1, 1)
|
|
||||||
|
|
||||||
self.control['home'] = self._gtk.ButtonImage('home', None, None, button_scale[0], button_scale[1])
|
if back == True:
|
||||||
self.control['home'].connect("clicked", self.menu_return, True)
|
self.control['back'] = self._gtk.ButtonImage('back', None, None, button_scale[0], button_scale[1])
|
||||||
self.control_grid.attach(self.control['home'], 0, 1, 1, 1)
|
self.control['back'].connect("clicked", self._screen._menu_go_back)
|
||||||
|
self.control_grid.attach(self.control['back'], 0, 0, 1, 1)
|
||||||
|
|
||||||
self.control['printer_select'] = Gtk.Label("")
|
self.control['home'] = self._gtk.ButtonImage('home', None, None, button_scale[0], button_scale[1])
|
||||||
|
self.control['home'].connect("clicked", self.menu_return, True)
|
||||||
|
self.control_grid.attach(self.control['home'], 0, 1, 1, 1)
|
||||||
|
else:
|
||||||
|
for i in range(2):
|
||||||
|
self.control['space%s' % i] = Gtk.Label("")
|
||||||
|
self.control_grid.attach(self.control['space%s' % i], 0, i, 1, 1)
|
||||||
|
|
||||||
|
if len(self._config.get_printers()) > 1:
|
||||||
|
self.control['printer_select'] = self._gtk.ButtonImage(
|
||||||
|
'shuffle', None, None, button_scale[0], button_scale[1])
|
||||||
|
self.control['printer_select'].connect("clicked", self._screen.show_printer_select)
|
||||||
|
else:
|
||||||
|
self.control['printer_select'] = Gtk.Label("")
|
||||||
self.control_grid.attach(self.control['printer_select'], 0, 2, 1, 1)
|
self.control_grid.attach(self.control['printer_select'], 0, 2, 1, 1)
|
||||||
else:
|
|
||||||
for i in range(3):
|
|
||||||
self.control['space%s' % i] = Gtk.Label("")
|
|
||||||
self.control_grid.attach(self.control['space%s' % i], 0, i, 1, 1)
|
|
||||||
|
|
||||||
self.control['estop'] = self._gtk.ButtonImage('emergency', None, None, button_scale[0], button_scale[1])
|
self.control['estop'] = self._gtk.ButtonImage('emergency', None, None, button_scale[0], button_scale[1])
|
||||||
self.control['estop'].connect("clicked", self.emergency_stop)
|
self.control['estop'].connect("clicked", self.emergency_stop)
|
||||||
self.control_grid.attach(self.control['estop'], 0, 3, 1, 1)
|
self.control_grid.attach(self.control['estop'], 0, 3, 1, 1)
|
||||||
#self.layout.put(self.control['estop'], int(self._screen.width/4*3 - button_scale[0]/2), 0)
|
#self.layout.put(self.control['estop'], int(self._screen.width/4*3 - button_scale[0]/2), 0)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
env = Environment(extensions=["jinja2.ext.i18n"])
|
env = Environment(extensions=["jinja2.ext.i18n"])
|
||||||
@ -66,13 +73,16 @@ class ScreenPanel:
|
|||||||
self.title.set_hexpand(True)
|
self.title.set_hexpand(True)
|
||||||
self.title.set_halign(Gtk.Align.CENTER)
|
self.title.set_halign(Gtk.Align.CENTER)
|
||||||
self.title.set_valign(Gtk.Align.CENTER)
|
self.title.set_valign(Gtk.Align.CENTER)
|
||||||
self.set_title(title)
|
if printer_name == True:
|
||||||
|
self.set_title("%s | %s" % (self._screen.connected_printer, title))
|
||||||
|
else:
|
||||||
|
self.set_title(title)
|
||||||
|
|
||||||
self.content = Gtk.Box(spacing=0)
|
self.content = Gtk.Box(spacing=0)
|
||||||
self.content.set_size_request(self._screen.width - action_bar_width, self._screen.height - self.title_spacing)
|
self.content.set_size_request(self._screen.width - action_bar_width, self._screen.height - self.title_spacing)
|
||||||
|
|
||||||
self.layout.put(self.control_grid, 0, 0)
|
if action_bar == True:
|
||||||
|
self.layout.put(self.control_grid, 0, 0)
|
||||||
self.layout.put(self.title, action_bar_width, 0)
|
self.layout.put(self.title, action_bar_width, 0)
|
||||||
self.layout.put(self.content, action_bar_width, self.title_spacing)
|
self.layout.put(self.content, action_bar_width, self.title_spacing)
|
||||||
|
|
||||||
|
@ -81,28 +81,27 @@ class MacroPanel(ScreenPanel):
|
|||||||
|
|
||||||
def load_gcode_macros(self):
|
def load_gcode_macros(self):
|
||||||
macros = self._screen.printer.get_gcode_macros()
|
macros = self._screen.printer.get_gcode_macros()
|
||||||
|
section_name = "displayed_macros %s" % self._screen.connected_printer
|
||||||
|
logging.info("Macro section name [%s]" % section_name)
|
||||||
|
|
||||||
for x in macros:
|
for x in macros:
|
||||||
macro = x[12:].strip()
|
macro = x[12:].strip()
|
||||||
|
|
||||||
if macro in self.loaded_macros:
|
if macro in self.loaded_macros:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logging.debug("Evaluating '%s' value '%s'" % (macro.strip().lower(),
|
if (section_name not in self._config.get_config().sections() or
|
||||||
self._config.get_config().getboolean("displayed_macros", macro.lower(), fallback=True)))
|
self._config.get_config().getboolean(section_name, macro.lower(), fallback=True)):
|
||||||
|
|
||||||
if ("displayed_macros" not in self._config.get_config().sections() or
|
|
||||||
self._config.get_config().getboolean("displayed_macros", macro.lower(), fallback=True)):
|
|
||||||
self.add_gcode_macro(macro)
|
self.add_gcode_macro(macro)
|
||||||
|
|
||||||
def run_gcode_macro(self, widget, macro):
|
def run_gcode_macro(self, widget, macro):
|
||||||
self._screen._ws.klippy.gcode_script(macro)
|
self._screen._ws.klippy.gcode_script(macro)
|
||||||
|
|
||||||
def unload_gcode_macros(self):
|
def unload_gcode_macros(self):
|
||||||
|
section_name = "displayed_macros %s" % self._screen.connected_printer
|
||||||
for macro in self.loaded_macros:
|
for macro in self.loaded_macros:
|
||||||
logging.debug("Evaluating '%s' value '%s'" % (macro.strip().lower(),
|
if (section_name in self._config.get_config().sections() and
|
||||||
self._config.get_config().getboolean("displayed_macros", macro.lower(), fallback=True)))
|
not self._config.get_config().getboolean(section_name, macro.lower(), fallback=True)):
|
||||||
if ("displayed_macros" in self._config.get_config().sections() and
|
|
||||||
not self._config.get_config().getboolean("displayed_macros", macro.lower(), fallback=True)):
|
|
||||||
macros = sorted(self.macros)
|
macros = sorted(self.macros)
|
||||||
pos = macros.index(macro)
|
pos = macros.index(macro)
|
||||||
self.labels['macros'].remove_row(pos)
|
self.labels['macros'].remove_row(pos)
|
||||||
|
@ -18,16 +18,16 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
progress = 0
|
progress = 0
|
||||||
state = "printing"
|
state = "printing"
|
||||||
|
|
||||||
|
def __init__(self, screen, title, back=False):
|
||||||
|
super().__init__(screen, title, False)
|
||||||
|
|
||||||
def initialize(self, panel_name):
|
def initialize(self, panel_name):
|
||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
self.layout = Gtk.Layout()
|
|
||||||
self.layout.set_size(self._screen.width, self._screen.height)
|
|
||||||
self.timeleft_type = "file"
|
self.timeleft_type = "file"
|
||||||
|
|
||||||
self.create_buttons()
|
self.create_buttons()
|
||||||
|
|
||||||
grid = self._gtk.HomogeneousGrid()
|
grid = self._gtk.HomogeneousGrid()
|
||||||
grid.set_size_request(self._screen.width, self._screen.height)
|
|
||||||
grid.set_row_homogeneous(False)
|
grid.set_row_homogeneous(False)
|
||||||
|
|
||||||
self.labels['button_grid'] = self._gtk.HomogeneousGrid()
|
self.labels['button_grid'] = self._gtk.HomogeneousGrid()
|
||||||
@ -170,23 +170,27 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
sfe_grid.attach(fan_box, 2, 0, 1, 1)
|
sfe_grid.attach(fan_box, 2, 0, 1, 1)
|
||||||
self.labels['sfe_grid'] = sfe_grid
|
self.labels['sfe_grid'] = sfe_grid
|
||||||
|
|
||||||
self.labels['i1_box'] = Gtk.VBox(spacing=0)
|
self.labels['i1_box'] = Gtk.HBox(spacing=0)
|
||||||
|
self.labels['i1_box'].set_vexpand(True)
|
||||||
self.labels['i1_box'].get_style_context().add_class("printing-info-box")
|
self.labels['i1_box'].get_style_context().add_class("printing-info-box")
|
||||||
self.labels['i1_box'].set_valign(Gtk.Align.CENTER)
|
self.labels['i1_box'].set_valign(Gtk.Align.CENTER)
|
||||||
self.labels['i2_box'] = Gtk.VBox(spacing=0)
|
self.labels['i2_box'] = Gtk.VBox(spacing=0)
|
||||||
self.labels['i2_box'].set_vexpand(True)
|
self.labels['i2_box'].set_vexpand(True)
|
||||||
self.labels['i2_box'].get_style_context().add_class("printing-info-box")
|
self.labels['i2_box'].get_style_context().add_class("printing-info-box")
|
||||||
|
self.labels['i2_box'].set_valign(Gtk.Align.CENTER)
|
||||||
|
self.labels['info_grid'] = self._gtk.HomogeneousGrid()
|
||||||
|
self.labels['info_grid'].attach(self.labels['i1_box'], 0, 0, 1, 1)
|
||||||
|
self.labels['info_grid'].attach(self.labels['i2_box'], 1, 0, 1, 1)
|
||||||
|
|
||||||
grid.attach(overlay, 0, 0, 1, 1)
|
grid.attach(overlay, 0, 0, 1, 1)
|
||||||
grid.attach(fi_box, 1, 0, 3, 1)
|
grid.attach(fi_box, 1, 0, 3, 1)
|
||||||
grid.attach(self.labels['i1_box'], 0, 1, 2, 2)
|
grid.attach(self.labels['info_grid'], 0, 1, 4, 2)
|
||||||
grid.attach(self.labels['i2_box'], 2, 1, 2, 2)
|
|
||||||
grid.attach(self.labels['button_grid'], 0, 3, 4, 1)
|
grid.attach(self.labels['button_grid'], 0, 3, 4, 1)
|
||||||
|
|
||||||
self.add_labels()
|
self.add_labels()
|
||||||
|
|
||||||
self.grid = grid
|
self.grid = grid
|
||||||
self.layout.put(grid, 0, 0)
|
self.content.add(grid)
|
||||||
|
|
||||||
self._screen.add_subscription(panel_name)
|
self._screen.add_subscription(panel_name)
|
||||||
|
|
||||||
@ -250,8 +254,6 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
self.labels['cancel'].connect("clicked", self.cancel)
|
self.labels['cancel'].connect("clicked", self.cancel)
|
||||||
self.labels['control'] = self._gtk.ButtonImage("control",_("Control"),"color3")
|
self.labels['control'] = self._gtk.ButtonImage("control",_("Control"),"color3")
|
||||||
self.labels['control'].connect("clicked", self._screen._go_to_submenu, "")
|
self.labels['control'].connect("clicked", self._screen._go_to_submenu, "")
|
||||||
self.labels['estop'] = self._gtk.ButtonImage("emergency",_("Emergency Stop"),"color4")
|
|
||||||
self.labels['estop'].connect("clicked", self.emergency_stop)
|
|
||||||
self.labels['menu'] = self._gtk.ButtonImage("complete",_("Main Menu"),"color4")
|
self.labels['menu'] = self._gtk.ButtonImage("complete",_("Main Menu"),"color4")
|
||||||
self.labels['menu'].connect("clicked", self.close_panel)
|
self.labels['menu'].connect("clicked", self.close_panel)
|
||||||
self.labels['pause'] = self._gtk.ButtonImage("pause",_("Pause"),"color1" )
|
self.labels['pause'] = self._gtk.ButtonImage("pause",_("Pause"),"color1" )
|
||||||
@ -484,12 +486,12 @@ class JobStatusPanel(ScreenPanel):
|
|||||||
if self.state == "printing":
|
if self.state == "printing":
|
||||||
self.labels['button_grid'].attach(self.labels['pause'], 0, 0, 1, 1)
|
self.labels['button_grid'].attach(self.labels['pause'], 0, 0, 1, 1)
|
||||||
self.labels['button_grid'].attach(self.labels['cancel'], 1, 0, 1, 1)
|
self.labels['button_grid'].attach(self.labels['cancel'], 1, 0, 1, 1)
|
||||||
self.labels['button_grid'].attach(self.labels['estop'], 2, 0, 1, 1)
|
self.labels['button_grid'].attach(Gtk.Label(""), 2, 0, 1, 1)
|
||||||
self.labels['button_grid'].attach(self.labels['control'], 3, 0, 1, 1)
|
self.labels['button_grid'].attach(self.labels['control'], 3, 0, 1, 1)
|
||||||
elif self.state == "paused":
|
elif self.state == "paused":
|
||||||
self.labels['button_grid'].attach(self.labels['resume'], 0, 0, 1, 1)
|
self.labels['button_grid'].attach(self.labels['resume'], 0, 0, 1, 1)
|
||||||
self.labels['button_grid'].attach(self.labels['cancel'], 1, 0, 1, 1)
|
self.labels['button_grid'].attach(self.labels['cancel'], 1, 0, 1, 1)
|
||||||
self.labels['button_grid'].attach(self.labels['estop'], 2, 0, 1, 1)
|
self.labels['button_grid'].attach(Gtk.Label(""), 2, 0, 1, 1)
|
||||||
self.labels['button_grid'].attach(self.labels['control'], 3, 0, 1, 1)
|
self.labels['button_grid'].attach(self.labels['control'], 3, 0, 1, 1)
|
||||||
elif self.state == "error" or self.state == "complete" or self.state == "cancelled":
|
elif self.state == "error" or self.state == "complete" or self.state == "cancelled":
|
||||||
self.labels['button_grid'].attach(Gtk.Label(""), 0, 0, 1, 1)
|
self.labels['button_grid'].attach(Gtk.Label(""), 0, 0, 1, 1)
|
||||||
|
33
panels/printer_select.py
Normal file
33
panels/printer_select.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import gi
|
||||||
|
import logging
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
from gi.repository import Gtk, Gdk, GLib
|
||||||
|
|
||||||
|
from ks_includes.KlippyGcodes import KlippyGcodes
|
||||||
|
from ks_includes.screen_panel import ScreenPanel
|
||||||
|
|
||||||
|
logger = logging.getLogger("KlipperScreen.PrinterSelect")
|
||||||
|
|
||||||
|
def create_panel(*args):
|
||||||
|
return PrinterSelect(*args)
|
||||||
|
|
||||||
|
class PrinterSelect(ScreenPanel):
|
||||||
|
def __init__(self, screen, title, back=True, action_bar=True, printer_name=True):
|
||||||
|
super().__init__(screen, title, False, False, False)
|
||||||
|
|
||||||
|
def initialize(self, panel_name):
|
||||||
|
_ = self.lang.gettext
|
||||||
|
|
||||||
|
printers = self._config.get_printers()
|
||||||
|
|
||||||
|
box = Gtk.Box()
|
||||||
|
self.content.add(box)
|
||||||
|
|
||||||
|
i = 1
|
||||||
|
for printer in printers:
|
||||||
|
name = list(printer)[0]
|
||||||
|
self.labels[name] = self._gtk.ButtonImage("extruder",name,"color%s" % (i%4))
|
||||||
|
self.labels[name].connect("clicked", self._screen.connect_printer_widget, name)
|
||||||
|
box.add(self.labels[name])
|
||||||
|
i += 1
|
@ -21,12 +21,23 @@ class SettingsPanel(ScreenPanel):
|
|||||||
self.labels['main_box'] = self.create_box('main')
|
self.labels['main_box'] = self.create_box('main')
|
||||||
self.labels['macros_box'] = self.create_box('macros')
|
self.labels['macros_box'] = self.create_box('macros')
|
||||||
|
|
||||||
|
printbox = Gtk.Box(spacing=0)
|
||||||
|
printbox.set_vexpand(False)
|
||||||
|
self.labels['add_printer_button'] = self._gtk.Button(_("Add Printer"), "color1")
|
||||||
|
#printbox.add(self.labels['add_printer_button'])
|
||||||
|
self.labels['printers_box'] = self.create_box('printers', printbox)
|
||||||
|
|
||||||
options = self._config.get_configurable_options().copy()
|
options = self._config.get_configurable_options().copy()
|
||||||
options.append({"macros": {
|
options.append({"macros": {
|
||||||
"name": _("Displayed Macros"),
|
"name": _("Displayed Macros"),
|
||||||
"type": "menu",
|
"type": "menu",
|
||||||
"menu": "macros"}
|
"menu": "macros"}
|
||||||
})
|
})
|
||||||
|
options.append({"printers": {
|
||||||
|
"name": _("Printer Connections"),
|
||||||
|
"type": "menu",
|
||||||
|
"menu": "printers"
|
||||||
|
}})
|
||||||
|
|
||||||
for option in options:
|
for option in options:
|
||||||
name = list(option)[0]
|
name = list(option)[0]
|
||||||
@ -36,14 +47,25 @@ class SettingsPanel(ScreenPanel):
|
|||||||
macro = macro[12:]
|
macro = macro[12:]
|
||||||
self.macros[macro] = {
|
self.macros[macro] = {
|
||||||
"name": macro,
|
"name": macro,
|
||||||
"section": "displayed_macros",
|
"section": "displayed_macros %s" % self._screen.connected_printer,
|
||||||
"type": "macro"
|
"type": "macro"
|
||||||
}
|
}
|
||||||
|
|
||||||
for macro in list(self.macros):
|
for macro in list(self.macros):
|
||||||
self.add_option('macros', self.macros, macro, self.macros[macro])
|
self.add_option('macros', self.macros, macro, self.macros[macro])
|
||||||
|
|
||||||
logging.debug("Macros: %s" % self.macros)
|
self.printers = {}
|
||||||
|
for printer in self._config.get_printers():
|
||||||
|
logging.debug("Printer: %s" % printer)
|
||||||
|
pname = list(printer)[0]
|
||||||
|
self.printers[pname] = {
|
||||||
|
"name": pname,
|
||||||
|
"section": "printer %s" % pname,
|
||||||
|
"type": "printer",
|
||||||
|
"moonraker_host": printer[pname]['moonraker_host'],
|
||||||
|
"moonraker_port": printer[pname]['moonraker_port'],
|
||||||
|
}
|
||||||
|
self.add_option("printers", self.printers, pname, self.printers[pname])
|
||||||
|
|
||||||
self.control['back'].disconnect_by_func(self._screen._menu_go_back)
|
self.control['back'].disconnect_by_func(self._screen._menu_go_back)
|
||||||
self.control['back'].connect("clicked", self.back)
|
self.control['back'].connect("clicked", self.back)
|
||||||
@ -59,7 +81,7 @@ class SettingsPanel(ScreenPanel):
|
|||||||
else:
|
else:
|
||||||
self._screen._menu_go_back()
|
self._screen._menu_go_back()
|
||||||
|
|
||||||
def create_box(self, name):
|
def create_box(self, name, insert=None):
|
||||||
# Create a scroll window for the macros
|
# Create a scroll window for the macros
|
||||||
scroll = Gtk.ScrolledWindow()
|
scroll = Gtk.ScrolledWindow()
|
||||||
scroll.set_property("overlay-scrolling", False)
|
scroll.set_property("overlay-scrolling", False)
|
||||||
@ -72,6 +94,8 @@ class SettingsPanel(ScreenPanel):
|
|||||||
# Create a box to contain all of the above
|
# Create a box to contain all of the above
|
||||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
|
||||||
box.set_vexpand(True)
|
box.set_vexpand(True)
|
||||||
|
if insert is not None:
|
||||||
|
box.pack_start(insert, False, False, 0)
|
||||||
box.pack_start(scroll, True, True, 0)
|
box.pack_start(scroll, True, True, 0)
|
||||||
return box
|
return box
|
||||||
|
|
||||||
@ -135,6 +159,15 @@ class SettingsPanel(ScreenPanel):
|
|||||||
dropdown.set_entry_text_column(0)
|
dropdown.set_entry_text_column(0)
|
||||||
dev.add(dropdown)
|
dev.add(dropdown)
|
||||||
logging.debug("Children: %s" % dropdown.get_children())
|
logging.debug("Children: %s" % dropdown.get_children())
|
||||||
|
elif option['type'] == "printer":
|
||||||
|
logging.debug("Option: %s" % option)
|
||||||
|
box = Gtk.Box()
|
||||||
|
box.set_vexpand(False)
|
||||||
|
label = Gtk.Label()
|
||||||
|
url = "%s:%s" % (option['moonraker_host'], option['moonraker_port'])
|
||||||
|
label.set_markup("<big>%s</big>\n%s" % (option['name'], url))
|
||||||
|
box.add(label)
|
||||||
|
dev.add(box)
|
||||||
elif option['type'] == "menu":
|
elif option['type'] == "menu":
|
||||||
open = self._gtk.ButtonImage("open",None,"color3")
|
open = self._gtk.ButtonImage("open",None,"color3")
|
||||||
open.connect("clicked", self.load_menu, option['menu'])
|
open.connect("clicked", self.load_menu, option['menu'])
|
||||||
|
@ -61,9 +61,11 @@ class SplashScreenPanel(ScreenPanel):
|
|||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
|
|
||||||
if "firmware_restart" not in self.labels:
|
if "firmware_restart" not in self.labels:
|
||||||
|
self.labels['printer_select'] = self._gtk.ButtonImage("shuffle",_("Change Printer"))
|
||||||
|
self.labels['printer_select'].connect("clicked", self._screen.show_printer_select)
|
||||||
self.labels['menu'] = self._gtk.ButtonImage("control",_("Menu"),"color4")
|
self.labels['menu'] = self._gtk.ButtonImage("control",_("Menu"),"color4")
|
||||||
self.labels['menu'].connect("clicked", self._screen._go_to_submenu, "")
|
self.labels['menu'].connect("clicked", self._screen._go_to_submenu, "")
|
||||||
self.labels['power'] = self._gtk.ButtonImage("reboot",_("Power On Printer"),"color3")
|
self.labels['power'] = self._gtk.ButtonImage("shutdown",_("Power On Printer"),"color3")
|
||||||
self.labels['restart'] = self._gtk.ButtonImage("reboot",_("Restart"),"color1")
|
self.labels['restart'] = self._gtk.ButtonImage("reboot",_("Restart"),"color1")
|
||||||
self.labels['restart'].connect("clicked", self.restart)
|
self.labels['restart'].connect("clicked", self.restart)
|
||||||
self.labels['firmware_restart'] = self._gtk.ButtonImage("restart",_("Firmware Restart"),"color2")
|
self.labels['firmware_restart'] = self._gtk.ButtonImage("restart",_("Firmware Restart"),"color2")
|
||||||
@ -82,7 +84,8 @@ class SplashScreenPanel(ScreenPanel):
|
|||||||
self.labels['actions'].add(self.labels['restart'])
|
self.labels['actions'].add(self.labels['restart'])
|
||||||
self.labels['actions'].add(self.labels['firmware_restart'])
|
self.labels['actions'].add(self.labels['firmware_restart'])
|
||||||
self.labels['actions'].add(self.labels['menu'])
|
self.labels['actions'].add(self.labels['menu'])
|
||||||
self.labels['actions'].show()
|
self.labels['actions'].add(self.labels['printer_select'])
|
||||||
|
self.labels['actions'].show_all()
|
||||||
|
|
||||||
def firmware_restart(self, widget):
|
def firmware_restart(self, widget):
|
||||||
self._screen._ws.klippy.restart_firmware()
|
self._screen._ws.klippy.restart_firmware()
|
||||||
|
89
screen.py
89
screen.py
@ -54,6 +54,7 @@ class KlipperScreen(Gtk.Window):
|
|||||||
""" Class for creating a screen for Klipper via HDMI """
|
""" Class for creating a screen for Klipper via HDMI """
|
||||||
_cur_panels = []
|
_cur_panels = []
|
||||||
bed_temp_label = None
|
bed_temp_label = None
|
||||||
|
connecting = False
|
||||||
connected_printer = None
|
connected_printer = None
|
||||||
currentPanel = None
|
currentPanel = None
|
||||||
files = None
|
files = None
|
||||||
@ -66,6 +67,8 @@ class KlipperScreen(Gtk.Window):
|
|||||||
panels = {}
|
panels = {}
|
||||||
popup_message = None
|
popup_message = None
|
||||||
printer = None
|
printer = None
|
||||||
|
printer_select_callbacks = []
|
||||||
|
printer_select_prepanel = None
|
||||||
rtl_languages = ['he_il']
|
rtl_languages = ['he_il']
|
||||||
subscriptions = []
|
subscriptions = []
|
||||||
shutdown = True
|
shutdown = True
|
||||||
@ -116,22 +119,51 @@ class KlipperScreen(Gtk.Window):
|
|||||||
self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.ARROW))
|
self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.ARROW))
|
||||||
else:
|
else:
|
||||||
self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.BLANK_CURSOR))
|
self.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.BLANK_CURSOR))
|
||||||
pname = list(self._config.get_printers()[0])[0]
|
|
||||||
self.connect_printer(pname, self._config.get_printers()[0][pname])
|
|
||||||
|
|
||||||
def connect_printer(self, name, data):
|
printers = self._config.get_printers()
|
||||||
|
logging.debug("Printers: %s" % printers)
|
||||||
|
if len(printers) == 1:
|
||||||
|
pname = list(self._config.get_printers()[0])[0]
|
||||||
|
self.connect_printer(pname)
|
||||||
|
else:
|
||||||
|
self.show_panel("printer_select","printer_select","Printer Select", 2)
|
||||||
|
|
||||||
|
def connect_printer_widget(self, widget, name):
|
||||||
|
self.connect_printer(name)
|
||||||
|
|
||||||
|
def connect_printer(self, name):
|
||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
|
|
||||||
if self.connected_printer == name:
|
if self.connected_printer == name:
|
||||||
|
if self.printer_select_prepanel != None:
|
||||||
|
self.show_panel(self.printer_select_prepanel, "","", 2)
|
||||||
|
self.printer_select_prepanel = None
|
||||||
|
while len(self.printer_select_callbacks) > 0:
|
||||||
|
i = self.printer_select_callbacks.pop(0)
|
||||||
|
i()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
self.printer_select_callbacks = []
|
||||||
|
self.printer_select_prepanel = None
|
||||||
|
|
||||||
if self.files is not None:
|
if self.files is not None:
|
||||||
self.files.stop()
|
self.files.stop()
|
||||||
|
self.files = None
|
||||||
|
|
||||||
|
for printer in self._config.get_printers():
|
||||||
|
pname = list(printer)[0]
|
||||||
|
|
||||||
|
if pname != name:
|
||||||
|
continue
|
||||||
|
data = printer[pname]
|
||||||
|
break
|
||||||
|
|
||||||
|
if self._ws is not None:
|
||||||
|
self._ws.close()
|
||||||
|
self.connecting = True
|
||||||
|
|
||||||
logging.info("Connecting to printer: %s" % name)
|
logging.info("Connecting to printer: %s" % name)
|
||||||
self.apiclient = KlippyRest(self._config.get_main_config_option("moonraker_host"),
|
self.apiclient = KlippyRest(data["moonraker_host"], data["moonraker_port"], data["moonraker_api_key"])
|
||||||
self._config.get_main_config_option("moonraker_port"),
|
|
||||||
self._config.get_main_config_option("moonraker_api_key", False))
|
|
||||||
|
|
||||||
self.printer = Printer({
|
self.printer = Printer({
|
||||||
"software_version": "Unknown"
|
"software_version": "Unknown"
|
||||||
@ -149,6 +181,8 @@ class KlipperScreen(Gtk.Window):
|
|||||||
|
|
||||||
self._remove_all_panels()
|
self._remove_all_panels()
|
||||||
panels = list(self.panels)
|
panels = list(self.panels)
|
||||||
|
if len(self.subscriptions) > 0:
|
||||||
|
self.subscriptions = []
|
||||||
for panel in panels:
|
for panel in panels:
|
||||||
del self.panels[panel]
|
del self.panels[panel]
|
||||||
self.printer_initializing(_("Connecting to %s") % name)
|
self.printer_initializing(_("Connecting to %s") % name)
|
||||||
@ -169,19 +203,17 @@ class KlipperScreen(Gtk.Window):
|
|||||||
self.printer.configure_power_devices(powerdevs['result'])
|
self.printer.configure_power_devices(powerdevs['result'])
|
||||||
self.panels['splash_screen'].show_restart_buttons()
|
self.panels['splash_screen'].show_restart_buttons()
|
||||||
|
|
||||||
if self._ws is not None:
|
|
||||||
self._ws.close
|
|
||||||
|
|
||||||
self._ws = KlippyWebsocket(self,
|
self._ws = KlippyWebsocket(self,
|
||||||
{
|
{
|
||||||
"on_connect": self.init_printer,
|
"on_connect": self.init_printer,
|
||||||
"on_message": self._websocket_callback,
|
"on_message": self._websocket_callback,
|
||||||
"on_close": self.printer_initializing
|
"on_close": self.printer_initializing
|
||||||
},
|
},
|
||||||
self._config.get_main_config_option("moonraker_host"),
|
data["moonraker_host"],
|
||||||
self._config.get_main_config_option("moonraker_port")
|
data["moonraker_port"]
|
||||||
)
|
)
|
||||||
self._ws.initial_connect()
|
self._ws.initial_connect()
|
||||||
|
self.connecting = False
|
||||||
|
|
||||||
self.files = KlippyFiles(self)
|
self.files = KlippyFiles(self)
|
||||||
self.files.start()
|
self.files.start()
|
||||||
@ -458,12 +490,25 @@ class KlipperScreen(Gtk.Window):
|
|||||||
if self.dpms_timeout == None and functions.dpms_loaded == True:
|
if self.dpms_timeout == None and functions.dpms_loaded == True:
|
||||||
self.dpms_timeout = GLib.timeout_add(1000, self.check_dpms_state)
|
self.dpms_timeout = GLib.timeout_add(1000, self.check_dpms_state)
|
||||||
|
|
||||||
|
def show_printer_select(self, widget=None):
|
||||||
|
logging.debug("Saving panel: %s" % self._cur_panels[0])
|
||||||
|
self.printer_select_prepanel = self._cur_panels[0]
|
||||||
|
self.show_panel("printer_select","printer_select","Printer Select", 2)
|
||||||
|
|
||||||
def state_disconnected(self):
|
def state_disconnected(self):
|
||||||
|
if "printer_select" in self._cur_panels:
|
||||||
|
self.printer_select_callbacks = [self.state_disconnected]
|
||||||
|
return
|
||||||
|
|
||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
logging.debug("### Going to disconnected")
|
logging.debug("### Going to disconnected")
|
||||||
self.printer_initializing(_("Klipper has disconnected"))
|
self.printer_initializing(_("Klipper has disconnected"))
|
||||||
|
|
||||||
def state_error(self):
|
def state_error(self):
|
||||||
|
if "printer_select" in self._cur_panels:
|
||||||
|
self.printer_select_callbacks = [self.state_error]
|
||||||
|
return
|
||||||
|
|
||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
msg = self.printer.get_stat("webhooks","state_message")
|
msg = self.printer.get_stat("webhooks","state_message")
|
||||||
if "FIRMWARE_RESTART" in msg:
|
if "FIRMWARE_RESTART" in msg:
|
||||||
@ -484,26 +529,45 @@ class KlipperScreen(Gtk.Window):
|
|||||||
self.printer_printing()
|
self.printer_printing()
|
||||||
|
|
||||||
def state_printing(self):
|
def state_printing(self):
|
||||||
|
if "printer_select" in self._cur_panels:
|
||||||
|
self.printer_select_callbacks = [self.state_printing]
|
||||||
|
return
|
||||||
|
|
||||||
if "job_status" not in self._cur_panels:
|
if "job_status" not in self._cur_panels:
|
||||||
self.printer_printing()
|
self.printer_printing()
|
||||||
|
|
||||||
def state_ready(self):
|
def state_ready(self):
|
||||||
|
if "printer_select" in self._cur_panels:
|
||||||
|
self.printer_select_callbacks = [self.state_ready]
|
||||||
|
return
|
||||||
|
|
||||||
# Do not return to main menu if completing a job, timeouts/user input will return
|
# Do not return to main menu if completing a job, timeouts/user input will return
|
||||||
if "job_status" in self._cur_panels or "main_menu" in self._cur_panels:
|
if "job_status" in self._cur_panels or "main_menu" in self._cur_panels:
|
||||||
return
|
return
|
||||||
self.printer_ready()
|
self.printer_ready()
|
||||||
|
|
||||||
def state_startup(self):
|
def state_startup(self):
|
||||||
|
if "printer_select" in self._cur_panels:
|
||||||
|
self.printer_select_callbacks = [self.state_startup]
|
||||||
|
return
|
||||||
|
|
||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
self.printer_initializing(_("Klipper is attempting to start"))
|
self.printer_initializing(_("Klipper is attempting to start"))
|
||||||
|
|
||||||
def state_shutdown(self):
|
def state_shutdown(self):
|
||||||
|
if "printer_select" in self._cur_panels:
|
||||||
|
self.printer_select_callbacks = [self.state_shutdown]
|
||||||
|
return
|
||||||
|
|
||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
self.printer_initializing(_("Klipper has shutdown"))
|
self.printer_initializing(_("Klipper has shutdown"))
|
||||||
|
|
||||||
def _websocket_callback(self, action, data):
|
def _websocket_callback(self, action, data):
|
||||||
_ = self.lang.gettext
|
_ = self.lang.gettext
|
||||||
|
|
||||||
|
if self.connecting == True:
|
||||||
|
return
|
||||||
|
|
||||||
if action == "notify_klippy_disconnected":
|
if action == "notify_klippy_disconnected":
|
||||||
logging.debug("Received notify_klippy_disconnected")
|
logging.debug("Received notify_klippy_disconnected")
|
||||||
self.printer.change_state("disconnected")
|
self.printer.change_state("disconnected")
|
||||||
@ -592,10 +656,11 @@ class KlipperScreen(Gtk.Window):
|
|||||||
self.printer.configure_power_devices(powerdevs['result'])
|
self.printer.configure_power_devices(powerdevs['result'])
|
||||||
|
|
||||||
def printer_ready(self):
|
def printer_ready(self):
|
||||||
|
_ = self.lang.gettext
|
||||||
self.close_popup_message()
|
self.close_popup_message()
|
||||||
# Force update to printer webhooks state in case the update is missed due to websocket subscribe not yet sent
|
# Force update to printer webhooks state in case the update is missed due to websocket subscribe not yet sent
|
||||||
self.printer.process_update({"webhooks":{"state":"ready","state_message": "Printer is ready"}})
|
self.printer.process_update({"webhooks":{"state":"ready","state_message": "Printer is ready"}})
|
||||||
self.show_panel('main_panel', "main_menu", self.connected_printer, 2,
|
self.show_panel('main_panel', "main_menu", _("Home"), 2,
|
||||||
items=self._config.get_menu_items("__main"), extrudercount=self.printer.get_extruder_count())
|
items=self._config.get_menu_items("__main"), extrudercount=self.printer.get_extruder_count())
|
||||||
self.ws_subscribe()
|
self.ws_subscribe()
|
||||||
if "job_status" in self.panels:
|
if "job_status" in self.panels:
|
||||||
|
5
styles/z-bolt/images/shuffle.svg
Normal file
5
styles/z-bolt/images/shuffle.svg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path style="fill: #fff;" d="M17,3L22.25,7.5L17,12L22.25,16.5L17,21V18H14.26L11.44,15.18L13.56,13.06L15.5,15H17V12L17,9H15.5L6.5,18H2V15H5.26L14.26,6H17V3M2,6H6.5L9.32,8.82L7.2,10.94L5.26,9H2V6Z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 489 B |
Loading…
x
Reference in New Issue
Block a user