job_status/settings: Allow different file estimation methods

This commit is contained in:
Jordan Ruthe 2021-01-20 22:06:48 -05:00
parent 52cadb7744
commit f297699396
6 changed files with 101 additions and 19 deletions

View File

@ -1,5 +1,10 @@
## Changelog
#### 2021 01 20
* Add different time estimation methods to settings panel
* Job status panel will use time estimation method selected from settings panel
* Bugfixes to state tracking
#### 2021 01 10
* Added system reboot/shutdown buttons to systems panel.

View File

@ -179,6 +179,12 @@ name: {{ gettext('System') }}
icon: info
panel: system
[menu __print settings]
name: {{ gettext('Settings') }}
icon: settings
panel: settings
[menu __splashscreen]
name: {{ gettext('Menu') }}

View File

@ -25,7 +25,15 @@ class KlipperScreenConfig:
self.configurable_options = [
{"invert_x": {"section": "main", "name": _("Invert X"), "type": "binary", "value": "False"}},
{"invert_y": {"section": "main", "name": _("Invert Y"), "type": "binary", "value": "False"}},
{"invert_z": {"section": "main", "name": _("Invert Z"), "type": "binary", "value": "False"}}
{"invert_z": {"section": "main", "name": _("Invert Z"), "type": "binary", "value": "False"}},
{"print_estimate_method": {"section": "main", "name": _("Estimated Time Method"), "type": "dropdown",
"value": "file","options":[
{"name": _("File Estimation (default)"), "value": "file"},
{"name": _("Duration Only"), "value": "duration"},
{"name": _("Filament Used"), "value": "filament"},
{"name": _("Slicer"), "value": "slicer"}
]}}
#{"": {"section": "main", "name": _(""), "type": ""}}
]
self.default_config_path = "%s/ks_includes/%s" % (os.getcwd(), self.configfile_name)

View File

@ -24,6 +24,7 @@ class JobStatusPanel(ScreenPanel):
_ = self.lang.gettext
self.layout = Gtk.Layout()
self.layout.set_size(self._screen.width, self._screen.height)
self.timeleft_type = "file"
self.create_buttons()
@ -322,7 +323,7 @@ class JobStatusPanel(ScreenPanel):
self.disable_button("pause","resume","cancel")
self._screen._ws.klippy.print_cancel(self._response_callback)
def _response_callback(self, response, method, params, func, *args):
def _response_callback(self, response, method, params, func=None, *args):
if func == "enable_button":
self.enable_button(*args)
@ -435,18 +436,33 @@ class JobStatusPanel(ScreenPanel):
self.progress = progress
self.labels['darea'].queue_draw()
if ps['print_duration'] == 0:
time_left = self.file_metadata['estimated_time'] if "estimated_time" in self.file_metadata else 0
else:
est_time = self.file_metadata['estimated_time'] if "estimated_time" in self.file_metadata else 0
time_left = max(
est_time - ps['print_duration'] ,
0 #ps['print_duration'] / (vsd['progress'] if vsd['progress'] != 0 else 1)
)
self.update_text("duration", str(self._gtk.formatTimeString(ps['print_duration'])))
timeleft_type = self._config.get_config()['main'].get('print_estimate_method','file')
if timeleft_type != self.timeleft_type:
if self.timeleft_type == "duration":
self.labels['it_box'].add(self.labels['est_time'])
elif timeleft_type == "duration":
self.labels['it_box'].remove(self.labels['est_time'])
self.timeleft_type = timeleft_type
if timeleft_type in ['filament','file','slicer']:
duration = ps['print_duration']
if timeleft_type == "filament":
estimated_filament = (self.file_metadata['filament_total'] if "filament_total" in self.file_metadata
else 1)
total_duration = duration / (ps['filament_used'] / estimated_filament)
elif timeleft_type == "file":
total_duration = duration / max(self.progress, 0.0001)
elif timeleft_type == "slicer":
total_duration = (self.file_metadata['estimated_time'] if "estimated_time" in self.file_metadata
else duration)
time_left = max(total_duration - duration, 0)
self.update_text("time_left", str(self._gtk.formatTimeString(time_left)))
self.update_progress()
self.update_progress()
if "pause_resume" in data and self.state != "complete":
if self.state == "paused" and data['pause_resume']['is_paused'] == False:

