Compare commits

..

38 Commits

Author SHA1 Message Date
34911e395b Extra bail removed 2024-08-23 18:24:40 +08:00
78e9068e2b return hwrev when start_session 2024-08-23 18:24:40 +08:00
04d073bc18 state str 2024-08-23 18:24:40 +08:00
255f7b7188 params update concurrently 2024-08-23 18:24:40 +08:00
70aee95914 Compact 2024-08-23 18:24:40 +08:00
e3701ece99 Stuff non-UI changes in Thermostat model 2024-08-23 18:24:40 +08:00
26c3d330c4 State dependend UI 2024-08-23 18:24:35 +08:00
671fb4fcc6 State 2024-08-23 18:24:18 +08:00
c0a638187c Actually its OSError 2024-08-23 18:24:18 +08:00
3fb450d2ca _ 2024-08-23 18:24:18 +08:00
f887413d82 conneting 2024-08-23 18:24:18 +08:00
fcadb8aa44 Remove wait_for
OSError raised anyways
2024-08-23 18:24:18 +08:00
16f3e81384 Raise if OSError 2024-08-23 18:24:18 +08:00
baf629ece7 Sep. line 2024-08-23 18:24:17 +08:00
87d09d8c7f {start,end}_session -> [dis]connect 2024-08-23 18:24:17 +08:00
12a3154493 In 2024-08-23 18:24:17 +08:00
f7665ea736 Compacting 2024-08-23 18:24:17 +08:00
16369cec71 try-block 2024-08-23 18:24:17 +08:00
1f90a2e9fe Fix? 2024-08-23 18:24:17 +08:00
022e6b9bda Connecting task moved? 2024-08-23 18:24:17 +08:00
e6b7a482ba AsyncIO version Client -> AsyncioClient 2024-08-23 18:24:17 +08:00
dd0463b85b Exclusively use the Thermostat object as a medium
All calls to the Thermostat should be forwarded by the medium.
2024-08-23 18:24:12 +08:00
d583abba69 Integrate WrappedClient into Thermostat model 2024-08-23 18:23:40 +08:00
9781c75319 Should not stop cancelling read if timeout'd 2024-08-23 18:23:39 +08:00
711bd14ce6 Fix Autotuner state for forceful disconnect 2024-08-23 18:23:39 +08:00
f230a51a52 Correct exception catching
asyncio.Task.result() is simply going to throw the exception in
asyncio.Task.exception(), there is no need to manually throw it.
2024-08-23 18:23:39 +08:00
446d5c4d22 Make connection loss handling more elegant
Show an info box on connection lost informing the user that the
Thermostat was forcefully disconnected.
2024-08-23 18:23:39 +08:00
5694951a23 ================gui_dev-fix_asyncio=============== 2024-08-23 18:23:39 +08:00
bd9da08fc7 This is bail 2024-08-23 18:23:36 +08:00
a087622371 task -> _connecting_task 2024-08-23 18:19:28 +08:00
2b265d6e36 Resgister task 2024-08-23 18:18:57 +08:00
9312433b98 ip -> host 2024-08-23 18:17:35 +08:00
2f56281031 Lazy evaluating for debug string command 2024-08-23 18:17:35 +08:00
61a48c37d1 Add pytec runnables 2024-08-23 18:17:35 +08:00
06e52a627f PYTHON shell 2024-08-23 18:17:35 +08:00
10acb23c82 Exactlier wording 2024-08-23 18:17:33 +08:00
159fdd863b unused 2024-08-23 18:13:58 +08:00
607d0f80e4 encoding 2024-08-23 18:13:58 +08:00
2 changed files with 35 additions and 32 deletions

View File

@ -8,9 +8,9 @@ from pytec.aioclient import AsyncioClient
class ThermostatConnectionState(Enum): class ThermostatConnectionState(Enum):
DISCONNECTED = False DISCONNECTED = "disconnected"
CONNECTING = "connecting" CONNECTING = "connecting"
CONNECTED = True CONNECTED = "connected"
class Thermostat(QObject, metaclass=PropertyMeta): class Thermostat(QObject, metaclass=PropertyMeta):
@ -31,20 +31,22 @@ class Thermostat(QObject, metaclass=PropertyMeta):
self._watch_task = None self._watch_task = None
self._report_mode_task = None self._report_mode_task = None
self._poll_for_report = True self._poll_for_report = True
self._update_params_task = None
self.connection_errored = False self.connection_errored = False
self.task = None
super().__init__(parent) super().__init__(parent)
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)
hw_rev_data = await self.get_hw_rev()
self.start_watching() self.start_watching()
return hw_rev_data
async def run(self): async def run(self):
self.task = asyncio.create_task(self.update_params()) self._update_params_task = asyncio.create_task(self.update_params())
while True: while True:
if self.task.done(): if self._update_params_task.done():
try: try:
self.task.result() self._update_params_task.result()
except OSError: except OSError:
logging.error( logging.error(
"Encountered an error while polling for information from Thermostat.", "Encountered an error while polling for information from Thermostat.",
@ -52,7 +54,7 @@ class Thermostat(QObject, metaclass=PropertyMeta):
) )
self.connection_error.emit() self.connection_error.emit()
return return
self.task = asyncio.create_task(self.update_params()) self._update_params_task = asyncio.create_task(self.update_params())
await asyncio.sleep(self._update_s) await asyncio.sleep(self._update_s)
@pyqtSlot() @pyqtSlot()
@ -64,16 +66,23 @@ class Thermostat(QObject, metaclass=PropertyMeta):
return self.hw_rev return self.hw_rev
async def update_params(self): async def update_params(self):
self.fan = await self._client.get_fan() fan_task = asyncio.create_task(self._client.get_fan())
self.pwm = await self._client.get_pwm() pwm_task = asyncio.create_task(self._client.get_pwm())
pid_task = asyncio.create_task(self._client.get_pid())
report_task = asyncio.create_task(self._client.report())
thermistor_task = asyncio.create_task(self._client.get_steinhart_hart())
postfilter_task = asyncio.create_task(self._client.get_postfilter())
self.fan = await fan_task
self.pwm = await pwm_task
if self._poll_for_report: if self._poll_for_report:
self.report = await self._client.report() self.report = await report_task
self.interval = [ self.interval = [
self.report[i]["interval"] for i in range(len(self.report)) self.report[i]["interval"] for i in range(len(self.report))
] ]
self.pid = await self._client.get_pid() self.pid = await pid_task
self.thermistor = await self._client.get_steinhart_hart() self.thermistor = await thermistor_task
self.postfilter = await self._client.get_postfilter() self.postfilter = await postfilter_task
def connected(self): def connected(self):
return self._client.connected() return self._client.connected()
@ -87,8 +96,8 @@ class Thermostat(QObject, metaclass=PropertyMeta):
await self.set_report_mode(False) await self.set_report_mode(False)
self._watch_task.cancel() self._watch_task.cancel()
self._watch_task = None self._watch_task = None
self.task.cancel() self._update_params_task.cancel()
self.task = None self._update_params_task = None
async def set_report_mode(self, enabled: bool): async def set_report_mode(self, enabled: bool):
self._poll_for_report = not enabled self._poll_for_report = not enabled

