diff --git a/ks_includes/widgets/keypad.py b/ks_includes/widgets/keypad.py index 179f5d3e..d601f493 100644 --- a/ks_includes/widgets/keypad.py +++ b/ks_includes/widgets/keypad.py @@ -5,11 +5,12 @@ from gi.repository import Gtk class Keypad(Gtk.Box): - def __init__(self, screen, change_temp, close_function): + def __init__(self, screen, change_temp, pid_calibrate, close_function): super().__init__(orientation=Gtk.Orientation.VERTICAL) self.labels = {} self.change_temp = change_temp + self.pid_calibrate = pid_calibrate self.screen = screen self._gtk = screen.gtk @@ -48,32 +49,52 @@ class Keypad(Gtk.Box): self.labels['entry'].props.xalign = 0.5 self.labels['entry'].connect("activate", self.update_entry, "E") + self.pid = self._gtk.Button('heat-up', _('Calibrate') + ' PID', None, .66, Gtk.PositionType.LEFT, 1) + self.pid.connect("clicked", self.update_entry, "PID") + self.pid.set_sensitive(False) b = self._gtk.Button('cancel', _('Close'), None, .66, Gtk.PositionType.LEFT, 1) b.connect("clicked", close_function) self.add(self.labels['entry']) self.add(numpad) - self.add(b) + self.bottom = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + self.bottom.add(b) + self.add(self.bottom) self.labels["keypad"] = numpad + def show_pid(self, can_pid): + if can_pid and self.pid not in self.bottom: + self.bottom.add(self.pid) + self.bottom.reorder_child(self.pid, 0) + elif self.pid in self.bottom: + self.bottom.remove(self.pid) + def clear(self): self.labels['entry'].set_text("") def update_entry(self, widget, digit): text = self.labels['entry'].get_text() + temp = self.validate_temp(text) if digit == 'B': if len(text) < 1: return self.labels['entry'].set_text(text[:-1]) elif digit == 'E': - try: - temp = int(text) - except ValueError: - temp = 0 self.change_temp(temp) self.labels['entry'].set_text("") - elif len(text) >= 3: + elif digit == 'PID': + self.pid_calibrate(temp) + self.labels['entry'].set_text("") + elif len(text + digit) > 3: return else: self.labels['entry'].set_text(text + digit) + self.pid.set_sensitive(self.validate_temp(self.labels['entry'].get_text()) > 9) + + @staticmethod + def validate_temp(temp): + try: + return int(temp) + except ValueError: + return 0 diff --git a/panels/main_menu.py b/panels/main_menu.py index b0cfe43b..74ae7e1e 100644 --- a/panels/main_menu.py +++ b/panels/main_menu.py @@ -188,13 +188,10 @@ class MainPanel(MenuPanel): self.update_graph_visibility() def change_target_temp(self, temp): - - max_temp = int(float(self._printer.get_config_section(self.active_heater)['max_temp'])) - if temp > max_temp: - self._screen.show_popup_message(_("Can't set above the maximum:") + f' {max_temp}') - return - temp = max(temp, 0) name = self.active_heater.split()[1] if len(self.active_heater.split()) > 1 else self.active_heater + temp = self.verify_max_temp(temp) + if temp is False: + return if self.active_heater.startswith('extruder'): self._screen._ws.klippy.set_tool_temp(self._printer.get_tool_number(self.active_heater), temp) @@ -209,6 +206,26 @@ class MainPanel(MenuPanel): self._screen.show_popup_message(_("Unknown Heater") + " " + self.active_heater) self._printer.set_dev_stat(self.active_heater, "target", temp) + def verify_max_temp(self, temp): + temp = int(temp) + max_temp = int(float(self._printer.get_config_section(self.active_heater)['max_temp'])) + logging.debug(f"{temp}/{max_temp}") + if temp > max_temp: + self._screen.show_popup_message(_("Can't set above the maximum:") + f' {max_temp}') + return False + return max(temp, 0) + + def pid_calibrate(self, temp): + if self.verify_max_temp(temp): + script = {"script": f"PID_CALIBRATE HEATER={self.active_heater} TARGET={temp}"} + self._screen._confirm_send_action( + None, + _("Initiate a PID calibration for:") + f" {self.active_heater} @ {temp} ºC" + + "\n\n" + _("It may take more than 5 minutes depending on the heater power."), + "printer.gcode.script", + script + ) + def create_left_panel(self): self.labels['devices'] = Gtk.Grid() @@ -269,7 +286,10 @@ class MainPanel(MenuPanel): self.devices[self.active_heater]['name'].get_style_context().add_class("button_active") if "keypad" not in self.labels: - self.labels["keypad"] = Keypad(self._screen, self.change_target_temp, self.hide_numpad) + self.labels["keypad"] = Keypad(self._screen, self.change_target_temp, self.pid_calibrate, self.hide_numpad) + can_pid = self._printer.state not in ["printing", "paused"] \ + and self._screen.printer.config[self.active_heater]['control'] == 'pid' + self.labels["keypad"].show_pid(can_pid) self.labels["keypad"].clear() if self._screen.vertical_mode: diff --git a/panels/temperature.py b/panels/temperature.py index 8e84d7e2..29e410d8 100644 --- a/panels/temperature.py +++ b/panels/temperature.py @@ -400,11 +400,9 @@ class TemperaturePanel(ScreenPanel): def change_target_temp(self, temp): name = self.active_heater.split()[1] if len(self.active_heater.split()) > 1 else self.active_heater - max_temp = int(float(self._printer.get_config_section(self.active_heater)['max_temp'])) - if temp > max_temp: - self._screen.show_popup_message(_("Can't set above the maximum:") + f' {max_temp}') + temp = self.verify_max_temp(temp) + if temp is False: return - temp = max(temp, 0) if self.active_heater.startswith('extruder'): self._screen._ws.klippy.set_tool_temp(self._printer.get_tool_number(self.active_heater), temp) @@ -419,6 +417,26 @@ class TemperaturePanel(ScreenPanel): self._screen.show_popup_message(_("Unknown Heater") + " " + self.active_heater) self._printer.set_dev_stat(self.active_heater, "target", temp) + def verify_max_temp(self, temp): + temp = int(temp) + max_temp = int(float(self._printer.get_config_section(self.active_heater)['max_temp'])) + logging.debug(f"{temp}/{max_temp}") + if temp > max_temp: + self._screen.show_popup_message(_("Can't set above the maximum:") + f' {max_temp}') + return False + return max(temp, 0) + + def pid_calibrate(self, temp): + if self.verify_max_temp(temp): + script = {"script": f"PID_CALIBRATE HEATER={self.active_heater} TARGET={temp}"} + self._screen._confirm_send_action( + None, + _("Initiate a PID calibration for:") + f" {self.active_heater} @ {temp} ºC" + + "\n\n" + _("It may take more than 5 minutes depending on the heater power."), + "printer.gcode.script", + script + ) + def create_left_panel(self): self.labels['devices'] = Gtk.Grid() @@ -517,7 +535,10 @@ class TemperaturePanel(ScreenPanel): self.devices[self.active_heater]['name'].get_style_context().add_class("button_active") if "keypad" not in self.labels: - self.labels["keypad"] = Keypad(self._screen, self.change_target_temp, self.hide_numpad) + self.labels["keypad"] = Keypad(self._screen, self.change_target_temp, self.pid_calibrate, self.hide_numpad) + can_pid = self._printer.state not in ["printing", "paused"] \ + and self._screen.printer.config[self.active_heater]['control'] == 'pid' + self.labels["keypad"].show_pid(can_pid) self.labels["keypad"].clear() if self._screen.vertical_mode: