From 19be2a76704a8b26e63f9bae37232aa92b587077 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 21 Jun 2026 12:15:35 +0200 Subject: [PATCH] Add a "Pot reset to ambient temperature" button, sim-only New btn_pot_reset next to the ambient entry, sends {"Pot": {"Reset": true}}; tasks/pot.py's PotTask.recv() (previously a no-op) now resets the plant to its current ambient temperature (Pot.initial()) on that command. The button only appears when the server reports its Pot is simulated (new "PlantSim" field on the System channel, derived from config.json's previously-unused Controller.plant_name) - resetting a simulated plant's temperature is meaningless for a real one. --- brewpi/brewpi.py | 3 ++- client/brewpi.ui | 16 ++++++++++++++++ client/brewpi_gui.py | 10 ++++++++++ client/main_window.py | 5 +++++ tasks/pot.py | 4 +++- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/brewpi/brewpi.py b/brewpi/brewpi.py index f4bc9a2..573a5e3 100755 --- a/brewpi/brewpi.py +++ b/brewpi/brewpi.py @@ -40,6 +40,7 @@ if __name__ == '__main__': DT_TASK = 1.0 / config['Controller']['sim_warp_factor'] DT_TASK_TRACER = DT_TASK / DT theta_amb = config['ambient_temperature'] + plant_sim = "sim" in config['Controller']['plant_name'] # Sensor sensor = TempSensorFactory.create(config['Controller']['sensor_name'], temp_offset=-0.15, variance=0.01) @@ -101,7 +102,7 @@ if __name__ == '__main__': msg_system = dispatcher.msgio_get("System") async def send_system_info(): - await msg_system.send({'AmbientTemp': theta_amb, 'WarpFactor': DT / DT_TASK}) + await msg_system.send({'AmbientTemp': theta_amb, 'WarpFactor': DT / DT_TASK, 'PlantSim': plant_sim}) asyncio.ensure_future(send_system_info()) async def on_system_recv(data): diff --git a/client/brewpi.ui b/client/brewpi.ui index 3f7e0b7..b1a149b 100644 --- a/client/brewpi.ui +++ b/client/brewpi.ui @@ -3711,6 +3711,22 @@ Set the simulated/assumed ambient temperature - press Enter to apply + + + + 700 + 500 + 220 + 31 + + + + Only available when the server's Pot is simulated + + + Pot reset to ambient temperature + + diff --git a/client/brewpi_gui.py b/client/brewpi_gui.py index 509593c..3ed563b 100755 --- a/client/brewpi_gui.py +++ b/client/brewpi_gui.py @@ -330,6 +330,10 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow): self.checkbox_heater_activate.stateChanged.connect(self.on_checkbox_changed) self.checkbox_stirrer_activate.stateChanged.connect(self.on_checkbox_stirrer_activate_changed) self.lineEdit_ambient.returnPressed.connect(self.on_ambient_entry_changed) + self.btn_pot_reset.clicked.connect(self.on_action_pot_reset) + # Only meaningful (and only shown) once the server confirms its Pot + # is simulated - see on_system_changed()'s "PlantSim" handling. + self.btn_pot_reset.setVisible(False) self.send_data = Queue() self.slider_pwr_initial_update = True @@ -462,6 +466,7 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow): self.sud_user_message = None self.ambient_temp = None self.lineEdit_ambient.clear() + self.btn_pot_reset.setVisible(False) self.warp_factor = 1.0 self.sud_start_time = None self.sud_paused_total = 0.0 @@ -500,8 +505,13 @@ class Window(QtWidgets.QMainWindow, Ui_MainWindow): self.lineEdit_ambient.setText("{:.1f}".format(self.ambient_temp)) elif "WarpFactor" in key: self.warp_factor = msg['WarpFactor'] + elif "PlantSim" in key: + self.btn_pot_reset.setVisible(msg['PlantSim']) self.update_status_env_label() + def on_action_pot_reset(self): + self.msg_pot.send({'Reset': True}) + def on_ambient_entry_changed(self): try: value = float(self.lineEdit_ambient.text()) diff --git a/client/main_window.py b/client/main_window.py index d0d1661..b024dc2 100644 --- a/client/main_window.py +++ b/client/main_window.py @@ -1237,6 +1237,9 @@ class Ui_MainWindow(object): self.lineEdit_ambient = QtWidgets.QLineEdit(self.centralwidget) self.lineEdit_ambient.setGeometry(QtCore.QRect(620, 500, 70, 31)) self.lineEdit_ambient.setObjectName("lineEdit_ambient") + self.btn_pot_reset = QtWidgets.QPushButton(self.centralwidget) + self.btn_pot_reset.setGeometry(QtCore.QRect(700, 500, 220, 31)) + self.btn_pot_reset.setObjectName("btn_pot_reset") self.label_8 = QtWidgets.QLabel(self.centralwidget) self.label_8.setGeometry(QtCore.QRect(200, 500, 67, 31)) self.label_8.setAlignment(QtCore.Qt.AlignCenter) @@ -1307,6 +1310,8 @@ class Ui_MainWindow(object): self.btn_connect.setText(_translate("MainWindow", "Connect")) self.label_ambient.setText(_translate("MainWindow", "Ambient [°C]")) self.lineEdit_ambient.setToolTip(_translate("MainWindow", "Set the simulated/assumed ambient temperature - press Enter to apply")) + self.btn_pot_reset.setToolTip(_translate("MainWindow", "Only available when the server\'s Pot is simulated")) + self.btn_pot_reset.setText(_translate("MainWindow", "Pot reset to ambient temperature")) self.label_8.setText(_translate("MainWindow", "Host")) self.menu_File.setTitle(_translate("MainWindow", "&File")) self.menu_Help.setTitle(_translate("MainWindow", "&Help")) diff --git a/tasks/pot.py b/tasks/pot.py index f0c1178..ac4b6d1 100644 --- a/tasks/pot.py +++ b/tasks/pot.py @@ -20,7 +20,9 @@ class PotTask(ATask): asyncio.create_task(self.send({'Temp': value})) async def recv(self, data): - pass + for pair in data.items(): + if 'Reset' in pair[0]: + self.plant.initial(self.plant.theta_amb) async def send(self, data): await self.msg_handler.send(data)