diff --git a/pykirdy/kirdy_qt.py b/pykirdy/kirdy_qt.py index c90f453..e4d262e 100644 --- a/pykirdy/kirdy_qt.py +++ b/pykirdy/kirdy_qt.py @@ -20,7 +20,7 @@ import logging import asyncio from driver.kirdy import Kirdy as Kirdy_Driver import qasync -from qasync import asyncClose +from qasync import asyncClose, asyncSlot from collections import deque from datetime import datetime, timezone, timedelta from time import time @@ -96,15 +96,16 @@ class Kirdy(QObject): def end_session(self): if self._timer.isActive(): self._timer.stop() - self._kirdy.end_session() + asyncio.get_running_loop().create_task(self._kirdy.end_session()) @pyqtSlot(bool) def connected_setup(self, connected): if connected: - self._kirdy.device.set_active_report_mode(True) + self._kirdy.task_dispatcher(self._kirdy.device.set_active_report_mode(True)) + self._kirdy._report_mode_on = True def timerEvent(self, event): - self._kirdy.device.get_settings_summary(sig=self.setting_update_sig) + self._kirdy.task_dispatcher(self._kirdy.device.get_settings_summary(sig=self.setting_update_sig)) @pyqtSlot(bool) def start_polling(self, start): @@ -548,19 +549,19 @@ class MainWindow(QtWidgets.QMainWindow): @pyqtSlot(bool) def dfu_mode(_): - self.kirdy.device.dfu() + self.kirdy.task_dispatcher(self.kirdy.device.dfu()) self.kirdy_handler.end_session() self.menu_action_dfu_mode.triggered.connect(dfu_mode) @pyqtSlot(bool) def reset_kirdy(_): - self.kirdy.device.hard_reset() + self.kirdy.task_dispatcher(self.kirdy.device.hard_reset()) self.kirdy_handler.end_session() self.menu_action_hard_reset.triggered.connect(reset_kirdy) @pyqtSlot(bool) def save_settings(_): - self.kirdy.device.save_current_settings_to_flash() + self.kirdy.task_dispatcher(self.kirdy.device.save_current_settings_to_flash()) saved = QtWidgets.QMessageBox(self) saved.setWindowTitle("Config saved") saved.setText(f"Laser diode and thermostat configs have been saved into flash.") @@ -570,7 +571,7 @@ class MainWindow(QtWidgets.QMainWindow): @pyqtSlot(bool) def load_settings(_): - self.kirdy.device.restore_settings_from_flash() + self.kirdy.task_dispatcher(self.kirdy.device.restore_settings_from_flash()) loaded = QtWidgets.QMessageBox(self) loaded.setWindowTitle("Config loaded") loaded.setText(f"Laser Diode and Thermostat configs have been loaded from flash.") @@ -596,32 +597,32 @@ class MainWindow(QtWidgets.QMainWindow): def _set_up_ctrl_btns(self): @pyqtSlot(bool) def ld_pwr_on(_): - self.kirdy.laser.set_power_on(True) + self.kirdy.task_dispatcher(self.kirdy.laser.set_power_on(True)) self.ld_pwr_on_btn.clicked.connect(ld_pwr_on) @pyqtSlot(bool) def ld_pwr_off(_): - self.kirdy.laser.set_power_on(False) + self.kirdy.task_dispatcher(self.kirdy.laser.set_power_on(False)) self.ld_pwr_off_btn.clicked.connect(ld_pwr_off) @pyqtSlot(bool) def ld_clear_alarm(_): - self.kirdy.laser.clear_alarm() + self.kirdy.task_dispatcher(self.kirdy.laser.clear_alarm()) self.ld_clear_alarm_btn.clicked.connect(ld_clear_alarm) @pyqtSlot(bool) def tec_pwr_on(_): - self.kirdy.thermostat.set_power_on(True) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_power_on(True)) self.tec_pwr_on_btn.clicked.connect(tec_pwr_on) @pyqtSlot(bool) def tec_pwr_off(_): - self.kirdy.thermostat.set_power_on(False) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_power_on(False)) self.tec_pwr_off_btn.clicked.connect(tec_pwr_off) @pyqtSlot(bool) def tec_clear_alarm(_): - self.kirdy.thermostat.clear_alarm() + self.kirdy.task_dispatcher(self.kirdy.thermostat.clear_alarm()) self.tec_clear_alarm_btn.clicked.connect(tec_clear_alarm) def _set_up_plot_menu(self): @@ -665,11 +666,11 @@ class MainWindow(QtWidgets.QMainWindow): tree.setParameters(self.params[3], showTop=False) self.params[3].sigTreeStateChanged.connect(self.send_command) - @pyqtSlot() - def autotune(param): + @asyncSlot() + async def autotune(param): match self.autotuner.state(): case PIDAutotuneState.STATE_OFF: - settings = self.kirdy.device.get_settings_summary() + settings = await self.kirdy.device.get_settings_summary() self.autotuner.setParam( param.parent().child('Target Temperature').value(), param.parent().child('Test Current').value() / 1000, @@ -678,7 +679,7 @@ class MainWindow(QtWidgets.QMainWindow): param.parent().child('Lookback').value()) self.autotuner.setReady() param.setOpts(title="Stop") - self.kirdy.thermostat.set_constant_current_control_mode() + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_constant_current_control_mode()) self.kirdy_handler.report_update_sig.connect(self.autotune_tick) self.loading_spinner.show() self.loading_spinner.start() @@ -686,7 +687,7 @@ class MainWindow(QtWidgets.QMainWindow): case PIDAutotuneState.STATE_READY | PIDAutotuneState.STATE_RELAY_STEP_UP | PIDAutotuneState.STATE_RELAY_STEP_DOWN: self.autotuner.setOff() param.setOpts(title="Run") - self.kirdy.thermostat.set_tec_i_out(0.0) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_tec_i_out(0.0)) self.kirdy_handler.report_update_sig.disconnect(self.autotune_tick) self.background_task_lbl.setText("Ready.") self.loading_spinner.stop() @@ -698,16 +699,16 @@ class MainWindow(QtWidgets.QMainWindow): match self.autotuner.state(): case PIDAutotuneState.STATE_READY | PIDAutotuneState.STATE_RELAY_STEP_UP | PIDAutotuneState.STATE_RELAY_STEP_DOWN: self.autotuner.run(report['thermostat']['temperature'], report['ts']/1000) - self.kirdy.thermostat.set_tec_i_out(self.autotuner.output()) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_tec_i_out(self.autotuner.output())) case PIDAutotuneState.STATE_SUCCEEDED: kp, ki, kd = self.autotuner.get_tec_pid() self.autotuner.setOff() self.params[3].child('PID Config', 'PID Auto Tune', 'Run').setOpts(title="Run") - self.kirdy.thermostat.set_pid_kp(kp) - self.kirdy.thermostat.set_pid_ki(ki) - self.kirdy.thermostat.set_pid_kd(kd) - self.kirdy.thermostat.set_pid_control_mode() - self.kirdy.thermostat.set_temperature_setpoint(self.params[3].child('PID Config', 'PID Auto Tune', 'Target Temperature').value()) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_kp(kp)) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_ki(ki)) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_kd(kd)) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_control_mode()) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_temperature_setpoint(self.params[3].child('PID Config', 'PID Auto Tune', 'Target Temperature').value())) self.kirdy_handler.report_update_sig.disconnect(self.autotune_tick) self.background_task_lbl.setText("Ready.") self.loading_spinner.stop() @@ -719,7 +720,7 @@ class MainWindow(QtWidgets.QMainWindow): case PIDAutotuneState.STATE_FAILED: self.autotuner.setOff() self.params[3].child('PID Config', 'PID Auto Tune', 'Run').setOpts(title="Run") - self.kirdy.thermostat.set_tec_i_out(0.0) + self.kirdy.task_dispatcher(self.kirdy.thermostat.set_tec_i_out(0.0)) self.kirdy_handler.report_update_sig.disconnect(self.autotune_tick) self.background_task_lbl.setText("Ready.") self.loading_spinner.stop() @@ -899,7 +900,7 @@ class MainWindow(QtWidgets.QMainWindow): port = net_settings["port"] prefix_len = net_settings["prefix_len"] gateway = net_settings["gateway_addr"] - self.kirdy.device.set_ip_settings(addr, port, prefix_len, gateway) + self.kirdy.task_dispatcher(self.kirdy.device.set_ip_settings(addr, port, prefix_len, gateway)) self.status_lbl.setText("IP Settings is Updated") @pyqtSlot() @@ -931,7 +932,7 @@ class MainWindow(QtWidgets.QMainWindow): target, action = inner_param.opts['target_action_pair'][inner_param.opts['limits'].index(data)] cmd = getattr(getattr(self.kirdy, target), action) param.child(*param.childPath(inner_param)).setOpts(lock=True) - cmd() + self.kirdy.task_dispatcher(cmd()) param.child(*param.childPath(inner_param)).setOpts(lock=False) continue """ cmd translation from non-mutex type parameter""" @@ -942,25 +943,27 @@ class MainWindow(QtWidgets.QMainWindow): data = siEval(str(data)+inner_param.opts["unit"], regex=FLOAT_REGEX, suffix=suffix) cmd = getattr(getattr(self.kirdy, inner_param.opts["target"]), inner_param.opts["action"]) param.child(*param.childPath(inner_param)).setOpts(lock=True) - cmd(data) + self.kirdy.task_dispatcher(cmd(data)) param.child(*param.childPath(inner_param)).setOpts(lock=False) continue -def coro_main(): +async def coro_main(): args = get_argparser().parse_args() if args.logLevel: logging.basicConfig(level=getattr(logging, args.logLevel)) - app = QtWidgets.QApplication(sys.argv) + app_quit_event = asyncio.Event() + + app = QtWidgets.QApplication.instance() + app.aboutToQuit.connect(app_quit_event.set) main_window = MainWindow(args) main_window.show() - app.aboutToQuit.connect(main_window.kirdy_handler.end_session) - app.exec() + await app_quit_event.wait() def main(): - coro_main() + qasync.run(coro_main()) if __name__ == '__main__': main()