job_status: rework time calculation
New 'Auto' setting that selects the best guess added an slicer time compensation if you find that your slicer always under/over estimates by some amount Split in days if the time is more than 24h
This commit is contained in:
parent
7a4613bfe4
commit
b1dd83d955
@ -333,9 +333,14 @@ class KlippyGtk:
|
||||
def formatTimeString(self, seconds):
|
||||
time = int(seconds)
|
||||
text = ""
|
||||
if int(time/86400) != 0:
|
||||
text += str(int(time/86400))+"d "
|
||||
if int(time/3600) != 0:
|
||||
text += str(int(time/3600))+"h "
|
||||
text += str(int(time/60) % 60)+"m "+str(time % 60)+"s"
|
||||
text += str(int(time/3600) % 24)+"h "
|
||||
if int(time/60) != 0:
|
||||
text += str(int(time/60) % 60)+"m "
|
||||
else:
|
||||
text = str(time % 60)+"s"
|
||||
return text
|
||||
|
||||
def formatTemperatureString(self, temp, target):
|
||||
|
@ -124,8 +124,8 @@ class KlipperScreenConfig:
|
||||
{"print_estimate_method": {
|
||||
"section": "main", "name": _("Estimated Time Method"), "type": "dropdown",
|
||||
"value": "file", "options": [
|
||||
{"name": _("File") + " " + _("(default)"), "value": "file"},
|
||||
{"name": _("Duration Only"), "value": "duration"},
|
||||
{"name": _("Auto") + " " + _("(default)"), "value": "auto"},
|
||||
{"name": _("File"), "value": "file"},
|
||||
{"name": _("Filament Used"), "value": "filament"},
|
||||
{"name": _("Slicer"), "value": "slicer"}]}},
|
||||
{"screen_blanking": {
|
||||
@ -153,6 +153,9 @@ class KlipperScreenConfig:
|
||||
"value": "False", "callback": screen.restart_warning}},
|
||||
{"use_dpms": {"section": "main", "name": _("Screen DPMS"), "type": "binary",
|
||||
"value": "True", "callback": screen.set_dpms}},
|
||||
{"print_estimate_compensation": {
|
||||
"section": "main", "name": _("Slicer Time correction (%)"), "type": "scale", "value": "100",
|
||||
"range": [50, 150], "step": 1}},
|
||||
# {"": {"section": "main", "name": _(""), "type": ""}}
|
||||
]
|
||||
|
||||
|
@ -130,14 +130,21 @@ class JobStatusPanel(ScreenPanel):
|
||||
self.labels['elapsed'].get_style_context().add_class("printing-info")
|
||||
self.labels['duration'] = Gtk.Label(label="0s")
|
||||
self.labels['duration'].get_style_context().add_class("printing-info")
|
||||
self.labels['est_time'] = Gtk.Label(label="/ 0s")
|
||||
self.labels['total'] = Gtk.Label(label=_("Total:"))
|
||||
self.labels['total'].get_style_context().add_class("printing-info")
|
||||
self.labels['est_time'] = Gtk.Label(label="0s")
|
||||
self.labels['est_time'].get_style_context().add_class("printing-info")
|
||||
it_box = Gtk.Box(spacing=0)
|
||||
it_box.add(clock)
|
||||
it_box.add(self.labels['elapsed'])
|
||||
it_box.add(self.labels['duration'])
|
||||
it_box.add(self.labels['est_time'])
|
||||
self.labels['it_box'] = it_box
|
||||
timegrid = Gtk.Grid()
|
||||
it1_box = Gtk.Box(spacing=0)
|
||||
it1_box.add(self.labels['elapsed'])
|
||||
it1_box.add(self.labels['duration'])
|
||||
it2_box = Gtk.Box(spacing=0)
|
||||
it2_box.add(self.labels['total'])
|
||||
it2_box.add(self.labels['est_time'])
|
||||
timegrid.attach(clock, 0, 0, 1, 2)
|
||||
timegrid.attach(it1_box, 1, 0, 1, 1)
|
||||
timegrid.attach(it2_box, 1, 1, 1, 1)
|
||||
self.labels['timegrid'] = timegrid
|
||||
|
||||
position = self._gtk.Image("move.svg", None, .6, .6)
|
||||
self.labels['pos_x'] = Gtk.Label(label="X: 0")
|
||||
@ -241,7 +248,7 @@ class JobStatusPanel(ScreenPanel):
|
||||
self.labels['i2_box'].add(self.labels['temp_grid'])
|
||||
self.labels['i2_box'].add(self.labels['pos_box'])
|
||||
self.labels['i2_box'].add(self.labels['sfe_grid'])
|
||||
self.labels['i2_box'].add(self.labels['it_box'])
|
||||
self.labels['i2_box'].add(self.labels['timegrid'])
|
||||
self.labels['i2_box'].add(self.labels['itl_box'])
|
||||
|
||||
|
||||
@ -412,29 +419,57 @@ class JobStatusPanel(ScreenPanel):
|
||||
self.update_percent_complete()
|
||||
|
||||
self.update_text("duration", str(self._gtk.formatTimeString(ps['print_duration'])))
|
||||
self.update_text("time_left", self.calculate_time_left(ps['print_duration'], ps['filament_used']))
|
||||
|
||||
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
|
||||
def calculate_time_left(self, duration=0, filament_used=0):
|
||||
total_duration = None
|
||||
if self.progress < 1:
|
||||
slicer_time = filament_time = file_time = None
|
||||
timeleft_type = self._config.get_config()['main'].get('print_estimate_method', 'auto')
|
||||
slicer_correction = (self._config.get_config()['main'].getint('print_estimate_compensation', 100) / 100)
|
||||
# speed_factor compensation based on empirical testing
|
||||
spdcomp = math.sqrt(self.speed / 100)
|
||||
|
||||
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 / (max(ps['filament_used'], 0.0001) / max(estimated_filament, 0.0001))
|
||||
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_text("est_time", "/ %s" % str(self._gtk.formatTimeString(total_duration)))
|
||||
if "estimated_time" in self.file_metadata:
|
||||
if self.file_metadata['estimated_time'] > 0:
|
||||
slicer_time = (self.file_metadata['estimated_time'] * slicer_correction) / spdcomp
|
||||
if slicer_time < duration:
|
||||
slicer_time = None
|
||||
|
||||
if "filament_total" in self.file_metadata:
|
||||
if self.file_metadata['filament_total'] > 0 and filament_used > 0:
|
||||
if self.file_metadata['filament_total'] > filament_used:
|
||||
filament_time = duration / (filament_used / self.file_metadata['filament_total'])
|
||||
if filament_time < duration:
|
||||
filament_time = None
|
||||
|
||||
if self.progress > 0:
|
||||
file_time = duration / self.progress
|
||||
|
||||
if timeleft_type == "file" and file_time is not None:
|
||||
total_duration = file_time
|
||||
elif timeleft_type == "filament" and filament_time is not None:
|
||||
total_duration = filament_time
|
||||
elif slicer_time is not None:
|
||||
if timeleft_type == "slicer":
|
||||
total_duration = slicer_time
|
||||
else:
|
||||
if filament_time is not None and self.progress > 0.14:
|
||||
# Weighted arithmetic mean (Slicer is the most accurate)
|
||||
total_duration = (slicer_time * 3 + filament_time + file_time) / 5
|
||||
else:
|
||||
# At the begining file and filament are innacurate
|
||||
total_duration = slicer_time
|
||||
elif file_time is not None:
|
||||
if filament_time is not None:
|
||||
total_duration = (filament_time + file_time) / 2
|
||||
else:
|
||||
total_duration = file_time
|
||||
|
||||
if total_duration is None:
|
||||
return "-"
|
||||
self.update_text("est_time", str(self._gtk.formatTimeString(total_duration)))
|
||||
return str(self._gtk.formatTimeString((total_duration - duration)))
|
||||
|
||||
def state_check(self):
|
||||
ps = self._printer.get_stat("print_stats")
|
||||
@ -541,7 +576,7 @@ class JobStatusPanel(ScreenPanel):
|
||||
self.file_metadata = self._files.get_file_info(self.filename)
|
||||
logging.info("Update Metadata. File: %s Size: %s" % (self.filename, self.file_metadata['size']))
|
||||
if "estimated_time" in self.file_metadata and self.timeleft_type == "slicer":
|
||||
self.update_text("est_time", "/ %s" %
|
||||
self.update_text("est_time",
|
||||
str(self._gtk.formatTimeString(self.file_metadata['estimated_time'])))
|
||||
if "thumbnails" in self.file_metadata:
|
||||
tmp = self.file_metadata['thumbnails'].copy()
|
||||
@ -578,7 +613,7 @@ class JobStatusPanel(ScreenPanel):
|
||||
self.labels[label].set_text(text)
|
||||
|
||||
def update_progress(self):
|
||||
self.labels['progress_text'].set_text("%s%%" % (str(min(int(round(self.progress, 2)*100), 100))))
|
||||
self.labels['progress_text'].set_text("%s%%" % (str(min(int(self.progress*100), 100))))
|
||||
|
||||
def update_message(self):
|
||||
msg = self._printer.get_stat("display_status", "message")
|
||||
|
Loading…
x
Reference in New Issue
Block a user