diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e9a3a71..550d0998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ - Fixed: Fix incorrect "No Pendant" in UI when pendant is working - Fixed: Fix invalid initial coordinates when resuming in the middle of a modal command - Fixed: 3D Visualisation of GCode movement would always show the initial movement as originating from the WCS Origin, this doesn't match reality. Now the Visualisation correctly shows the line as originating from above the first movement command at the configured clearance_z (default of MCS Z-3) +- Fixed: Elapsed and remaining job timers now pause while playback is paused - Change: Remove remaining "Can not load config, Key:" messages from the MDI - Change: Resume playback will now use gcode loaded in the controller instead of cached local file diff --git a/carveracontroller/main.py b/carveracontroller/main.py index 3b35b8b9..12b7f704 100644 --- a/carveracontroller/main.py +++ b/carveracontroller/main.py @@ -5442,6 +5442,11 @@ def _on_time_estimate_progress(self, state, percent): self.progressFinish() # --------------------------------------------------------------`--------- + _PROGRESS_TIMER_PAUSED_STATES = frozenset({"Hold", "Pause", "Wait", "Tool"}) + + def _current_remaining_sec(self): + return max(0.0, self._remaining_anchor_sec - (time.time() - self._remaining_anchor_time)) + def _update_progress_smooth(self, dt): """Refresh elapsed/remaining display every second while playing.""" app = App.get_running_app() @@ -5449,18 +5454,13 @@ def _update_progress_smooth(self, dt): not app.playing or (not app.selected_remote_filename and not app.selected_local_filename) or not self.selected_file_line_count + or app.state in self._PROGRESS_TIMER_PAUSED_STATES ): + # While held/paused, leave the last progress_info unchanged so both timers freeze. return - remaining_display = max(0.0, self._remaining_anchor_sec - (time.time() - self._remaining_anchor_time)) + remaining_display = self._current_remaining_sec() filename = os.path.basename(app.selected_remote_filename or app.selected_local_filename) - self.progress_info = " {} ( {}/{} - {}%, {} elapsed, {} to go )".format( - filename, - self.played_lines, - self.selected_file_line_count, - int(self.wpb_play.value), - Utils.second2hour(CNC.vars["playedseconds"]), - Utils.second2hour(int(remaining_display)), - ) + self.progress_info = f" {filename} ( {self.played_lines}/{self.selected_file_line_count} - {int(self.wpb_play.value)}%, {Utils.second2hour(CNC.vars['playedseconds'])} elapsed, {Utils.second2hour(int(remaining_display))} to go )" # --------------------------------------------------------------`--------- def updateCompressProgress(self, value): @@ -5490,6 +5490,7 @@ def updateStatus(self, *args): return if app.state != CNC.vars["state"]: + prev_state = app.state app.state = CNC.vars["state"] CNC.vars["color"] = STATECOLOR[app.state] self.status_data_view.color = CNC.vars["color"] @@ -5497,6 +5498,15 @@ def updateStatus(self, *args): self.pausing = 1 if app.state == "Pause" else 0 self.waiting = 1 if app.state == "Wait" else 0 self.tooling = 1 if app.state == "Tool" else 0 + if app.playing: + was_paused = prev_state in self._PROGRESS_TIMER_PAUSED_STATES + now_paused = app.state in self._PROGRESS_TIMER_PAUSED_STATES + if now_paused and not was_paused: + # Park remaining so pause duration is not subtracted on resume. + self._remaining_anchor_sec = self._current_remaining_sec() + self._remaining_anchor_time = now + elif was_paused and not now_paused: + self._remaining_anchor_time = now # update status self.status_data_view.main_text = app.state if app.state == NOT_CONNECTED: