forked from M-Labs/thermostat
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:
parent
fcda46d1f3
commit
b32b38d830
pytec
@ -1,9 +1,11 @@
|
|||||||
from PyQt6.QtCore import QObject, pyqtSlot
|
from PyQt6.QtCore import QObject, pyqtSlot, pyqtSignal
|
||||||
from qasync import asyncSlot
|
from qasync import asyncSlot
|
||||||
from autotune import PIDAutotuneState, PIDAutotune
|
from autotune import PIDAutotuneState, PIDAutotune
|
||||||
|
|
||||||
|
|
||||||
class PIDAutoTuner(QObject):
|
class PIDAutoTuner(QObject):
|
||||||
|
autotune_state_changed = pyqtSignal(int, PIDAutotuneState)
|
||||||
|
|
||||||
def __init__(self, parent, thermostat, num_of_channel):
|
def __init__(self, parent, thermostat, num_of_channel):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
@ -37,9 +39,11 @@ class PIDAutoTuner(QObject):
|
|||||||
self.lookback[ch],
|
self.lookback[ch],
|
||||||
)
|
)
|
||||||
self.autotuners[ch].setReady()
|
self.autotuners[ch].setReady()
|
||||||
|
self.autotune_state_changed.emit(ch, self.autotuners[ch].state())
|
||||||
|
|
||||||
async def stop_pid_from_running(self, ch):
|
async def stop_pid_from_running(self, ch):
|
||||||
self.autotuners[ch].setOff()
|
self.autotuners[ch].setOff()
|
||||||
|
self.autotune_state_changed.emit(ch, self.autotuners[ch].state())
|
||||||
await self._thermostat.set_param("pwm", ch, "i_set", 0)
|
await self._thermostat.set_param("pwm", ch, "i_set", 0)
|
||||||
|
|
||||||
@asyncSlot(list)
|
@asyncSlot(list)
|
||||||
@ -65,6 +69,7 @@ class PIDAutoTuner(QObject):
|
|||||||
case PIDAutotuneState.STATE_SUCCEEDED:
|
case PIDAutotuneState.STATE_SUCCEEDED:
|
||||||
kp, ki, kd = self.autotuners[ch].get_tec_pid()
|
kp, ki, kd = self.autotuners[ch].get_tec_pid()
|
||||||
self.autotuners[ch].setOff()
|
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, "kp", kp)
|
||||||
await self._thermostat.set_param("pid", ch, "ki", ki)
|
await self._thermostat.set_param("pid", ch, "ki", ki)
|
||||||
@ -76,4 +81,5 @@ class PIDAutoTuner(QObject):
|
|||||||
)
|
)
|
||||||
case PIDAutotuneState.STATE_FAILED:
|
case PIDAutotuneState.STATE_FAILED:
|
||||||
self.autotuners[ch].setOff()
|
self.autotuners[ch].setOff()
|
||||||
|
self.autotune_state_changed.emit(ch, self.autotuners[ch].state())
|
||||||
await self._thermostat.set_param("pwm", ch, "i_set", 0)
|
await self._thermostat.set_param("pwm", ch, "i_set", 0)
|
||||||
|
@ -6,7 +6,7 @@ from pyqtgraph.parametertree import (
|
|||||||
registerParameterType,
|
registerParameterType,
|
||||||
)
|
)
|
||||||
from qasync import asyncSlot
|
from qasync import asyncSlot
|
||||||
from functools import partial
|
from autotune import PIDAutotuneState
|
||||||
|
|
||||||
|
|
||||||
class MutexParameter(pTypes.ListParameter):
|
class MutexParameter(pTypes.ListParameter):
|
||||||
@ -55,7 +55,6 @@ class CtrlPanel(QObject):
|
|||||||
info_box,
|
info_box,
|
||||||
trees_ui,
|
trees_ui,
|
||||||
param_tree,
|
param_tree,
|
||||||
sigActivated_handles,
|
|
||||||
parent=None,
|
parent=None,
|
||||||
):
|
):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
@ -93,8 +92,9 @@ class CtrlPanel(QObject):
|
|||||||
self.params[i].child("Load from flash").sigActivated.connect(
|
self.params[i].child("Load from flash").sigActivated.connect(
|
||||||
partial(self.load_settings, i)
|
partial(self.load_settings, i)
|
||||||
)
|
)
|
||||||
for handle in sigActivated_handles[i]:
|
self.params[i].child(
|
||||||
self.params[i].child(*handle[0]).sigActivated.connect(handle[1])
|
"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.pid_update.connect(self.update_pid)
|
||||||
self.thermostat.report_update.connect(self.update_report)
|
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"
|
f"Channel {ch} settings has been saved to flash.\n"
|
||||||
"It will be loaded on Thermostat reset, or when settings are explicitly loaded.",
|
"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)
|
||||||
|
|
||||||
|
@ -76,28 +76,18 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
self.thermostat.connection_state_changed.connect(self._on_connection_changed)
|
self.thermostat.connection_state_changed.connect(self._on_connection_changed)
|
||||||
|
|
||||||
self.autotuners = PIDAutoTuner(self, self.thermostat, 2)
|
self.autotuners = PIDAutoTuner(self, self.thermostat, 2)
|
||||||
|
self.autotuners.autotune_state_changed.connect(self.pid_autotune_handler)
|
||||||
|
|
||||||
def get_ctrl_panel_config(args):
|
def get_ctrl_panel_config(args):
|
||||||
with open(args.param_tree, "r", encoding="utf-8") as f:
|
with open(args.param_tree, "r", encoding="utf-8") as f:
|
||||||
return json.load(f)["ctrl_panel"]
|
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.ctrl_panel_view = CtrlPanel(
|
||||||
self.thermostat,
|
self.thermostat,
|
||||||
self.autotuners,
|
self.autotuners,
|
||||||
self.info_box,
|
self.info_box,
|
||||||
[self.ch0_tree, self.ch1_tree],
|
[self.ch0_tree, self.ch1_tree],
|
||||||
get_ctrl_panel_config(args),
|
get_ctrl_panel_config(args),
|
||||||
param_tree_sigActivated_handles,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.zero_limits_warning = ZeroLimitsWarningView(
|
self.zero_limits_warning = ZeroLimitsWarningView(
|
||||||
@ -107,8 +97,6 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
self.zero_limits_warning.set_limits_warning
|
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.thermostat.hw_rev_update.connect(self._status)
|
||||||
self.report_apply_btn.clicked.connect(
|
self.report_apply_btn.clicked.connect(
|
||||||
lambda: self.thermostat.set_update_s(self.report_refresh_spin.value())
|
lambda: self.thermostat.set_update_s(self.report_refresh_spin.value())
|
||||||
@ -218,23 +206,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||||||
else:
|
else:
|
||||||
await self.thermostat.end_session()
|
await self.thermostat.end_session()
|
||||||
|
|
||||||
@asyncSlot()
|
@asyncSlot(int, PIDAutotuneState)
|
||||||
async def pid_auto_tune_request(self, ch=0):
|
async def pid_autotune_handler(self, _ch, _state):
|
||||||
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, _):
|
|
||||||
ch_tuning = []
|
ch_tuning = []
|
||||||
for ch in range(self.NUM_CHANNELS):
|
for ch in range(self.NUM_CHANNELS):
|
||||||
match self.autotuners.get_state(ch):
|
match self.autotuners.get_state(ch):
|
||||||
|
Loading…
Reference in New Issue
Block a user