Compare commits

..

3 Commits

Author SHA1 Message Date
05ecb22741 Stuff non-UI changes in Thermostat model 2024-08-23 12:11:58 +08:00
b9a1c04159 State dependend UI 2024-08-23 11:56:02 +08:00
9e269ed161 State 2024-08-23 11:54:55 +08:00
2 changed files with 57 additions and 46 deletions

View File

@ -8,9 +8,9 @@ from pytec.aioclient import AsyncioClient
class ThermostatConnectionState(Enum): class ThermostatConnectionState(Enum):
STATE_DISCONNECTED = "disconnected" DISCONNECTED = False
STATE_CONNECTING = "connecting" CONNECTING = "connecting"
STATE_CONNECTED = "connected" CONNECTED = True
class Thermostat(QObject, metaclass=PropertyMeta): class Thermostat(QObject, metaclass=PropertyMeta):
@ -37,6 +37,7 @@ class Thermostat(QObject, metaclass=PropertyMeta):
async def start_session(self, host, port): async def start_session(self, host, port):
await self._client.connect(host, port) await self._client.connect(host, port)
self.start_watching()
async def run(self): async def run(self):
self.task = asyncio.create_task(self.update_params()) self.task = asyncio.create_task(self.update_params())
@ -104,6 +105,8 @@ class Thermostat(QObject, metaclass=PropertyMeta):
] ]
async def end_session(self): async def end_session(self):
await self.set_report_mode(False)
self.stop_watching()
await self._client.disconnect() await self._client.disconnect()
self.connection_errored = False self.connection_errored = False

View File

