From cf294d18d64ad13997cf60d077e061cdf64a81b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Odd=20Str=C3=A5b=C3=B8?= Date: Fri, 5 Nov 2021 03:01:43 +0100 Subject: [PATCH] Add timeout to read function Fix __exit__ --- solar_ble.py | 35 +++++++++++++++++++++++++++++------ test_bleuart.py | 19 ++++++++++--------- 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/solar_ble.py b/solar_ble.py index eb4dd3f..149c390 100755 --- a/solar_ble.py +++ b/solar_ble.py @@ -24,6 +24,11 @@ INTERVAL = 15 WRITE_DEVICE = "0000ffd1-0000-1000-8000-00805f9b34fb" READ_DEVICE = "0000fff1-0000-1000-8000-00805f9b34fb" +ACTION_READ = 0x03 +ACTION_WRITE = 0x03 + +POSSIBLE_MARKER = (0x01, 0xFD, 0xFE, 0xFF) + # get(255, 12, 2) # "ff 03 00 0c 00 02" CMD_GET_1 = b"\xff\x03\x00\x0c\x00\x02" @@ -316,14 +321,14 @@ class BTLEUart(io.RawIOBase): left = timeout - (time.time() - start) if left < 0: break - self.device.waitForNotifications(0.1) + self._poll() try: self._read_buffer.extend(self.delegate.queue.get_nowait()) except queue.Empty: pass try: while True: - self.device.waitForNotifications(0.01) + self._poll() self._read_buffer.extend(self.delegate.queue.get_nowait()) except queue.Empty: @@ -334,7 +339,7 @@ class BTLEUart(io.RawIOBase): left = timeout - (time.time() - start) if left < 0: break - self.device.waitForNotifications(0.1) + self._poll() try: self._read_buffer.extend(self.delegate.queue.get_nowait()) except queue.Empty: @@ -360,6 +365,22 @@ class BTLEUart(io.RawIOBase): def readall(self) -> bytes: return self._read() + def read( + self, size: Optional[int] = None, timeout: Optional[float] = None + ) -> Optional[bytes]: + if timeout: + _timeout = self.timeout + self.timeout = timeout + + if size is None: + res = super().read() + else: + res = super().read(size) + + if timeout: + self.timeout = _timeout + return res + def write(self, b: "ReadableBuffer") -> Optional[int]: self._ensure_connected() if TYPE_CHECKING: @@ -373,8 +394,9 @@ class BTLEUart(io.RawIOBase): def __enter__(self): return self - def __exit__(self): + def __exit__(self, type, value, traceback): self.device.disconnect() + del self.device def seekable(self) -> bool: return False @@ -403,8 +425,9 @@ def write(fh, data): fh.write(data + bcrc) -def construct_request(address, words=1): - return struct.pack("!BBHH", 0xFF, 0x03, address, words) +def construct_request(address, words=1, action=ACTION_READ, marker=0xFF): + assert marker in {POSSIBLE_MARKER}, f"marker should be one of {POSSIBLE_MARKER}" + return struct.pack("!BBHH", marker, action, address, words) def poll(dev: btle.Peripheral, timeout: float = 1) -> bool: diff --git a/test_bleuart.py b/test_bleuart.py index a8321a4..7af93d2 100644 --- a/test_bleuart.py +++ b/test_bleuart.py @@ -1,16 +1,17 @@ # -*- coding: utf-8 -*- from solar_ble import MAC, BTLEUart, construct_request, write -x = BTLEUart(MAC) +with BTLEUart(MAC, timeout=1) as x: -print(x) -write(x, construct_request(0x0C, 8)) + print(x) -print(x.read(3)) -print(x.read(8 * 2)) -print(x.read(2)) + write(x, construct_request(0x0E, words=3)) + x.read(3, timeout=1) + print(x.read(6, timeout=0.01)) + x.read(2, timeout=0.01) + print(x.timeout) -x.timeout = 10 + # x.timeout = 2 -print(x.read()) -print(x.read(1)) + # print(x.read()) + # print(x.read(1))