Compare commits

..

2 Commits

Author SHA1 Message Date
9c22950e59 State 2024-08-21 16:18:01 +08:00
cebf995427 Remove all timeouts from aioclient 2024-08-21 16:18:01 +08:00
7 changed files with 43 additions and 64 deletions

View File

@ -118,20 +118,6 @@
];
};
pytec-dev-wrappers = pkgs.runCommandNoCC "pytec-dev-wrappers" {}
''
mkdir -p $out/bin
for program in ${self}/pytec/*.py; do
if [ -x $program ]; then
progname=`basename -s .py $program`
outname=$out/bin/$progname
echo "#!${pkgs.bash}/bin/bash" >> $outname
echo "exec python3 -m pytec.$progname \"\$@\"" >> $outname
chmod 755 $outname
fi
done
'';
thermostat_gui = pkgs.python3Packages.buildPythonPackage {
pname = "thermostat_gui";
version = "0.0.0";
@ -177,7 +163,6 @@
rust
openocd
dfu-util
pytec-dev-wrappers
]
++ (with python3Packages; [
numpy
@ -189,9 +174,6 @@
pglive
qtextras
]);
shellHook = ''
export PYTHONPATH=`pwd`/pytec:$PYTHONPATH
'';
};
defaultPackage.x86_64-linux = thermostat;
};

0
pytec/autotune.py Executable file → Normal file
View File

View File

@ -4,7 +4,7 @@ from pytec.aioclient import AsyncioClient
async def main():
tec = AsyncioClient()
await tec.connect() # (host="192.168.1.26", port=23)
await tec.start_session() # (host="192.168.1.26", port=23)
await tec.set_param("s-h", 1, "t0", 20)
print(await tec.get_pwm())
print(await tec.get_pid())

0
pytec/plot.py Executable file → Normal file
View File

View File

@ -13,14 +13,13 @@ class AsyncioClient:
self._writer = None
self._command_lock = asyncio.Lock()
self._report_mode_on = False
self.timeout = None
async def connect(self, host="192.168.1.26", port=23):
"""Connect to Thermostat at specified host and port.
async def start_session(self, host="192.168.1.26", port=23):
"""Start session to Thermostat at specified host and port.
Example::
client = AsyncioClient()
await client.connect()
await client.start_session()
"""
self._reader, self._writer = await asyncio.open_connection(host, port)
await self._check_zero_limits()
@ -29,8 +28,8 @@ class AsyncioClient:
"""Returns True if client is connected"""
return self._writer is not None
async def disconnect(self):
"""Disconnect from the Thermostat"""
async def end_session(self):
"""End session to Thermostat"""
if self._writer is None:
return
@ -54,9 +53,7 @@ class AsyncioClient:
async def _read_line(self):
# read 1 line
chunk = await asyncio.wait_for(
self._reader.readline(), self.timeout
) # Only wait for response until timeout
chunk = await self._reader.readline()
return chunk.decode("utf-8", errors="ignore")
async def _read_write(self, command):
@ -70,7 +67,7 @@ class AsyncioClient:
line = await self._read_write(command)
response = json.loads(line)
logging.debug("%s: %s", command, response)
logging.debug(f"{command}: {response}")
if "error" in response:
raise CommandError(response["error"])
return response
@ -241,7 +238,7 @@ class AsyncioClient:
self._writer.write("reset\n".encode("utf-8"))
await self._writer.drain()
await self.disconnect()
await self.end_session()
async def dfu(self):
"""Put the Thermostat in DFU update mode
@ -254,7 +251,7 @@ class AsyncioClient:
self._writer.write("dfu\n".encode("utf-8"))
await self._writer.drain()
await self.disconnect()
await self.end_session()
async def ipv4(self):
"""Get the IPv4 settings of the Thermostat"""

View File

@ -32,21 +32,20 @@ class Thermostat(QObject, metaclass=PropertyMeta):
self._report_mode_task = None
self._poll_for_report = True
self.connection_errored = False
self.task = None
super().__init__(parent)
async def start_session(self, host, port):
await self._client.connect(host, port)
await self._client.start_session(host, port)
async def run(self):
self.task = asyncio.create_task(self.update_params())
while True:
if self.task.done():
try:
self.task.result()
except OSError:
_ = self.task.result()
except asyncio.TimeoutError:
logging.error(
"Encountered an error while polling for information from Thermostat.",
"Encountered an error while updating parameter tree.",
exc_info=True,
)
self.connection_error.emit()
@ -104,7 +103,7 @@ class Thermostat(QObject, metaclass=PropertyMeta):
]
async def end_session(self):
await self._client.disconnect()
await self._client.end_session()
self.connection_errored = False
async def set_ipv4(self, ipv4):

55
pytec/tec_qt.py Executable file → Normal file
View File

@ -65,7 +65,6 @@ class MainWindow(QtWidgets.QMainWindow):
self.thermostat = Thermostat(
self, self.report_refresh_spin.value()
)
self._connecting_task = None
def handle_connection_error():
self.info_box.display_info_box(
@ -239,38 +238,40 @@ class MainWindow(QtWidgets.QMainWindow):
except:
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()
async def on_connect_btn_clicked(self):
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()
host, port = (
self.conn_menu.host_set_line.text(),
self.conn_menu.port_set_spin.value(),
)
self._connecting()
self._connecting_task = asyncio.create_task(
self.thermostat.start_session(host=host, port=port)
)
try:
await self._connecting_task
except (OSError, asyncio.CancelledError) as exc:
await self.bail()
if isinstance(exc, asyncio.CancelledError):
self._connecting_task = None
try:
if (self._connecting_task is None) or (not 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:
self._connecting_task = asyncio.wait_for(
self.thermostat.start_session(host=host, port=port), timeout=5
)
await self._connecting_task
except asyncio.TimeoutError:
return
raise
else:
await self._on_connection_changed(True)
finally:
self._connecting_task = None
else:
if self._connecting_task is not None:
self._connecting_task.cancel()
await self.bail()
elif self._connecting_task is not None:
self._connecting_task.cancel()
else:
await self.bail()
# TODO: Remove asyncio.TimeoutError in Python 3.11
except (OSError, asyncio.TimeoutError):
try:
await self.bail()
except ConnectionResetError:
pass
@asyncSlot()
async def bail(self):