Updates to graphing.

Modify heaters to show only ones available in the temp store. Add 
ability to hide/show heaters.
This commit is contained in:
Jordan 2021-09-28 22:53:00 -04:00 committed by jordanruthe
parent 5bfcd0108a
commit 139115a0e9
5 changed files with 200 additions and 59 deletions

View File

@ -36,6 +36,32 @@ class KlippyGtk:
self.header_image_scale_height = 1.4
self.cursor = cursor
self.color_list = {
"extruder": {
"base": 'ff5252',
"hsplit": int('20', 16),
"state": 0
},
"bed": {
"base": '1fb0ff',
"hsplit": int('20', 16),
"state": 0
},
"fan": {
"colors": ['3DC25A', '58FC7C', '10EB40', '7EF297'],
"state": 0
},
"sensor": {
"colors": ['D67600', '830EE3', 'B366F2', 'E06573', 'E38819'],
"state": 0
}
}
for key in self.color_list:
if "base" in self.color_list[key]:
rgb = [int(self.color_list[key]['base'][i:i+2], 16) for i in range(0, 6, 2)]
self.color_list[key]['rgb'] = rgb
logging.debug("img width: %s height: %s" % (self.img_width, self.img_height))
def get_action_bar_width(self):
@ -65,6 +91,29 @@ class KlippyGtk:
def get_keyboard_height(self):
return (self.width - self.get_action_bar_width()) * self.keyboard_ratio
def get_temp_color(self, device):
if device not in self.color_list:
return False, False
if 'base' in self.color_list[device]:
rgb = self.color_list[device]['rgb'].copy()
if self.color_list[device]['state'] > 0:
rgb[1] = rgb[1] + self.color_list[device]['hsplit'] * self.color_list[device]['state']
self.color_list[device]['state'] += 1
color = '{:02X}{:02X}{:02X}'.format(rgb[0], rgb[1], rgb[2])
rgb = [x/255 for x in rgb]
else:
colors = self.color_list[device]['colors']
color = colors[self.color_list[device]['state'] % len(colors)]
rgb = [int(color[i:i+2], 16)/255 for i in range(0, 6, 2)]
return rgb, color
def reset_temp_color(self):
for key in self.color_list:
self.color_list[key]['state'] = 0
def Label(self, label, style=None):
la = Gtk.Label(label)
if style is not None and style is not False:
@ -80,7 +129,7 @@ class KlippyGtk:
image = Gtk.Image.new_from_pixbuf(pixbuf)
label = Gtk.Label()
label.set_text(text)
label.set_markup(text)
box1.add(image)
box1.add(label)
@ -90,6 +139,25 @@ class KlippyGtk:
return {"l": label, "b": box1}
def ImageMenuButton(self, image_name, text, size=20, style=False, width_scale=.32, height_scale=.32, popover=False):
box1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=15)
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
"%s/styles/%s/images/%s.svg" % (klipperscreendir, self.theme, str(image_name)),
int(round(self.img_width * width_scale)), int(round(self.img_height * height_scale)), True)
image = Gtk.Image.new_from_pixbuf(pixbuf)
mb = Gtk.MenuButton(label="", popover=popover)
label = mb.get_label()
box1.add(image)
box1.add(mb)
if style is not False:
ctx = box1.get_style_context()
ctx.add_class(style)
return {"l": label, "mb": mb, "b": box1}
def Image(self, image_name, style=False, width_scale=1, height_scale=1):
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
"%s/styles/%s/images/%s" % (klipperscreendir, self.theme, str(image_name)),

View File

