Scale the Sud forecast progress by the server's actual warp factor

SudTask now computes warp_factor = dt/interval (the same simulated-vs-
wall-clock split Pot/TempController/Stirrer already use internally)
and sends it once at startup as 'WarpFactor'. The GUI uses it to scale
real elapsed time into the forecast's simulated-schedule time axis,
so the progress line lines up with the actual sim speed instead of
assuming real time.

Also fixes SudTask.tick() to decrement hold_remaining by dt (simulated
seconds) instead of interval (wall-clock seconds) - it was the only
place in the sim using the wall-clock interval for something meant to
track simulated time, so hold steps were taking warp_factor times
longer in real time than their declared duration intends. Without
this fix the GUI's new warp-scaled progress line would race ahead of
the real server during holds.
This commit is contained in:
2026-06-21 00:27:14 +02:00
parent e1d0deb8d2
commit 189d1e24d2
3 changed files with 27 additions and 5 deletions
+11 -1
View File
@@ -190,6 +190,10 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
self.sud_loaded = False
self.sud_state = None
self.sud_user_message = None
# Simulated-seconds-per-real-second, from SudTask's 'WarpFactor'
# message; defaults to 1.0 (no scaling) until that arrives, or for
# a server that doesn't send it at all.
self.sud_warp_factor = 1.0
# time.monotonic() of the last IDLE/DONE -> running transition, used
# to position the forecast plot's progress line; None while not
# running. sud_paused_total accumulates time spent PAUSED so the
@@ -287,7 +291,10 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
# While paused, use the moment the pause began as "now" so the
# line freezes instead of drifting ahead of actual progress.
now = self.sud_pause_started_at if self.sud_pause_started_at is not None else time.monotonic()
elapsed_min = (now - self.sud_start_time - self.sud_paused_total) / 60.0
elapsed_real_s = now - self.sud_start_time - self.sud_paused_total
# The forecast's x-axis is simulated-schedule time; scale real
# elapsed time by the server's warp factor to match it.
elapsed_min = elapsed_real_s * self.sud_warp_factor / 60.0
self.forecast_plot.set_progress(elapsed_min)
else:
self.forecast_plot.clear_progress()
@@ -314,6 +321,7 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
self.sud_loaded = False
self.sud_state = None
self.sud_user_message = None
self.sud_warp_factor = 1.0
self.sud_start_time = None
self.sud_paused_total = 0.0
self.sud_pause_started_at = None
@@ -483,6 +491,8 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
self.update_sud_forecast(msg['Json'])
elif "Name" in key:
self.statusBar().showMessage("Sud schedule updated: {}".format(msg['Name']), 5000)
elif "WarpFactor" in key:
self.sud_warp_factor = msg['WarpFactor']
elif "State" in key:
prev_state = self.sud_state
self.sud_state = msg['State']