1
0
forked from M-Labs/thermostat

Exclusively use the Thermostat object as a medium

All calls to the Thermostat should be forwarded by the medium.
This commit is contained in:
atse 2024-07-08 11:55:09 +08:00
parent 80975f50b1
commit 058e597ef0
3 changed files with 40 additions and 32 deletions

View File

@ -4,10 +4,10 @@ from autotune import PIDAutotuneState, PIDAutotune
class PIDAutoTuner(QObject):
def __init__(self, parent, client, num_of_channel):
def __init__(self, parent, thermostat, num_of_channel):
super().__init__(parent)
self._client = client
self._thermostat = thermostat
self.autotuners = [PIDAutotune(25) for _ in range(num_of_channel)]
self.target_temp = [20.0 for _ in range(num_of_channel)]
self.test_current = [1.0 for _ in range(num_of_channel)]
@ -37,7 +37,7 @@ class PIDAutoTuner(QObject):
async def stop_pid_from_running(self, ch):
self.autotuners[ch].setOff()
await self._client.set_param("pwm", ch, "i_set", 0)
await self._thermostat.set_param("pwm", ch, "i_set", 0)
@asyncSlot(list)
async def tick(self, report):
@ -56,21 +56,21 @@ class PIDAutoTuner(QObject):
self.autotuners[ch].run(
channel_report["temperature"], channel_report["time"]
)
await self._client.set_param(
await self._thermostat.set_param(
"pwm", ch, "i_set", self.autotuners[ch].output()
)
case PIDAutotuneState.STATE_SUCCEEDED:
kp, ki, kd = self.autotuners[ch].get_tec_pid()
self.autotuners[ch].setOff()
await self._client.set_param("pid", ch, "kp", kp)
await self._client.set_param("pid", ch, "ki", ki)
await self._client.set_param("pid", ch, "kd", kd)
await self._client.set_param("pwm", ch, "pid")
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, "kd", kd)
await self._thermostat.set_param("pwm", ch, "pid")
await self._client.set_param(
await self._thermostat.set_param(
"pid", ch, "target", self.target_temp[ch]
)
case PIDAutotuneState.STATE_FAILED:
self.autotuners[ch].setOff()
await self._client.set_param("pwm", ch, "i_set", 0)
await self._thermostat.set_param("pwm", ch, "i_set", 0)

View File

@ -3,6 +3,7 @@ from qasync import asyncSlot
from pytec.gui.model.property import Property, PropertyMeta
import asyncio
import logging
from pytec.aioclient import Client
class Thermostat(QObject, metaclass=PropertyMeta):
@ -17,9 +18,9 @@ class Thermostat(QObject, metaclass=PropertyMeta):
info_box_trigger = pyqtSignal(str, str)
connection_error = pyqtSignal()
def __init__(self, parent, client, update_s):
def __init__(self, parent, update_s):
self._update_s = update_s
self._client = client
self._client = Client()
self._watch_task = None
self._report_mode_task = None
self._poll_for_report = True
@ -27,6 +28,9 @@ class Thermostat(QObject, metaclass=PropertyMeta):
self.connection_errored = False
super().__init__(parent)
async def start_session(self, host, port):
await self._client.start_session(host, port, timeout=5)
async def run(self):
self._update_params_task = asyncio.create_task(self.update_params())
while True:
@ -128,3 +132,12 @@ class Thermostat(QObject, metaclass=PropertyMeta):
@pyqtSlot(float)
def set_update_s(self, update_s):
self._update_s = update_s
async def set_fan(self, power="auto"):
await self._client.set_fan(power)
async def get_fan(self):
return await self._client.get_fan()
async def set_param(self, topic, channel, field="", value=""):
await self._client.set_param(topic, channel, field, value)

View File

@ -8,7 +8,6 @@ from pytec.gui.view.ctrl_panel import CtrlPanel
from pytec.gui.view.info_box import InfoBox
from pytec.gui.model.pid_autotuner import PIDAutoTuner
from pytec.gui.model.thermostat import Thermostat
from pytec.aioclient import Client
import json
from autotune import PIDAutotuneState
from qasync import asyncSlot, asyncClose
@ -64,11 +63,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.hw_rev_data = None
self.info_box = InfoBox()
self.client = Client()
self.thermostat = Thermostat(
self, self.client, self.report_refresh_spin.value()
)
self.thermostat = Thermostat(self, self.report_refresh_spin.value())
def handle_connection_error():
self.info_box.display_info_box(
@ -79,10 +74,10 @@ class MainWindow(QtWidgets.QMainWindow):
self.thermostat.connection_error.connect(handle_connection_error)
self.client.connection_error.connect(self.thermostat.timed_out)
self.client.connection_error.connect(self.bail)
self.thermostat.connection_error.connect(self.thermostat.timed_out)
self.thermostat.connection_error.connect(self.bail)
self.autotuners = PIDAutoTuner(self, self.client, 2)
self.autotuners = PIDAutoTuner(self, self.thermostat, 2)
def get_ctrl_panel_config(args):
with open(args.param_tree, "r", encoding="utf-8") as f:
@ -242,14 +237,14 @@ class MainWindow(QtWidgets.QMainWindow):
self.conn_menu.port_set_spin.value(),
)
try:
if not (self.client.connecting() or self.client.connected()):
if not (self.thermostat.connecting() or self.thermostat.connected()):
self.status_lbl.setText("Connecting...")
self.connect_btn.setText("Stop")
self.conn_menu.host_set_line.setEnabled(False)
self.conn_menu.port_set_spin.setEnabled(False)
try:
await self.client.start_session(host=host, port=port, timeout=5)
await self.thermostat.start_session(host=host, port=port)
except StoppedConnecting:
return
await self._on_connection_changed(True)
@ -266,7 +261,7 @@ class MainWindow(QtWidgets.QMainWindow):
@asyncSlot()
async def bail(self):
await self._on_connection_changed(False)
await self.client.end_session()
await self.thermostat.end_session()
@asyncSlot(object, object)
async def send_command(self, param, changes):
@ -288,7 +283,7 @@ class MainWindow(QtWidgets.QMainWindow):
else:
set_param_args = (*thermostat_param, data)
param.child(*param.childPath(inner_param)).setOpts(lock=True)
await self.client.set_param(*set_param_args)
await self.thermostat.set_param(*set_param_args)
param.child(*param.childPath(inner_param)).setOpts(lock=False)
if inner_param.opts.get("pid_autotune", None) is not None:
@ -304,7 +299,7 @@ class MainWindow(QtWidgets.QMainWindow):
if activater is not None:
if activater[1] == "ch":
activater[1] = ch
await self.client.set_param(*activater)
await self.thermostat.set_param(*activater)
@asyncSlot()
async def pid_auto_tune_request(self, ch=0):
@ -367,24 +362,24 @@ class MainWindow(QtWidgets.QMainWindow):
@asyncSlot(int)
async def fan_set_request(self, value):
assert self.client.connected()
assert self.thermostat.connected()
if self.thermostat_ctrl_menu.fan_auto_box.isChecked():
with QSignalBlocker(self.thermostat_ctrl_menu.fan_auto_box):
self.thermostat_ctrl_menu.fan_auto_box.setChecked(False)
await self.client.set_fan(value)
await self.thermostat.set_fan(value)
if not self.hw_rev_data["settings"]["fan_pwm_recommended"]:
self.thermostat_ctrl_menu.set_fan_pwm_warning()
@asyncSlot(int)
async def fan_auto_set_request(self, enabled):
assert self.client.connected()
assert self.thermostat.connected()
if enabled:
await self.client.set_fan("auto")
self.fan_update(await self.client.get_fan())
await self.thermostat.set_fan("auto")
self.fan_update(await self.thermostat.get_fan())
else:
await self.client.set_fan(
await self.thermostat.set_fan(
self.thermostat_ctrl_menu.fan_power_slider.value()
)