@ -20,7 +20,7 @@ class HeaterGraph(Gtk.DrawingArea):
def add_object(self, name, type, rgb=[0, 0, 0], dashed=False, fill=False):
if name not in self.store:
self.store.update({name: {}})
self.store.update({name: {"show": True}})
self.store[name].update({type: {
"dashed": dashed,
"fill": fill,
@ -32,6 +32,8 @@ class HeaterGraph(Gtk.DrawingArea):
mnum = []
for x in self.store:
for t in self.store[x]:
if t == "show":
continue
mnum.append(max(self.printer.get_temp_store(x, t, data_points)))
return max(mnum)
@ -63,8 +65,10 @@ class HeaterGraph(Gtk.DrawingArea):
[g_width, g_height]
]
points_per_pixel = 2
points_per_pixel = self.max_length / (gsize[1][0]-gsize[0][0])
data_points = (gsize[1][0]-gsize[0][0]) * points_per_pixel
logging.info("aa: %s %s" % (points_per_pixel, data_points))
max_num = math.ceil(self.get_max_num(data_points) * 1.1 / 10) * 10
d_width = 1 / points_per_pixel
@ -72,6 +76,8 @@ class HeaterGraph(Gtk.DrawingArea):
self.graph_time(ctx, gsize, points_per_pixel)
for name in self.store:
if not self.store[name]['show']:
continue
for type in self.store[name]:
d = self.printer.get_temp_store(name, type, data_points)
if d is False:
@ -163,3 +169,13 @@ class HeaterGraph(Gtk.DrawingArea):
ctx.show_text("%02d:%02d" % (hour, min))
ctx.stroke()
i += 1
def is_showing(self, device):
if device not in self.store:
return False
return self.store[device]['show']
def set_showing(self, device, show=True):
if device not in self.store:
return
self.store[device]['show'] = show

View File

@ -53,10 +53,6 @@ class Printer:
"temperature": 0,
"target": 0
}
self.tempstore[x] = {
"temperatures": [0 for x in range(1200)],
"targets": [0 for x in range(1200)]
}
self.tools.append(x)
self.tools = sorted(self.tools)
self.toolcount += 1
@ -69,10 +65,6 @@ class Printer:
"temperature": 0,
"target": 0
}
self.tempstore[x] = {
"temperatures": [0 for x in range(1200)],
"targets": [0 for x in range(1200)]
}
if x.startswith('bed_mesh '):
r = self.config[x]
r['x_count'] = int(r['x_count'])
@ -282,6 +274,15 @@ class Printer:
def get_extruder_count(self):
return self.extrudercount
def get_temp_store_devices(self):
return list(self.tempstore)
def get_temp_store_device_has_target(self, device):
if device in self.tempstore:
if "targets" in self.tempstore[device]:
return True
return False
def get_temp_store(self, device, section=False, results=0):
if device not in self.tempstore:
return False
@ -312,11 +313,12 @@ class Printer:
def init_temp_store(self, result):
for dev in result:
if dev in self.tempstore:
if "targets" in result[dev]:
self.tempstore[dev]["targets"] = result[dev]["targets"]
if "temperatures" in result[dev]:
self.tempstore[dev]["temperatures"] = result[dev]["temperatures"]
self.tempstore[dev] = {}
if "targets" in result[dev]:
self.tempstore[dev]["targets"] = result[dev]["targets"]
if "temperatures" in result[dev]:
self.tempstore[dev]["temperatures"] = result[dev]["temperatures"]
logging.info("Temp store: %s" % list(self.tempstore))
def section_exists(self, section):
if section in self.get_config_section_list():

View File

