From b32b38d83007a79f15b2a3be11a09eebe89e967a Mon Sep 17 00:00:00 2001 From: atse Date: Tue, 27 Aug 2024 16:46:48 +0800 Subject: [PATCH] Move pid autotuning request to CtrlPanel And update autotune UI only on state change instead of every single report update --- pytec/pytec/gui/model/pid_autotuner.py | 8 ++++++- pytec/pytec/gui/view/ctrl_panel.py | 22 +++++++++++++---- pytec/tec_qt.py | 33 +++----------------------- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/pytec/pytec/gui/model/pid_autotuner.py b/pytec/pytec/gui/model/pid_autotuner.py index 16ccb88..22837cd 100644 --- a/pytec/pytec/gui/model/pid_autotuner.py +++ b/pytec/pytec/gui/model/pid_autotuner.py @@ -1,9 +1,11 @@ -from PyQt6.QtCore import QObject, pyqtSlot +from PyQt6.QtCore import QObject, pyqtSlot, pyqtSignal from qasync import asyncSlot from autotune import PIDAutotuneState, PIDAutotune class PIDAutoTuner(QObject): + autotune_state_changed = pyqtSignal(int, PIDAutotuneState) + def __init__(self, parent, thermostat, num_of_channel): super().__init__(parent) @@ -37,9 +39,11 @@ class PIDAutoTuner(QObject): self.lookback[ch], ) self.autotuners[ch].setReady() + self.autotune_state_changed.emit(ch, self.autotuners[ch].state()) async def stop_pid_from_running(self, ch): self.autotuners[ch].setOff() + self.autotune_state_changed.emit(ch, self.autotuners[ch].state()) await self._thermostat.set_param("pwm", ch, "i_set", 0) @asyncSlot(list) @@ -65,6 +69,7 @@ class PIDAutoTuner(QObject): case PIDAutotuneState.STATE_SUCCEEDED: kp, ki, kd = self.autotuners[ch].get_tec_pid() self.autotuners[ch].setOff() + self.autotune_state_changed.emit(ch, self.autotuners[ch].state()) await self._thermostat.set_param("pid", ch, "kp", kp) await self._thermostat.set_param("pid", ch, "ki", ki) @@ -76,4 +81,5 @@ class PIDAutoTuner(QObject): ) case PIDAutotuneState.STATE_FAILED: self.autotuners[ch].setOff() + self.autotune_state_changed.emit(ch, self.autotuners[ch].state()) await self._thermostat.set_param("pwm", ch, "i_set", 0) diff --git a/pytec/pytec/gui/view/ctrl_panel.py b/pytec/pytec/gui/view/ctrl_panel.py index c8ce16d..153cbd4 100644 --- a/pytec/pytec/gui/view/ctrl_panel.py +++ b/pytec/pytec/gui/view/ctrl_panel.py @@ -6,7 +6,7 @@ from pyqtgraph.parametertree import ( registerParameterType, ) from qasync import asyncSlot -from functools import partial +from autotune import PIDAutotuneState class MutexParameter(pTypes.ListParameter): @@ -55,7 +55,6 @@ class CtrlPanel(QObject): info_box, trees_ui, param_tree, - sigActivated_handles, parent=None, ): super().__init__(parent) @@ -93,8 +92,9 @@ class CtrlPanel(QObject): self.params[i].child("Load from flash").sigActivated.connect( partial(self.load_settings, i) ) - for handle in sigActivated_handles[i]: - self.params[i].child(*handle[0]).sigActivated.connect(handle[1]) + self.params[i].child( + "PID Config", "PID Auto Tune", "Run" + ).sigActivated.connect(partial(self.pid_auto_tune_request, i)) self.thermostat.pid_update.connect(self.update_pid) self.thermostat.report_update.connect(self.update_report) @@ -277,3 +277,17 @@ class CtrlPanel(QObject): f"Channel {ch} settings has been saved to flash.\n" "It will be loaded on Thermostat reset, or when settings are explicitly loaded.", ) + + @asyncSlot() + async def pid_auto_tune_request(self, ch=0): + match self.autotuners.get_state(ch): + case PIDAutotuneState.STATE_OFF | PIDAutotuneState.STATE_FAILED: + self.autotuners.load_params_and_set_ready(ch) + + case ( + PIDAutotuneState.STATE_READY + | PIDAutotuneState.STATE_RELAY_STEP_UP + | PIDAutotuneState.STATE_RELAY_STEP_DOWN + ): + await self.autotuners.stop_pid_from_running(ch) + diff --git a/pytec/tec_qt.py b/pytec/tec_qt.py index 389f027..07fc43e 100755 --- a/pytec/tec_qt.py +++ b/pytec/tec_qt.py @@ -76,28 +76,18 @@ class MainWindow(QtWidgets.QMainWindow): self.thermostat.connection_state_changed.connect(self._on_connection_changed) self.autotuners = PIDAutoTuner(self, self.thermostat, 2) + self.autotuners.autotune_state_changed.connect(self.pid_autotune_handler) def get_ctrl_panel_config(args): with open(args.param_tree, "r", encoding="utf-8") as f: return json.load(f)["ctrl_panel"] - param_tree_sigActivated_handles = [ - [ - [ - ["PID Config", "PID Auto Tune", "Run"], - partial(self.pid_auto_tune_request, ch), - ], - ] - for ch in range(self.NUM_CHANNELS) - ] - self.ctrl_panel_view = CtrlPanel( self.thermostat, self.autotuners, self.info_box, [self.ch0_tree, self.ch1_tree], get_ctrl_panel_config(args), - param_tree_sigActivated_handles, ) self.zero_limits_warning = ZeroLimitsWarningView( @@ -107,8 +97,6 @@ class MainWindow(QtWidgets.QMainWindow): self.zero_limits_warning.set_limits_warning ) - self.thermostat.report_update.connect(self.pid_autotune_handler) - self.thermostat.hw_rev_update.connect(self._status) self.report_apply_btn.clicked.connect( lambda: self.thermostat.set_update_s(self.report_refresh_spin.value()) @@ -218,23 +206,8 @@ class MainWindow(QtWidgets.QMainWindow): else: await self.thermostat.end_session() - @asyncSlot() - async def pid_auto_tune_request(self, ch=0): - match self.autotuners.get_state(ch): - case PIDAutotuneState.STATE_OFF | PIDAutotuneState.STATE_FAILED: - self.autotuners.load_params_and_set_ready(ch) - - case ( - PIDAutotuneState.STATE_READY - | PIDAutotuneState.STATE_RELAY_STEP_UP - | PIDAutotuneState.STATE_RELAY_STEP_DOWN - ): - await self.autotuners.stop_pid_from_running(ch) - # To Update the UI elements - self.pid_autotune_handler([]) - - @asyncSlot(list) - async def pid_autotune_handler(self, _): + @asyncSlot(int, PIDAutotuneState) + async def pid_autotune_handler(self, _ch, _state): ch_tuning = [] for ch in range(self.NUM_CHANNELS): match self.autotuners.get_state(ch):