View File

@ -23,17 +23,17 @@ class SettingsPanel(ScreenPanel):
self.labels['main_box'] = self.create_box('main')
self.labels['macros_box'] = self.create_box('macros')
options = self._config.get_configurable_options()
options = self._config.get_configurable_options().copy()
options.append({"macros": {
"name": _("Displayed Macros"),
"type": "menu",
"menu": "macros"}
})
for option in options:
name = list(option)[0]
self.add_option('main', self.settings, name, option[name])
self.add_option('main', self.settings, "macros", {
"name": _("Displayed Macros"),
"type": "menu",
"menu": "macros"
})
for macro in self._printer.get_config_section_list("gcode_macro "):
macro = macro[12:]
self.macros[macro] = {
@ -120,6 +120,19 @@ class SettingsPanel(ScreenPanel):
switch.set_property("height-request", round(self._gtk.get_image_height()*1.25))
box.add(switch)
dev.add(box)
elif option['type'] == "dropdown":
dropdown = Gtk.ComboBoxText()
i = 0
for opt in option['options']:
dropdown.append(opt['value'], opt['name'])
if opt['value'] == self._config.get_config()[option['section']].get(opt_name, option['value']):
dropdown.set_active(i)
i += 1
dropdown.connect("changed", self.on_dropdown_change, option['section'], opt_name)
#dropdown.props.relief = Gtk.ReliefStyle.NONE
dropdown.set_entry_text_column(0)
dev.add(dropdown)
logger.debug("Children: %s" % dropdown.get_children())
elif option['type'] == "menu":
open = self._gtk.ButtonImage("open",None,"color3")
open.connect("clicked", self.load_menu, option['menu'])
@ -128,12 +141,15 @@ class SettingsPanel(ScreenPanel):
dev.add(open)
frame.add(dev)
frame.show_all()
opt_array[opt_name] = {
"name": option['name'],
"row": frame
}
opts = sorted(opt_array)
opts = sorted(list(opt_array), key=lambda x: opt_array[x]['name'])
pos = opts.index(opt_name)
self.labels[boxname].insert_row(pos)
@ -162,6 +178,15 @@ class SettingsPanel(ScreenPanel):
self.content.add(self.labels[self.menu[-1]])
self.content.show_all()
def on_dropdown_change(self, combo, section, option):
tree_iter = combo.get_active_iter()
if tree_iter is not None:
model = combo.get_model()
value = model[tree_iter][1]
logger.debug("[%s] %s changed to %s" % (section, option, value))
self._config.set(section, option, value)
self._config.save_user_config_options()
def switch_config_option(self, switch, gparam, section, option):
logger.debug("[%s] %s toggled %s" % (section, option, switch.get_active()))
if section not in self._config.get_config().sections():

View File

@ -1,6 +1,7 @@
* {
color: #fff;
font-size: KS_FONT_SIZEpx;
-GtkComboBox-appears-as-list: 0;
}
window {
@ -50,6 +51,11 @@ button.file-list {
margin: 0;
}
combobox box button {
border: .05em solid #cccccc;
padding: .5em 1em;
}
entry {
font-size: 1em;
background-color: #20292F;
@ -66,6 +72,18 @@ label {
color: white;
}
menu {
background-color: #13181C;
border: .1em solid #cccccc;
}
menuitem {
background-color: #13181C;
border: .1em solid #cccccc;
border-bottom: 0;
border-top: 0;
}
progress, trough {
min-height: 2em;
background-color: #404E57;
@ -97,6 +115,10 @@ trough {
margin: .5em 1em;
}
.popup {
background-color: #0000ff;
}
.dialog {
border: .1em solid black;
padding: 2.5em;