Gate Start/Pause/Stop on whether a Sud is loaded and running

Start is enabled only once a schedule is loaded and idle; Pause/Stop
only while it's actually running (RAMPING/HOLDING/WAIT_USER). All
three stay disabled until something arrives on the Sud channel (which
only happens if a SudTask is actually configured server-side), and
get disabled again on disconnect since nothing reported over a dead
connection can still be trusted.

Also drops actionStop's leftover wiring to disconnect() - now that
Stop is meant to stop a running brew, it shouldn't tear down the
websocket connection instead.
This commit is contained in:
2026-06-20 23:19:01 +02:00
parent 127dd9da51
commit 2adcca6716
+24 -1
View File
@@ -16,6 +16,10 @@ from ws.message import MessageDispatcherSync
from queue import Queue
import asyncio
# str(SudState.X) values (as sent in the 'State' message) that count as
# "running" for enabling/disabling the Start/Pause/Stop toolbar actions.
SUD_RUNNING_STATES = {"SudState.RAMPING", "SudState.HOLDING", "SudState.WAIT_USER"}
def _style_axis(ax):
ax.set_facecolor('white')
@@ -164,6 +168,8 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
self.msg_dispatch.on_connect_changed = self.on_ws_connect_changed
self.ws_client = WsClient(listener=self.msg_dispatch, loop=loop)
self.connected = False
self.sud_loaded = False
self.sud_state = None
self.msg_pot = self.msg_dispatch.msgio_get('Pot')
self.msg_sensor = self.msg_dispatch.msgio_get('Sensor')
self.msg_heater = self.msg_dispatch.msgio_get('Heater')
@@ -179,8 +185,8 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
self.msg_sud.set_recv_handler(self.on_sud_changed)
self.setupUi(self)
self.update_sud_actions()
self.btn_connect.clicked.connect(self.on_btn_connect_clicked)
self.actionStop.triggered.connect(self.disconnect)
self.actionSudDownload.triggered.connect(self.on_action_sud_download)
self.actionSudUpload.triggered.connect(self.on_action_sud_upload)
self.Slider_pwr_soll.valueChanged.connect(self.on_slider_pwr_soll_changed)
@@ -263,6 +269,17 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
def on_ws_connect_changed(self, connected):
self.connected = connected
self.btn_connect.setText("Disconnect" if connected else "Connect")
if not connected:
# Nothing reported over a dead connection can be trusted anymore.
self.sud_loaded = False
self.sud_state = None
self.update_sud_actions()
def update_sud_actions(self):
running = self.sud_loaded and self.sud_state in SUD_RUNNING_STATES
self.actionStart.setEnabled(self.sud_loaded and not running)
self.actionPause.setEnabled(running)
self.actionStop.setEnabled(running)
def on_slider_temp_soll_changed(self, value):
print("on_slider_temp_soll_changed {}".format(value))
@@ -390,6 +407,9 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow):
def on_sud_changed(self, msg):
print("on_sud_changed {}".format(msg))
# Receiving anything at all on this channel means a Sud is loaded
# server-side - the schedule it's running may still be coming.
self.sud_loaded = True
for key in msg:
if "Json" in key:
if self.sud_download_path:
@@ -400,6 +420,9 @@ 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 "State" in key:
self.sud_state = msg['State']
self.update_sud_actions()
def update_sud_forecast(self, doc):
try: