klightspeed / BrassMonkeyFridgeMonitor

Fridge monitor for Alpicool / Brass Monkey fridges
MIT License
5 stars 0 forks source link

Timeout error #4

Open DanClarke-io opened 1 month ago

DanClarke-io commented 1 month ago

I am getting a timeout error when putting in the MAC address of my fridge. I know it does work as I've partially built a script using this basic script:

import asyncio
import logging
from bleak import BleakScanner, BleakClient
from bleak.backends.characteristic import BleakGATTCharacteristic

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)

writeableFridgeUUID = "00001235-0000-1000-8000-00805f9b34fb" # Writable
readeableFridgeUUID = "00001236-0000-1000-8000-00805f9b34fb" # Read Notify
ping_command = bytearray([0xfe, 0xfe, 0x3, 0x1, 0x2, 0x0])
def notification_handler(characteristic: BleakGATTCharacteristic, data: bytearray):
    """Simple notification handler which prints the data received."""
    logger.info("%s: %r", characteristic.description, data)
    logger.info("%s: %r", characteristic.description, data.decode('utf-16'))
    logger.info(decode_fridge_data(data))

async def main():
    while True:
     devices = await BleakScanner.discover()
     for d in devices:
          logger.info(d)
          if d.address=="ED:67:39:CE:17:7A": #Found Fridge
            # logger.info(d.metadata)
            client = BleakClient(d.address)
            async with BleakClient(d, timeout=100) as client:
                # paired = await client.pair(protection_level=2)
                logger.info(f"Paired")
                for service in client.services:
                    logger.info("[Service] {0}: {1}".format(service.uuid, service.description))
                    for char in service.characteristics:
                        logger.info("\t[Characteristic] {0}: ({1}) | Name: {2}".format(char.uuid, ",".join(char.properties), char.description))
                logging.info("Sending ping command")
                await client.write_gatt_char(writeableFridgeUUID, ping_command)
                logging.info("Starting notifications")
                await client.start_notify(readeableFridgeUUID, notification_handler)
                await asyncio.sleep(30.0)
                await client.stop_notify(readeableFridgeUUID)

I get an output of:

INFO:__main__:ED:67:39:CE:17:7A: A1-ED6739CE177A
INFO:__main__:Paired
INFO:__main__:[Service] 00001234-0000-1000-8000-00805f9b34fb: Vendor specific
INFO:__main__:  [Characteristic] 00001235-0000-1000-8000-00805f9b34fb: (write) | Name: Vendor specific
INFO:__main__:  [Characteristic] 00001236-0000-1000-8000-00805f9b34fb: (read,notify) | Name: Vendor specific
INFO:__main__:  [Characteristic] 0000fff1-0000-1000-8000-00805f9b34fb: (write,notify) | Name: Vendor specific
INFO:__main__:[Service] 0000180a-0000-1000-8000-00805f9b34fb: Device Information
INFO:__main__:  [Characteristic] 00002a29-0000-1000-8000-00805f9b34fb: (read) | Name: Manufacturer Name String
INFO:__main__:  [Characteristic] 00002a26-0000-1000-8000-00805f9b34fb: (read) | Name: Firmware Revision String
INFO:__main__:  [Characteristic] 00002a28-0000-1000-8000-00805f9b34fb: (read) | Name: Software Revision String
INFO:root:Sending ping command
INFO:root:Starting notifications
INFO:__main__:bytearray(b'\xfe\xfe!\x01\x00\x01\x00\x02\x05\x08\x00\x02\x00\x00\x00\x00\x01\x00\x05d')

This is the output I get from your script, I just wish I could get it to not time out!

 ✘ ⚡ root@journey-control  /opt/BrassMonkeyFridgeMonitor   main ●  python3 fridge.py ED:67:39:CE:17:7A
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/bleak/backends/bluezdbus/client.py", line 214, in connect
    reply = await self._bus.call(
  File "/usr/local/lib/python3.9/dist-packages/dbus_fast/aio/message_bus.py", line 385, in call
    await future
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 556, in <module>
    main()
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 550, in main
    asyncio.run(run(args.address, args.bind, args.loop, args.pollinterval))
  File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 494, in run
    async with Fridge(addr) as fridge:
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 348, in __aenter__
    await self.connect()
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 316, in connect
    await self.client.connect(Timeout=100)
  File "/usr/local/lib/python3.9/dist-packages/bleak/__init__.py", line 615, in connect
    return await self._backend.connect(**kwargs)
  File "/usr/local/lib/python3.9/dist-packages/bleak/backends/bluezdbus/client.py", line 315, in connect
    raise
  File "/usr/local/lib/python3.9/dist-packages/async_timeout/__init__.py", line 141, in __aexit__
    self._do_exit(exc_type)
  File "/usr/local/lib/python3.9/dist-packages/async_timeout/__init__.py", line 228, in _do_exit
    raise asyncio.TimeoutError
asyncio.exceptions.TimeoutError
klightspeed commented 1 month ago

Perhaps I should move from the implicit BleakScanner.discover() in client.connect() to an explicit BleakScanner.discover() in run(), passing the BLEDevice into the Fridge constructor?

klightspeed commented 1 month ago

fridge.py has been updated to use BleakScanner.find_device_by_address(), which should reduce the likelihood of getting a timeout connecting to the device.

DanClarke-io commented 1 month ago

Thanks for your quick replies @klightspeed, unfortunately we are still facing the same issue.. I'm trying to merge the decoding function of your repo into the python code I've worked on, i'll keep you posted!

Here is the response I get now:

✘ ⚡ root@journey-control  /opt/BrassMonkeyFridgeMonitor   main  python3 fridge.py ED:67:39:CE:17:7A
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/bleak/backends/bluezdbus/client.py", line 214, in connect
    reply = await self._bus.call(
  File "/usr/local/lib/python3.9/dist-packages/dbus_fast/aio/message_bus.py", line 385, in call
    await future
asyncio.exceptions.CancelledError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 563, in <module>
    main()
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 557, in main
    asyncio.run(run(args.address, args.bind, args.loop, args.pollinterval))
  File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 501, in run
    async with Fridge(fridge_dev) as fridge:
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 346, in __aenter__
    await self.connect()
  File "/opt/BrassMonkeyFridgeMonitor/fridge.py", line 316, in connect
    await self.client.connect()
  File "/usr/local/lib/python3.9/dist-packages/bleak/__init__.py", line 615, in connect
    return await self._backend.connect(**kwargs)
  File "/usr/local/lib/python3.9/dist-packages/bleak/backends/bluezdbus/client.py", line 315, in connect
    raise
  File "/usr/local/lib/python3.9/dist-packages/async_timeout/__init__.py", line 141, in __aexit__
    self._do_exit(exc_type)
  File "/usr/local/lib/python3.9/dist-packages/async_timeout/__init__.py", line 228, in _do_exit
    raise asyncio.TimeoutError
asyncio.exceptions.TimeoutError

Running on a RPI4

Thanks again

klightspeed commented 1 month ago
async with BleakClient(d) as client:

BleakClient.__aenter__ internally calls connect, so apart from the multiple retries in fridge.py, there should be no functional difference.

You should be able to import fridge.py as a module, and use it at whatever depth you are wanting (whether using the raw decoding functions, or the Fridge class).