Compare commits

..

103 Commits

Author SHA1 Message Date
3f32c9a4a2 aioclient: More accurate DFU docstring 2024-08-29 13:23:50 +08:00
89986fd810 No need for async as well 2024-08-29 12:51:18 +08:00
f8900d295d Order 2024-08-29 12:12:05 +08:00
f0772a8072 No need for async 2024-08-29 12:11:49 +08:00
b9ba1e2d9f Remove extra imports 2024-08-29 12:02:56 +08:00
4997db0b4c blank line 2024-08-29 11:48:39 +08:00
65e3f6395b report group 2024-08-29 11:47:39 +08:00
daa3192d41 end_session in thermostat itself afterall 2024-08-29 11:40:57 +08:00
a6be838445 Reorder MainWindow 2024-08-29 11:26:11 +08:00
89076b2d13 Actually pid_auto_tune_request belongs to ctrl_panel 2024-08-29 11:09:33 +08:00
78b3f8e419 fixup! fixup! Rearrange MainWindow.__init__ 2024-08-29 10:57:45 +08:00
3925551071 Move command line host:port setting handling
To main
2024-08-29 10:36:18 +08:00
2fd852e171 finish IP -> HOST 2024-08-29 10:35:41 +08:00
425dee173b No need for explicitly resetting Autotune elements 2024-08-28 17:49:19 +08:00
9531e7063a fixup! Rearrange MainWindow.__init__ 2024-08-28 17:26:43 +08:00
e3ea0f970e Use new style super() 2024-08-28 17:22:59 +08:00
9b9b4baf98 Rearrange MainWindow.__init__ 2024-08-28 17:20:14 +08:00
60295d2baa Thermostat: Add disconnect callback
For communicating with the autotuner before the client fully
disconnects
2024-08-28 17:06:17 +08:00
c761f9fe94 Fix hwrev getting 2024-08-28 16:32:55 +08:00
585c35b4c9 fixup forgetting to await 2024-08-28 16:09:30 +08:00
f9f8f6f2b6 Remove info_box_trigger 2024-08-28 13:45:57 +08:00
2a12d02bc8 Remove connection errored 2024-08-28 13:38:09 +08:00
96b0ddc26c Simply test for connectivity for turning PID off 2024-08-28 13:37:49 +08:00
e30d07d707 Fix pressing enter not working in conn menu 2024-08-28 11:38:51 +08:00
326c22d6b2 Assign connection_errored as well 2024-08-28 11:07:34 +08:00
b3f629fb4a Back out 2024-08-28 11:06:26 +08:00
c2dccb80f8 Put UI changes into conn_menu 2024-08-28 11:03:26 +08:00
db127f788b fixup! Refactor repeated stuff 2024-08-28 10:55:58 +08:00
863106d835 fixup! Concentrate ThermostatCtrlMenu UI changes 2024-08-28 10:54:58 +08:00
ff4aa61b1e fixup! Clear Graph UI changes 2024-08-28 10:52:12 +08:00
209ea365c2 ConnectionBtn + StatusLbl 2024-08-28 10:50:48 +08:00
35a179f7fa Clear Graph UI changes 2024-08-28 10:50:38 +08:00
94eb6b09fd Concentrate ThermostatCtrlMenu UI changes 2024-08-28 10:33:59 +08:00
2ec059d402 Descriptive name 2024-08-28 10:24:37 +08:00
ac9ddc92a6 Refactor repeated stuff 2024-08-28 10:24:25 +08:00
94eb331c96 Actually move it into autotuners 2024-08-27 18:29:13 +08:00
40abceb688 Split PID handler UI up 2024-08-27 18:24:56 +08:00
7b662374bc hwrev updates 2024-08-27 18:13:05 +08:00
dc5460f591 aioclient: Add missing readline for saving
Saving all channels returns multiple JSON objects, read the extra {}.
2024-08-27 17:08:38 +08:00
df79d4d977 Fix not actually awaiting for load/save 2024-08-27 17:07:45 +08:00
9910f935a9 Add back the info_box 2024-08-27 17:07:12 +08:00
e3ac7debc4 Fix info boxes for load/saving from flash 2024-08-27 17:00:16 +08:00
a8d7986c82 Move reset request to thermostat control menu
We don't get auto reconnect anymore
2024-08-27 16:51:01 +08:00
5a09c026fa Move pid autotuning request to CtrlPanel
And update autotune UI only on state change instead of every single
report update
2024-08-27 16:46:48 +08:00
8ab04ac3cd autotuner*s* 2024-08-27 16:04:07 +08:00
5ecbb262be Move channelGraph stuff inside LiveDataPlotter 2024-08-27 16:01:07 +08:00
f141705b0e Move plot_options_menu stuff into menu 2024-08-27 16:01:03 +08:00
19470b3d02 Move autotune ticking connect 2024-08-27 15:20:50 +08:00
5862a2f7d5 Moove functools up 2024-08-27 14:56:17 +08:00
ac34472d31 Get thermostat_ctrl_menu to subscribe to hwrev updates 2024-08-27 13:31:23 +08:00
f45061a652 Save/load info box content 2024-08-27 13:21:41 +08:00
d9a3fcdc4b Remove unused load/save request & signal 2024-08-27 13:19:06 +08:00
22fc7cbf22 Fix loading all channel settings would bring up 2 info boxes 2024-08-27 13:17:25 +08:00
0133d2e41b ok which commit to fixup huh 2024-08-27 12:06:57 +08:00
43758e12a3 hw_rev 2024-08-27 11:27:31 +08:00
5dcf9e8f31 fan_update: tec_qt to thermostat_ctrl_menu 2024-08-27 10:45:19 +08:00
40c0519237 Fix updating status label for hwrev = None 2024-08-27 10:40:06 +08:00
260a466078 Put some menu requests in menu itself 2024-08-26 18:01:01 +08:00
8a13ce2b47 Tie Thermostat ConnectionState to Qt signal for now
Change this to callback-based later for decoupling from Qt
2024-08-26 17:09:29 +08:00
ba369c880e Move sigActivatedHandle to CtrlPanel 2024-08-26 15:23:55 +08:00
375e159c39 Get rid of timeout on readline 2024-08-26 15:21:26 +08:00
4240312bf4 Put send_command in CtrlPanel 2024-08-26 13:49:56 +08:00
20f168e04c flake update 2024-08-26 13:11:26 +08:00
efe0c086d8 Extra bail removed 2024-08-26 12:21:57 +08:00
9f3591770a return hwrev when start_session 2024-08-26 12:21:57 +08:00
17157fd890 state str 2024-08-26 12:21:57 +08:00
42268e2186 params update concurrently 2024-08-26 12:21:57 +08:00
db15c0052e Compact 2024-08-26 12:21:57 +08:00
bfddfd8e20 Stuff non-UI changes in Thermostat model 2024-08-26 12:21:57 +08:00
77b66e15cc State dependend UI 2024-08-26 12:21:57 +08:00
ae51fc739e State 2024-08-26 12:21:57 +08:00
7279c4d64a Actually its OSError 2024-08-26 12:21:57 +08:00
71f40027f5 conneting 2024-08-26 12:21:57 +08:00
388c914c18 Remove wait_for
OSError raised anyways
2024-08-26 12:21:57 +08:00
659ed384ae {start,end}_session -> [dis]connect 2024-08-26 12:21:57 +08:00
b252dc6a44 Simplify on_connect_btn_clicked
Raise if OSError
2024-08-26 12:21:57 +08:00
0dbed18ba1 Connecting task moved? 2024-08-26 12:21:57 +08:00
2b9a4c168e AsyncIO version Client -> AsyncioClient 2024-08-26 12:21:57 +08:00
83405103f2 Exclusively use the Thermostat object as a medium
All calls to the Thermostat should be forwarded by the medium.
2024-08-26 12:21:57 +08:00
71f4ad6e34 Integrate WrappedClient into Thermostat model 2024-08-26 12:21:57 +08:00
4d21770542 Should not stop cancelling read if timeout'd 2024-08-26 12:21:57 +08:00
52ee422a70 Fix Autotuner state for forceful disconnect 2024-08-26 12:21:57 +08:00
5475bf7951 _ 2024-08-26 12:21:57 +08:00
da70430c35 Make connection loss handling more elegant
Show an info box on connection lost informing the user that the
Thermostat was forcefully disconnected.
2024-08-26 12:21:57 +08:00
5e8f61be9e ================gui_dev-fix_asyncio=============== 2024-08-26 12:21:57 +08:00
b6f936a65f This is bail 2024-08-26 12:21:57 +08:00
79cc11dd14 thermostat: Properly register task
Also Thermostat.task -> Thermostat._update_params_task
2024-08-26 12:21:57 +08:00
7a5bb8d308 ip -> host 2024-08-26 12:21:57 +08:00
7245e514e8 Lazy evaluating for debug string command 2024-08-26 12:21:57 +08:00
fbaeb870c6 Add pytec runnables 2024-08-26 12:21:52 +08:00
f922ea906f PYTHON shell 2024-08-26 12:18:22 +08:00
aef3a9870b Exactlier wording 2024-08-26 12:18:22 +08:00
752d6f8eab unused 2024-08-26 12:18:22 +08:00
7a5ec14b95 encoding 2024-08-26 12:18:22 +08:00
b2f188b556 Just catch asyncio.TimeoutError
Will just change to TimeoutError once we switch to Python 3.11 in the
flake.
2024-08-26 12:18:22 +08:00
a2afd81dcd Remove exception too general 2024-08-26 12:18:22 +08:00
89319c0cd9 Use asserts to check for connectivity 2024-08-26 12:18:22 +08:00
f75de51447 Add back the parent 2024-08-26 12:18:22 +08:00
6f0956b35c Fix method call 2024-08-26 12:18:22 +08:00
6067c41ca4 README: Proofread 2024-08-26 12:18:22 +08:00
8a01249d60 Swap order arounda bit more 2024-08-26 12:18:22 +08:00
0ec18dfbff Formatting 2024-08-26 12:18:22 +08:00
6f7b46bc2f Use qtextras 2024-08-26 12:18:19 +08:00
5 changed files with 45 additions and 65 deletions