@ -7,7 +7,7 @@ from pytec.gui.view.live_plot_view import LiveDataPlotter
from pytec.gui.view.ctrl_panel import CtrlPanel from pytec.gui.view.ctrl_panel import CtrlPanel
from pytec.gui.view.info_box import InfoBox from pytec.gui.view.info_box import InfoBox
from pytec.gui.model.pid_autotuner import PIDAutoTuner from pytec.gui.model.pid_autotuner import PIDAutoTuner
from pytec.gui.model.thermostat import Thermostat from pytec.gui.model.thermostat import Thermostat, ThermostatConnectionState
import json import json
from autotune import PIDAutotuneState from autotune import PIDAutotuneState
from qasync import asyncSlot, asyncClose from qasync import asyncSlot, asyncClose
@ -176,37 +176,51 @@ class MainWindow(QtWidgets.QMainWindow):
self.channel_graphs.clear_graphs() self.channel_graphs.clear_graphs()
async def _on_connection_changed(self, result): async def _on_connection_changed(self, result):
self.graph_group.setEnabled(result) match result:
self.report_group.setEnabled(result) case ThermostatConnectionState.CONNECTED:
self.thermostat_settings.setEnabled(result) self.graph_group.setEnabled(True)
self.report_group.setEnabled(True)
self.thermostat_settings.setEnabled(True)
self.conn_menu.host_set_line.setEnabled(not result) self.conn_menu.host_set_line.setEnabled(False)
self.conn_menu.port_set_spin.setEnabled(not result) self.conn_menu.port_set_spin.setEnabled(False)
self.connect_btn.setText("Disconnect" if result else "Connect") self.connect_btn.setText("Disconnect")
if result:
self.hw_rev_data = await self.thermostat.get_hw_rev()
logging.debug(self.hw_rev_data)
self._status(self.hw_rev_data) self.hw_rev_data = await self.thermostat.get_hw_rev()
self.thermostat.start_watching() logging.debug(self.hw_rev_data)
else:
self.status_lbl.setText("Disconnected") self._status(self.hw_rev_data)
self.background_task_lbl.setText("Ready.")
self.loading_spinner.hide() case ThermostatConnectionState.CONNECTING:
self.loading_spinner.stop() self.status_lbl.setText("Connecting...")
self.thermostat_ctrl_menu.fan_pwm_warning.setPixmap(QtGui.QPixmap()) self.connect_btn.setText("Stop")
self.thermostat_ctrl_menu.fan_pwm_warning.setToolTip("") self.conn_menu.host_set_line.setEnabled(False)
self.clear_graphs() self.conn_menu.port_set_spin.setEnabled(False)
self.report_box.setChecked(False)
for ch in range(self.NUM_CHANNELS): case ThermostatConnectionState.DISCONNECTED:
if self.autotuners.get_state(ch) != PIDAutotuneState.STATE_OFF: self.graph_group.setEnabled(False)
if self.thermostat.connection_errored: self.report_group.setEnabled(False)
# Don't send any commands, just reset local state self.thermostat_settings.setEnabled(False)
self.autotuners.autotuners[ch].setOff()
else: self.conn_menu.host_set_line.setEnabled(True)
await self.autotuners.stop_pid_from_running(ch) self.conn_menu.port_set_spin.setEnabled(True)
await self.thermostat.set_report_mode(False) self.connect_btn.setText("Connect")
self.thermostat.stop_watching()
self.status_lbl.setText("Disconnected")
self.background_task_lbl.setText("Ready.")
self.loading_spinner.hide()
self.loading_spinner.stop()
self.thermostat_ctrl_menu.fan_pwm_warning.setPixmap(QtGui.QPixmap())
self.thermostat_ctrl_menu.fan_pwm_warning.setToolTip("")
self.clear_graphs()
self.report_box.setChecked(False)
for ch in range(self.NUM_CHANNELS):
if self.autotuners.get_state(ch) != PIDAutotuneState.STATE_OFF:
if self.thermostat.connection_errored:
# Don't send any commands, just reset local state
self.autotuners.autotuners[ch].setOff()
else:
await self.autotuners.stop_pid_from_running(ch)
def _status(self, hw_rev_d: dict): def _status(self, hw_rev_d: dict):
logging.debug(hw_rev_d) logging.debug(hw_rev_d)
@ -239,19 +253,13 @@ class MainWindow(QtWidgets.QMainWindow):
except: except:
pass pass
def _connecting(self):
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)
@asyncSlot() @asyncSlot()
async def on_connect_btn_clicked(self): async def on_connect_btn_clicked(self):
if (self._connecting_task is None) and (not self.thermostat.connected()): if (self._connecting_task is None) and (not self.thermostat.connected()):
host = self.conn_menu.host_set_line.text() host = self.conn_menu.host_set_line.text()
port = self.conn_menu.port_set_spin.value() port = self.conn_menu.port_set_spin.value()
self._connecting() await self._on_connection_changed(ThermostatConnectionState.CONNECTING)
self._connecting_task = asyncio.create_task( self._connecting_task = asyncio.create_task(
self.thermostat.start_session(host=host, port=port) self.thermostat.start_session(host=host, port=port)
) )
@ -262,11 +270,11 @@ class MainWindow(QtWidgets.QMainWindow):
if isinstance(exc, asyncio.CancelledError): if isinstance(exc, asyncio.CancelledError):
return return
raise raise
else:
await self._on_connection_changed(True)
finally: finally:
self._connecting_task = None self._connecting_task = None
await self._on_connection_changed(ThermostatConnectionState.CONNECTED)
elif self._connecting_task is not None: elif self._connecting_task is not None:
self._connecting_task.cancel() self._connecting_task.cancel()
else: else:
@ -274,7 +282,7 @@ class MainWindow(QtWidgets.QMainWindow):
@asyncSlot() @asyncSlot()
async def bail(self): async def bail(self):
await self._on_connection_changed(False) await self._on_connection_changed(ThermostatConnectionState.DISCONNECTED)
await self.thermostat.end_session() await self.thermostat.end_session()
@asyncSlot(object, object) @asyncSlot(object, object)
@ -413,14 +421,14 @@ class MainWindow(QtWidgets.QMainWindow):
async def dfu_request(self, _): async def dfu_request(self, _):
assert self.thermostat.connected() assert self.thermostat.connected()
await self._on_connection_changed(False) await self._on_connection_changed(ThermostatConnectionState.DISCONNECTED)
await self.thermostat.dfu() await self.thermostat.dfu()
@asyncSlot(bool) @asyncSlot(bool)
async def reset_request(self, _): async def reset_request(self, _):
assert self.thermostat.connected() assert self.thermostat.connected()
await self._on_connection_changed(False) await self._on_connection_changed(ThermostatConnectionState.DISCONNECTED)
await self.thermostat.reset() await self.thermostat.reset()
await asyncio.sleep(0.1) # Wait for the reset to start await asyncio.sleep(0.1) # Wait for the reset to start
@ -440,7 +448,7 @@ class MainWindow(QtWidgets.QMainWindow):
await self.thermostat.set_ipv4(ipv4_settings) await self.thermostat.set_ipv4(ipv4_settings)
await self.thermostat.end_session() await self.thermostat.end_session()
await self._on_connection_changed(False) await self._on_connection_changed(ThermostatConnectionState.DISCONNECTED)
async def coro_main(): async def coro_main():