Use f-strings Avoid unnecessary casts to str()bool()int() Ensure file closure Merge nested ifs Simplify for-assigns-appends with comprehensions and internal functions Avoid shadowing internal function names Initialize variables Return value directly instead of assign then return Make some methods static
155 lines
5.3 KiB
Python
155 lines
5.3 KiB
Python
import gi
|
|
import logging
|
|
|
|
gi.require_version("Gtk", "3.0")
|
|
from gi.repository import Gtk, GLib, Pango
|
|
|
|
from ks_includes.KlippyGcodes import KlippyGcodes
|
|
from ks_includes.screen_panel import ScreenPanel
|
|
|
|
|
|
def create_panel(*args):
|
|
return FanPanel(*args)
|
|
|
|
|
|
CHANGEABLE_FANS = ["fan", "fan_generic"]
|
|
|
|
|
|
class FanPanel(ScreenPanel):
|
|
|
|
def initialize(self, panel_name):
|
|
self.fan_speed = {}
|
|
self.user_selecting = False
|
|
self.devices = {}
|
|
# Create a grid for all devices
|
|
self.labels['devices'] = Gtk.Grid()
|
|
self.labels['devices'].set_valign(Gtk.Align.CENTER)
|
|
|
|
self.load_fans()
|
|
|
|
scroll = self._gtk.ScrolledWindow()
|
|
scroll.add(self.labels['devices'])
|
|
|
|
self.content.add(scroll)
|
|
|
|
def process_update(self, action, data):
|
|
if action != "notify_status_update":
|
|
return
|
|
|
|
for fan in self.devices:
|
|
if fan in data and "speed" in data[fan]:
|
|
self.update_fan_speed(None, fan, self._printer.get_fan_speed(fan, data[fan]["speed"]))
|
|
|
|
def update_fan_speed(self, widget, fan, speed):
|
|
if fan not in self.devices:
|
|
return
|
|
|
|
if self.devices[fan]['changeable'] is True:
|
|
if self.devices[fan]['scale'].has_grab():
|
|
return
|
|
self.devices[fan]["speed"] = round(float(speed) * 100)
|
|
self.devices[fan]['scale'].disconnect_by_func(self.set_fan_speed)
|
|
self.devices[fan]['scale'].set_value(self.devices[fan]["speed"])
|
|
self.devices[fan]['scale'].connect("button-release-event", self.set_fan_speed, fan)
|
|
else:
|
|
self.devices[fan]["speed"] = float(speed)
|
|
self.devices[fan]['scale'].set_fraction(self.devices[fan]["speed"])
|
|
if widget is not None:
|
|
self.set_fan_speed(None, None, fan)
|
|
|
|
def add_fan(self, fan):
|
|
|
|
logging.info(f"Adding fan: {fan}")
|
|
changeable = any(fan.startswith(x) or fan == x for x in CHANGEABLE_FANS)
|
|
name = Gtk.Label()
|
|
fan_name = _("Part Fan") if fan == "fan" else " ".join(fan.split(" ")[1:])
|
|
name.set_markup(f"\n<big><b>{fan_name}</b></big>\n")
|
|
name.set_hexpand(True)
|
|
name.set_vexpand(True)
|
|
name.set_halign(Gtk.Align.START)
|
|
name.set_valign(Gtk.Align.CENTER)
|
|
name.set_line_wrap(True)
|
|
name.set_line_wrap_mode(Pango.WrapMode.WORD_CHAR)
|
|
|
|
fan_col = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
|
|
stop_btn = self._gtk.ButtonImage("cancel", None, "color1", 1)
|
|
stop_btn.set_hexpand(False)
|
|
stop_btn.connect("clicked", self.update_fan_speed, fan, 0)
|
|
max_btn = self._gtk.ButtonImage("fan-on", _("Max"), "color2", 1)
|
|
max_btn.set_hexpand(False)
|
|
max_btn.connect("clicked", self.update_fan_speed, fan, 100)
|
|
|
|
speed = float(self._printer.get_fan_speed(fan))
|
|
if changeable:
|
|
speed = round(speed * 100)
|
|
scale = Gtk.Scale.new_with_range(orientation=Gtk.Orientation.HORIZONTAL, min=0, max=100, step=1)
|
|
scale.set_value(speed)
|
|
scale.set_digits(0)
|
|
scale.set_hexpand(True)
|
|
scale.set_has_origin(True)
|
|
scale.get_style_context().add_class("fan_slider")
|
|
scale.connect("button-release-event", self.set_fan_speed, fan)
|
|
fan_col.add(stop_btn)
|
|
fan_col.add(scale)
|
|
fan_col.add(max_btn)
|
|
else:
|
|
scale = Gtk.ProgressBar()
|
|
scale.set_fraction(speed)
|
|
scale.set_show_text(True)
|
|
scale.set_hexpand(True)
|
|
fan_col.pack_start(scale, True, True, 10)
|
|
|
|
fan_row = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
fan_row.add(name)
|
|
fan_row.add(fan_col)
|
|
|
|
frame = Gtk.Frame()
|
|
frame.get_style_context().add_class("frame-item")
|
|
frame.add(fan_row)
|
|
|
|
self.devices[fan] = {
|
|
"changeable": changeable,
|
|
"scale": scale,
|
|
"speed": speed,
|
|
}
|
|
|
|
devices = sorted(self.devices)
|
|
if fan == "fan":
|
|
pos = 0
|
|
elif "fan" in devices:
|
|
devices.pop(devices.index("fan"))
|
|
pos = devices.index(fan) + 1
|
|
else:
|
|
pos = devices.index(fan)
|
|
|
|
self.labels['devices'].insert_row(pos)
|
|
self.labels['devices'].attach(frame, 0, pos, 1, 1)
|
|
self.labels['devices'].show_all()
|
|
|
|
def load_fans(self):
|
|
fans = self._printer.get_fans()
|
|
for fan in fans:
|
|
# Support for hiding devices by name
|
|
name = " ".join(fan.split(" ")[1:]) if fan != "fan" else fan
|
|
if name.startswith("_"):
|
|
continue
|
|
self.add_fan(fan)
|
|
frame = Gtk.Frame()
|
|
frame.set_vexpand(False)
|
|
self.labels['devices'].attach(frame, 0, -1, 1, 1)
|
|
|
|
def set_fan_speed(self, widget, event, fan):
|
|
value = self.devices[fan]['scale'].get_value()
|
|
|
|
if fan == "fan":
|
|
self._screen._ws.klippy.gcode_script(KlippyGcodes.set_fan_speed(value))
|
|
else:
|
|
f = " ".join(fan.split(" ")[1:])
|
|
self._screen._ws.klippy.gcode_script(f"SET_FAN_SPEED FAN={f} SPEED={float(value) / 100}")
|
|
# Check the speed in case it wasn't applied
|
|
GLib.timeout_add_seconds(1, self.check_fan_speed, fan)
|
|
|
|
def check_fan_speed(self, fan):
|
|
self.update_fan_speed(None, fan, self._printer.get_fan_speed(fan))
|
|
return False
|