View File

@ -1,19 +1,7 @@
import asyncio
from contextlib import suppress
from pytec.aioclient import AsyncioClient
async def poll_for_info(tec):
while True:
print(tec.get_pwm())
print(tec.get_steinhart_hart())
print(tec.get_pid())
print(tec.get_postfilter())
print(tec.get_fan())
await asyncio.sleep(1)
async def main():
tec = AsyncioClient()
await tec.connect() # (host="192.168.1.26", port=23)
@ -23,14 +11,8 @@ async def main():
print(await tec.get_pwm())
print(await tec.get_postfilter())
print(await tec.get_steinhart_hart())
polling_task = asyncio.create_task(poll_for_info(tec))
async for data in tec.report_mode():
print(data)
polling_task.cancel()
with suppress(asyncio.CancelledError):
await polling_task
asyncio.run(main())

View File

@ -11,6 +11,7 @@ class PIDAutoTuner(QObject):
self._thermostat = thermostat
self._thermostat.report_update.connect(self.tick)
self._thermostat.interval_update.connect(self.update_sampling_interval)
self.autotuners = [PIDAutotune(25) for _ in range(num_of_channel)]
self.target_temp = [20.0 for _ in range(num_of_channel)]
@ -19,6 +20,10 @@ class PIDAutoTuner(QObject):
self.lookback = [3.0 for _ in range(num_of_channel)]
self.sampling_interval = [1 / 16.67 for _ in range(num_of_channel)]
@pyqtSlot(list)
def update_sampling_interval(self, interval):
self.sampling_interval = interval
def set_params(self, params_name, ch, val):
getattr(self, params_name)[ch] = val
@ -45,14 +50,11 @@ class PIDAutoTuner(QObject):
@asyncSlot(list)
async def tick(self, report):
for channel_report in report:
ch = channel_report["channel"]
self.sampling_interval[ch] = channel_report["interval"]
# TODO: Skip when PID Autotune or emit error message if NTC is not connected
if channel_report["temperature"] is None:
continue
ch = channel_report["channel"]
match self.autotuners[ch].state():
case (
PIDAutotuneState.STATE_READY

View File

@ -20,6 +20,7 @@ class Thermostat(QObject, metaclass=PropertyMeta):
pid = Property(list)
pwm = Property(list)
postfilter = Property(list)
interval = Property(list)
report = Property(list)
connection_error = pyqtSignal()
@ -53,45 +54,36 @@ class Thermostat(QObject, metaclass=PropertyMeta):
"Encountered an error while polling for information from Thermostat.",
exc_info=True,
)
await self.handle_connection_error()
self.handle_connection_error()
return
self._update_params_task = asyncio.create_task(self.update_params())
await asyncio.sleep(self._update_s)
async def handle_connection_error(self):
await self.end_session()
def handle_connection_error(self):
self.end_session()
self.connection_error.emit()
async def get_hw_rev(self):
return await self._client.hw_rev()
async def update_params(self):
fan_task = asyncio.create_task(self._client.get_fan())
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:
(
self.fan,
self.pwm,
self.report,
self.pid,
self.thermistor,
self.postfilter,
) = await asyncio.gather(
self._client.get_fan(),
self._client.get_pwm(),
self._client.report(),
self._client.get_pid(),
self._client.get_steinhart_hart(),
self._client.get_postfilter(),
)
else:
self.fan, self.pwm, self.pid, self.thermistor, self.postfilter = (
await asyncio.gather(
self._client.get_fan(),
self._client.get_pwm(),
self._client.get_pid(),
self._client.get_steinhart_hart(),
self._client.get_postfilter(),
)
)
self.report = await report_task
self.interval = [
self.report[i]["interval"] for i in range(len(self.report))
]
self.pid = await pid_task
self.thermistor = await thermistor_task
self.postfilter = await postfilter_task
def connected(self):
return self._client.connected()
@ -118,6 +110,9 @@ class Thermostat(QObject, metaclass=PropertyMeta):
async def report_mode(self):
async for report in self._client.report_mode():
self.report_update.emit(report)
self.interval = [
self.report[i]["interval"] for i in range(len(self.report))
]
@asyncSlot()
async def end_session(self):

View File

@ -285,6 +285,19 @@ class CtrlPanel(QObject):
f"Channel {ch} PID Autotune has failed.",
)
@asyncSlot()
async def pid_auto_tune_request(self, ch):
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)
@asyncSlot(int)
async def load_settings(self, ch):
await self.thermostat.load_cfg(ch)
@ -303,17 +316,3 @@ class CtrlPanel(QObject):
f"Channel {ch} settings has been saved to flash.\n"
"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)

View File

@ -59,7 +59,9 @@ class MainWindow(QtWidgets.QMainWindow):
self.info_box = InfoBox()
# Models
self.thermostat = Thermostat(self, self.report_refresh_spin.value())
self.thermostat = Thermostat(
self, self.report_refresh_spin.value()
)
self._connecting_task = None
self.thermostat.connection_state_changed.connect(self._on_connection_changed)