Bladeren bron

close ble connection between requests

subDesTagesMitExtraKaese 1 maand geleden
bovenliggende
commit
de96b439de
2 gewijzigde bestanden met toevoegingen van 51 en 39 verwijderingen
  1. 49 38
      main.py
  2. 2 1
      src/bleclient.py

+ 49 - 38
main.py

@@ -16,56 +16,67 @@ from src.variables import variables, VariableContainer, battery_and_load_paramet
 request_interval = 20   # In seconds
 reconnect_interval = 5  # In seconds
 
-async def request_and_publish_details(sensor: MqttSensor, mppt: BleClient) -> None:
-    details = await mppt.request_details()
-    if details:
-        print(f"Battery: {details['battery_percentage'].value}% ({details['battery_voltage'].value}V)")
-        await sensor.publish(details)
-    else:
-        print("No values recieved")
+ble_lock = asyncio.Lock()
+
+async def request_and_publish_details(sensor: MqttSensor, address: str) -> None:
+    async with ble_lock:
+        try:
+            async with BleClient(address) as mppt:
+                details = await mppt.request_details()
+                if details:
+                    print(f"Battery: {details['battery_percentage'].value}% ({details['battery_voltage'].value}V)")
+                    await sensor.publish(details)
+                else:
+                    print("No values recieved")
+        except (EOFError, BleakError, asyncio.TimeoutError) as e:
+            print(f"Got {type(e).__name__} while fetching details: {e}")
+
+async def request_and_publish_parameters(sensor: MqttSensor, address: str) -> None:
+    async with ble_lock:
+        async with BleClient(address) as mppt:
+            parameters = await mppt.request_parameters()
+            if parameters:
+                await sensor.publish(parameters)
 
-async def subscribe_and_watch(sensor: MqttSensor, mppt: BleClient):
+async def subscribe_and_watch(sensor: MqttSensor, address: str):
     parameters = battery_and_load_parameters[:12] + switches
     await sensor.subscribe(parameters)
     await sensor.store_config(switches)
+
     while True:
         command = await sensor.get_command()
         print(f"Received command to set {command.name} to '{command.value}'")
-        results = await mppt.write([command])
-        await sensor.publish(results)
+        async with ble_lock:
+            try:
+                async with BleClient(address) as mppt:
+                    results = await mppt.write([command])
+                    await sensor.publish(results)
+            except (BleakError, asyncio.TimeoutError) as e:
+                print(f"Get {type(e).__name__} while writing command: {e}")
+
 
 async def run_mppt(sensor: MqttSensor, address: str):
-    task = None
     loop = asyncio.get_event_loop()
+    task = loop.create_task(subscribe_and_watch(sensor, address))
+
     try:
-        async with BleClient(address) as mppt:
-            task = loop.create_task(subscribe_and_watch(sensor, mppt))
-            parameters = await mppt.request_parameters()
-            await sensor.publish(parameters)
-            while True:
-                await request_and_publish_details(sensor, mppt)
-                await asyncio.sleep(request_interval)
-                if not task.cancelled() and task.exception:
-                    break
-    except EOFError:
-        pass
-    except asyncio.TimeoutError:
-        print("BLE communication timed out")
-        return
-    except BleakDeviceNotFoundError:
-        print(f"BLE device with address {address} was not found")
-        return
-    except BleakError as e:
-        print(f"BLE error occurred: {e}")
-        return
+        await request_and_publish_parameters(sensor, address)
+        while True:
+            await request_and_publish_details(sensor, address)
+            await asyncio.sleep(request_interval)
+            if task.done() and task.exception():
+                break
+    except (EOFError, asyncio.TimeoutError, BleakDeviceNotFoundError, BleakError) as e:
+        print(f"{type(e).__name__} occurred: {e}")
     finally:
-        if task:
-            task.cancel()
-            try:
-                await task
-            except asyncio.CancelledError:
-                pass
-    print("BLE device disconnected")
+        task.cancel()
+        try:
+            await task
+        except asyncio.CancelledError:
+            pass
+
+    print("BLE session ended.")
+
 
 async def run_mqtt(address, host, port, username, password):
     while True:

+ 2 - 1
src/bleclient.py

@@ -17,6 +17,7 @@ class BleClient(LumiaxClient):
         self.client = BleakClient(mac_address)
         self.response_queue = asyncio.Queue()
         self.lock = asyncio.Lock()
+        super().__init__()
 
     async def __aenter__(self):
         await self.client.connect()  # Connect to the BLE device
@@ -40,7 +41,7 @@ class BleClient(LumiaxClient):
             print(f"Response from device: 0x{self.buffer.hex()}")
             print(f"Error while parsing response: {e}")
 
-    async def read(self, start_address: int, count: int, repeat = 10, timeout = 5) -> ResultContainer:
+    async def read(self, start_address: int, count: int, repeat = 10, timeout = 2) -> ResultContainer:
         async with self.lock:
             self.start_address = start_address
             command = self.get_read_command(0xFE, start_address, count)