Force the heater off and show a "Cool down" indicator during a passive cooldown

A ramp step whose target is below the current actual temperature can
only be reached by ambient cooling - the heater can't actively cool.
SudTask now detects this once per ramp phase and calls the controller's
new set_cooling() override (forces y=0, bypassing the FSM) instead of
waiting for its hysteresis-based IDLE transition. The GUI shows a
blinking blue "Cool down" label in the status bar while this is active.
Progression already only advances once theta_ist matches theta_soll
regardless of direction, so no change was needed there.
This commit is contained in:
2026-06-21 09:10:13 +02:00
parent 9bd9889cb0
commit 1170718c3b
4 changed files with 56 additions and 1 deletions
+28
View File
@@ -227,6 +227,18 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
self.status_label_env = QtWidgets.QLabel()
self.statusBar().addPermanentWidget(self.status_label_env)
self.update_status_env_label()
# Blinking indicator for a Sud ramp step that's cooling down
# (target below the current temperature - the heater is forced off
# server-side and we just wait for ambient loss to catch up).
self.sud_cooling = False
self.status_label_cooling = QtWidgets.QLabel("Cool down")
self.status_label_cooling.setStyleSheet("color: blue; font-weight: bold;")
self.status_label_cooling.setVisible(False)
self.statusBar().addPermanentWidget(self.status_label_cooling)
self.cooling_blink_timer = QtCore.QTimer(self)
self.cooling_blink_timer.timeout.connect(self.on_cooling_blink)
self.update_sud_actions()
self.btn_connect.clicked.connect(self.on_btn_connect_clicked)
self.actionStart.triggered.connect(self.on_action_sud_start)
@@ -336,6 +348,7 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
self.sud_start_time = None
self.sud_paused_total = 0.0
self.sud_pause_started_at = None
self.set_sud_cooling(False)
self.update_sud_actions()
self.update_status_env_label()
@@ -361,6 +374,20 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
ambient = "{:.1f}°C".format(self.ambient_temp) if self.ambient_temp is not None else "-"
self.status_label_env.setText("Ambient: {} Warp: {:.1f}x".format(ambient, self.warp_factor))
def set_sud_cooling(self, cooling):
if cooling == self.sud_cooling:
return
self.sud_cooling = cooling
if cooling:
self.status_label_cooling.setVisible(True)
self.cooling_blink_timer.start(500)
else:
self.cooling_blink_timer.stop()
self.status_label_cooling.setVisible(False)
def on_cooling_blink(self):
self.status_label_cooling.setVisible(not self.status_label_cooling.isVisible())
def on_slider_temp_soll_changed(self, value):
print("on_slider_temp_soll_changed {}".format(value))
self.msg_tempctrl.send({'Soll': {'Temp': value}})
@@ -544,6 +571,7 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
self.statusBar().showMessage("Step {}: {}".format(step.get('Index'), descr))
else:
self.statusBar().clearMessage()
self.set_sud_cooling(step.get('Cooling', False))
self.update_sud_actions()
def update_sud_forecast(self, doc):