View File

@ -29,9 +29,9 @@ def get_argparser():
"--connect", "--connect",
default=None, default=None,
action="store_true", action="store_true",
help="Automatically connect to the specified Thermostat in IP:port format", help="Automatically connect to the specified Thermostat in host:port format",
) )
parser.add_argument("IP", metavar="ip", default=None, nargs="?") parser.add_argument("HOST", metavar="host", default=None, nargs="?")
parser.add_argument("PORT", metavar="port", default=None, nargs="?") parser.add_argument("PORT", metavar="port", default=None, nargs="?")
parser.add_argument( parser.add_argument(
"-l", "-l",
@ -72,8 +72,6 @@ class MainWindow(QtWidgets.QMainWindow):
"Connection Error", "Thermostat connection lost. Is it unplugged?" "Connection Error", "Thermostat connection lost. Is it unplugged?"
) )
self.bail()
self.thermostat.connection_error.connect(handle_connection_error) self.thermostat.connection_error.connect(handle_connection_error)
self.thermostat.connection_error.connect(self.thermostat.timed_out) self.thermostat.connection_error.connect(self.thermostat.timed_out)
@ -82,7 +80,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.autotuners = PIDAutoTuner(self, self.thermostat, 2) self.autotuners = PIDAutoTuner(self, self.thermostat, 2)
def get_ctrl_panel_config(args): def get_ctrl_panel_config(args):
with open(args.param_tree, "r") 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 = [ param_tree_sigActivated_handles = [
@ -186,9 +184,6 @@ class MainWindow(QtWidgets.QMainWindow):
self.conn_menu.port_set_spin.setEnabled(False) self.conn_menu.port_set_spin.setEnabled(False)
self.connect_btn.setText("Disconnect") self.connect_btn.setText("Disconnect")
self.hw_rev_data = await self.thermostat.get_hw_rev()
logging.debug(self.hw_rev_data)
self._status(self.hw_rev_data) self._status(self.hw_rev_data)
case ThermostatConnectionState.CONNECTING: case ThermostatConnectionState.CONNECTING:
@ -223,7 +218,6 @@ class MainWindow(QtWidgets.QMainWindow):
await self.autotuners.stop_pid_from_running(ch) 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)
self.status_lbl.setText( self.status_lbl.setText(
f"Connected to Thermostat v{hw_rev_d['rev']['major']}.{hw_rev_d['rev']['minor']}" f"Connected to Thermostat v{hw_rev_d['rev']['major']}.{hw_rev_d['rev']['minor']}"
) )
@ -247,7 +241,7 @@ class MainWindow(QtWidgets.QMainWindow):
await self.thermostat.set_report_mode(enabled) await self.thermostat.set_report_mode(enabled)
@asyncClose @asyncClose
async def closeEvent(self, event): async def closeEvent(self, _event):
try: try:
await self.bail() await self.bail()
except: except:
@ -256,15 +250,16 @@ class MainWindow(QtWidgets.QMainWindow):
@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()
port = self.conn_menu.port_set_spin.value()
await self._on_connection_changed(ThermostatConnectionState.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=self.conn_menu.host_set_line.text(),
port=self.conn_menu.port_set_spin.value(),
)
) )
try: try:
await self._connecting_task self.hw_rev_data = await self._connecting_task
except (OSError, asyncio.CancelledError) as exc: except (OSError, asyncio.CancelledError) as exc:
await self.bail() await self.bail()
if isinstance(exc, asyncio.CancelledError): if isinstance(exc, asyncio.CancelledError):
@ -447,8 +442,7 @@ class MainWindow(QtWidgets.QMainWindow):
assert self.thermostat.connected() assert self.thermostat.connected()
await self.thermostat.set_ipv4(ipv4_settings) await self.thermostat.set_ipv4(ipv4_settings)
await self.thermostat.end_session() await self.bail()
await self._on_connection_changed(ThermostatConnectionState.DISCONNECTED)
async def coro_main(): async def coro_main():