Move pid autotuning request to CtrlPanel

And update autotune UI only on state change instead of every single
report update
This commit is contained in:
atse 2024-08-27 16:46:48 +08:00
parent 4407e5c97a
commit 3aeef04330
3 changed files with 27 additions and 34 deletions

View File

@ -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)

View File

@ -6,6 +6,7 @@ from pyqtgraph.parametertree import (
registerParameterType,
)
from qasync import asyncSlot
from autotune import PIDAutotuneState
import pytec.gui.view.lockable_unit
@ -26,7 +27,6 @@ class CtrlPanel(QObject):
info_box,
trees_ui,
param_tree,
sigActivated_handles,
parent=None,
):
super().__init__(parent)
@ -67,8 +67,9 @@ class CtrlPanel(QObject):
param.child("load").sigActivated.connect(
partial(self.load_settings, ch)
)
for handle in sigActivated_handles[ch]:
param.child(*handle[0]).sigActivated.connect(handle[1])
param.child("pid", "pid_autotune", "run_pid").sigActivated.connect(
partial(self.pid_auto_tune_request, ch)
)
def _indicate_usage(param, control_method="constant_current"):
for item in param.child("i_set").items:
@ -247,3 +248,16 @@ 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)

View File

@ -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", "pid_autotune", "run_pid"],
partial(self.pid_autotune_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_autotune_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):