@ -64,19 +64,45 @@ class MainPanel(MenuPanel):
if d.startswith('extruder'):
i += 1
image = "extruder-%s" % i
class_name = "graph_label_%s" % device
rgb, color = self._gtk.get_temp_color("extruder")
elif device == "heater_bed":
image = "bed"
devname = "Heater Bed"
class_name = "graph_label_heater_bed"
rgb = [1, 0, 0]
rgb, color = self._gtk.get_temp_color("bed")
else:
s = 1
for d in self.devices:
if "sensor" in d:
s += 1
image = "heat-up"
class_name = "graph_label_sensor_%s" % s
rgb = [1, 0, 0]
rgb, color = self._gtk.get_temp_color("sensor")
can_target = self._printer.get_temp_store_device_has_target(device)
self.labels['da'].add_object(device, "temperatures", rgb, False, True)
if can_target:
self.labels['da'].add_object(device, "targets", rgb, True, False)
text = "<span underline='double' underline_color='#%s'>%s</span>" % (color, devname.capitalize())
name = self._gtk.ButtonImage(image, devname.capitalize(), None, .5, .5, Gtk.PositionType.LEFT, False)
# name['b'].set_hexpand(True)
name.connect('clicked', self.on_popover_clicked, device)
name.set_alignment(0, .5)
name.get_style_context().add_class(class_name)
logging.info("DClass %s %s" % (device, class_name))
name = self._gtk.ImageLabel(image, devname.capitalize(), 20, False, .5, .5)
name['b'].set_hexpand(True)
temp = Gtk.Label("")
temp.set_markup(self.format_temp(self._printer.get_dev_stat(device, "temperature")))
target = Gtk.Label("")
target.set_markup(self.format_target(self._printer.get_dev_stat(device, "target")))
if can_target:
target = Gtk.Label("")
target.set_markup(self.format_target(self._printer.get_dev_stat(device, "target")))
labels = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
@ -87,20 +113,45 @@ class MainPanel(MenuPanel):
self.devices[device] = {
"name": name,
"target": target,
"temp": temp,
"temp": temp
}
if can_target:
self.devices[device]["target"] = target
devices = sorted(self.devices)
pos = devices.index(device) + 1
self.labels['devices'].insert_row(pos)
self.labels['devices'].attach(name['b'], 0, pos, 1, 1)
# self.labels['devices'].attach(name['b'], 0, pos, 1, 1)
self.labels['devices'].attach(name, 0, pos, 1, 1)
self.labels['devices'].attach(temp, 1, pos, 1, 1)
self.labels['devices'].attach(target, 2, pos, 1, 1)
if can_target:
self.labels['devices'].attach(target, 2, pos, 1, 1)
self.labels['devices'].show_all()
def on_popover_clicked(self, widget, device):
self.popover_device = device
po = self.labels['popover']
po.set_relative_to(widget)
self.popover_populate_menu()
po.show_all()
def popover_populate_menu(self):
pobox = self.labels['popover_vbox']
for child in pobox.get_children():
pobox.remove(child)
if self.labels['da'].is_showing(self.popover_device):
pobox.pack_start(self.labels['graph_hide'], True, True, 5)
else:
pobox.pack_start(self.labels['graph_show'], True, True, 5)
def graph_show_device(self, widget, show=True):
logging.info("Graph show: %s %s" % (self.popover_device, show))
self.labels['da'].set_showing(self.popover_device, show)
self.labels['da'].queue_draw()
self.popover_populate_menu()
self.labels['popover'].show_all()
def create_left_panel(self):
_ = self.lang.gettext
@ -117,19 +168,8 @@ class MainPanel(MenuPanel):
self.labels['devices'].attach(temp, 1, 0, 1, 1)
self.labels['devices'].attach(target, 2, 0, 1, 1)
rgbs = [
[0, 1, 0],
[1, 0, 0],
[0, 0, 1]
]
heaters = ['heater_bed', 'extruder']
i = 0
da = HeaterGraph(self._printer)
da.set_vexpand(True)
for h in heaters:
da.add_object(h, "temperatures", rgbs[i], False, True)
da.add_object(h, "targets", rgbs[i], True, False)
i += 1
self.labels['da'] = da
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=0)
@ -137,32 +177,25 @@ class MainPanel(MenuPanel):
box.add(self.labels['devices'])
box.add(da)
self.load_devices()
self.labels['graph_hide'] = self._gtk.Button(label="Hide")
self.labels['graph_hide'].connect("clicked", self.graph_show_device, False)
self.labels['graph_show'] = self._gtk.Button(label="Show")
self.labels['graph_show'].connect("clicked", self.graph_show_device)
popover = Gtk.Popover()
self.labels['popover_vbox'] = Gtk.VBox()
# vbox.pack_start(Gtk.Button(label="Hide"), False, True, 10)
# vbox.pack_start(Gtk.Label(label="Item 2"), False, True, 10)
popover.add(self.labels['popover_vbox'])
popover.set_position(Gtk.PositionType.BOTTOM)
self.labels['popover'] = popover
for d in self._printer.get_temp_store_devices():
self.add_device(d)
return box
def load_devices(self):
self.heaters = []
i = 0
for x in self._printer.get_tools():
self.labels[x] = self._gtk.ButtonImage("extruder-"+str(i), self._gtk.formatTemperatureString(0, 0))
self.heaters.append(x)
i += 1
add_heaters = self._printer.get_heaters()
for h in add_heaters:
if h == "heater_bed":
self.labels[h] = self._gtk.ButtonImage("bed", self._gtk.formatTemperatureString(0, 0))
else:
name = " ".join(h.split(" ")[1:])
self.labels[h] = self._gtk.ButtonImage("heat-up", name)
self.heaters.append(h)
for d in self.heaters:
self.add_device(d)
logging.info("Heaters: %s" % self.heaters)
def process_update(self, action, data):
if action != "notify_status_update":
return

View File

@ -430,3 +430,25 @@ trough {
.error {
background-color: rgba(204, 30, 30, 0.7);
}
popover {
background-color: #222;
}
popover button {
background-color: #222;
}
/* Hardcoded values until creation of dynamic CSS updates */
.graph_label_extruder {border-left: .4em solid #ff5252;}
.graph_label_extruder2 {border-left: .4em solid #ff7252;}
.graph_label_heater_bed {border-left: .4em solid #1fb0ff;}
.graph_label_fan_1 {border-left: .4em solid #3DC25A;}
.graph_label_fan_2 {border-left: .4em solid #58FC7C;}
.graph_label_fan_3 {border-left: .4em solid #10EB40;}
.graph_label_fan_4 {border-left: .4em solid #7EF297;}
.graph_label_sensor_1 {border-left: .4em solid #D67600;}
.graph_label_sensor_2 {border-left: .4em solid #830EE3;}
.graph_label_sensor_3 {border-left: .4em solid #B366F2;}
.graph_label_sensor_4 {border-left: .4em solid #E06573;}
.graph_label_sensor_5 {border-left: .4em solid #E38819;}