import logging import gi import time import os.path import pathlib gi.require_version("Gtk", "3.0") from gi.repository import Gtk from ks_includes.screen_panel import ScreenPanel from ks_includes.ModelConfig import ModelConfig class Panel(ScreenPanel): def __init__(self, screen, title): title = title or _("System") super().__init__(screen, title) self.current_row = 0 self.mem_multiplier = None self.model_config = None self.scales = {} self.labels = {} self.models = {} self.click_count = 0 self.last_click_time = 0 self.click_threshold = 0.2 self.target_clicks = 10 self.grid = Gtk.Grid(column_spacing=10, row_spacing=5) sysinfo = screen.printer.system_info logging.info(sysinfo) self.cpu_count = int(sysinfo["cpu_info"]["cpu_count"]) self.labels["cpu_usage"] = Gtk.Label(label="", xalign=0) self.grid.attach(self.labels["cpu_usage"], 0, self.current_row, 1, 1) self.scales["cpu_usage"] = Gtk.ProgressBar( hexpand=True, show_text=False, fraction=0 ) self.grid.attach(self.scales["cpu_usage"], 1, self.current_row, 1, 1) self.current_row += 1 self.labels["memory_usage"] = Gtk.Label(label="", xalign=0) self.grid.attach(self.labels["memory_usage"], 0, self.current_row, 1, 1) self.scales["memory_usage"] = Gtk.ProgressBar( hexpand=True, show_text=False, fraction=0 ) self.grid.attach(self.scales["memory_usage"], 1, self.current_row, 1, 1) self.current_row += 1 self.grid.attach(Gtk.Separator(), 0, self.current_row, 2, 1) self.current_row += 1 self.machine_info(sysinfo) self.current_row += 1 self.populate_info(sysinfo) scroll = self._gtk.ScrolledWindow() scroll.add(self.grid) self.content.add(scroll) if self.model_config is None: self.model_config = ModelConfig() self.labels["model_menu"] = self._gtk.ScrolledWindow() self.labels["model"] = Gtk.Grid() self.labels["model_menu"].add(self.labels["model"]) klipperscreendir = pathlib.Path(__file__).parent.resolve().parent self.model_list_path = os.path.join( klipperscreendir, "config", "model_menu.conf" ) self.model_list = pathlib.Path(self.model_list_path).read_text() with open(self.model_list_path) as file: for line in file: model_name = line.strip() self.models[model_name] = { "name": model_name, "type": "button", "callback": self.change_model, } self.add_option( "model", self.models, model_name, self.models[model_name] ) def change_model(self, widget, event): self.model_config.generate_config(event) def on_model_click(self, widget, event): current_time = time.time() if (current_time - self.last_click_time) <= self.click_threshold: self.click_count += 1 else: self.click_count = 0 self.last_click_time = current_time if self.click_count == self.target_clicks: self.click_count = 0 self.load_menu("system", _("model")) def set_mem_multiplier(self, data): memory_units = data.get("memory_units", "kB").lower() units_mapping = { "kb": 1024, "mb": 1024**2, "gb": 1024**3, "tb": 1024**4, "pb": 1024**5, } self.mem_multiplier = units_mapping.get(memory_units, 1) def add_label_to_grid(self, text, column, bold=False): if bold: text = f"{text}" label = Gtk.Label(label=text, use_markup=True, xalign=0, wrap=True) self.grid.attach(label, column, self.current_row, 1, 1) self.current_row += 1 def machine_info(self, sysinfo): self.add_label_to_grid(self.prettify("device"), 0, bold=True) self.current_row -= 1 self.add_label_to_grid("Maker: CreatBot", 1) event_box = Gtk.EventBox() event_box.connect("button-press-event", self.on_model_click) mode = self._screen.connecting_to_printer.split("-")[0] label = Gtk.Label(label=f"Model: {mode}", use_markup=True, xalign=0, wrap=True) self.grid.attach(event_box, 1, self.current_row, 1, 1) self.current_row += 1 event_box.add(label) self.add_label_to_grid(f"Name: {self._screen.connecting_to_printer}", 1) def populate_info(self, sysinfo): for category, data in sysinfo.items(): if category == "python": self.add_label_to_grid(self.prettify(category), 0, bold=True) self.current_row -= 1 self.add_label_to_grid( f'Version: {data["version_string"].split(" ")[0]}', 1 ) continue if ( category in ( "virtualization", "provider", "available_services", "service_state", "instance_ids", ) or not sysinfo[category] ): continue self.add_label_to_grid(self.prettify(category), 0, bold=True) if isinstance(data, dict): for key, value in data.items(): if key in ("version_parts", "memory_units") or not value: continue if key == "total_memory": if not self.mem_multiplier: self.set_mem_multiplier(data) value = self.format_size(int(value) * self.mem_multiplier) if isinstance(value, dict): self.add_label_to_grid(self.prettify(key), 0) self.current_row -= 1 for sub_key, sub_value in value.items(): if not sub_value: continue elif ( isinstance(sub_value, list) and sub_key == "ip_addresses" ): for _ip in sub_value: self.add_label_to_grid( f"{self.prettify(sub_key)}: {_ip['address']}", 1 ) continue self.add_label_to_grid( f"{self.prettify(sub_key)}: {sub_value}", 1 ) else: self.add_label_to_grid(f"{self.prettify(key)}: {value}", 1) def process_update(self, action, data): if action == "notify_proc_stat_update": self.labels["cpu_usage"].set_label( f'CPU: {data["system_cpu_usage"]["cpu"]:.0f}%' ) self.scales["cpu_usage"].set_fraction( float(data["system_cpu_usage"]["cpu"]) / 100 ) self.labels["memory_usage"].set_label( _("Memory") + f': {(data["system_memory"]["used"] / data["system_memory"]["total"]) * 100:.0f}%' ) self.scales["memory_usage"].set_fraction( float(data["system_memory"]["used"]) / float(data["system_memory"]["total"]) )