undera / pylgbst

Python library for LEGO® PoweredUp devices
MIT License
558 stars 121 forks source link

To bleak or not to bleak...? #134

Open HotDog702 opened 1 year ago

HotDog702 commented 1 year ago

Hello. I have a win10 system with anaconda installed. I have a rather simple code to test bleak connection (as demo.py does not work)

import time
import asyncio
from bleak import BleakScanner, BleakClient
import pylgbst

# address = "80:6F:B0:A4:83:59"  # Handset
# address = "90:84:2B:18:8D:71"  # HUB NO.4
address = "00:16:53:AF:A1:FF"  # MoveHub

# [Service] 00001801-0000-1000-8000-00805f9b34fb: Generic Attribute Profile
# [Service] 00001800-0000-1000-8000-00805f9b34fb: Generic Access Profile
LEGO_Hub_Service = '00001623-1212-efde-1623-785feabcd123'
LEGO_Hub_Characteristic = '00001624-1212-efde-1623-785feabcd123'

async def main1(address):
    async with BleakClient(address) as client:
        print("Connected: {0}".format(client.is_connected))
        # await client.write_gatt_char(LEGO_Hub_Characteristic, bytearray([0x05, 0x00, 0x01, 0x01, 0x05]))
        for service in client.services:
            print("[Service] {0}: {1}".format(service.uuid, service.description))
            for char in service.characteristics:
                if "read" in char.properties:
                    try:
                        value = bytes(await client.read_gatt_char(char.uuid))
                    except Exception as e:
                        value = str(e).encode()
                else:
                    value = None
                print(
                    "\t[Characteristic] {0}: (Handle: {1}) ({2}) | Name: {3}, Value: {4} ".format(
                        char.uuid,
                        char.handle,
                        ",".join(char.properties),
                        char.description,
                        value,
                    )
                )
                print("Connected: {0}".format(client.is_connected))
                if False:  #char.uuid == LEGO_Hub_Characteristic:
                    print(f'\t\t{len(char.descriptors)} descriptor(s) found')
                    print("Connected: {0}".format(client.is_connected))
                    for descriptor in char.descriptors:
                        print(
                            "\t\t[Descriptor] {0}: (Handle: {1})".format(
                                descriptor.uuid, descriptor.handle)
                            )
                        # value = await client.read_gatt_descriptor(descriptor.handle)
                        # print(
                        #     "\t\t[Descriptor] {0}: (Handle: {1}) | Value: {2} ".format(
                        #         descriptor.uuid, descriptor.handle, bytes(value)
                        #     )
                        # )
asyncio.run(main1(address))

The problem is that with this code I can connect and read characteristics from Handset and SmartHub, but not MoveHub. MoveHub allows to read services, but reading characteristics returns "not connected" value:

[Characteristic] 00002a04-0000-1000-8000-00805f9b34fb: (Handle: 10) (read) | Name: Peripheral Preferred Connection Parameters, Value: b'Not connected'

So, trying to further read descriptors raises an exception, as MoveHub really breaks the connection. Any ideas, why this happens and how to fix?

P.S. I've bought BlueGiga dongle, with it demo.py works

maieuticus commented 1 year ago

i tried your code with my MoveHub and got this result:

Connected: True [Service] 00001801-0000-1000-8000-00805f9b34fb: Generic Attribute Profile [Characteristic] 00002a05-0000-1000-8000-00805f9b34fb: (Handle: 2) (indicate) | Name: Service Changed, Value: None Connected: True [Service] 00001800-0000-1000-8000-00805f9b34fb: Generic Access Profile [Characteristic] 00002a00-0000-1000-8000-00805f9b34fb: (Handle: 6) (read,write-without-response,write,authenticated-signed-writes) | Name: Device Name, Value: b'LEGO Bootloader' Connected: True [Characteristic] 00002a01-0000-1000-8000-00805f9b34fb: (Handle: 8) (read,write-without-response,write,authenticated-signed-writes) | Name: Appearance, Value: b'\x00\x00' Connected: True [Characteristic] 00002a04-0000-1000-8000-00805f9b34fb: (Handle: 10) (read) | Name: Peripheral Preferred Connection Parameters, Value: b'\xff\xff\xff\xff\x00\x00\xff\xff' Connected: True [Service] 00001625-1212-efde-1623-785feabcd123: LEGO Wireless Protocol v3 Bootloader Service [Characteristic] 00001626-1212-efde-1623-785feabcd123: (Handle: 13) (read,write-without-response,write,notify) | Name: LEGO Wireless Protocol v3 Bootloader Characteristic, Value: b'\x04\x00\x05\x02\x05' Connected: True

HotDog702 commented 1 year ago

Hmm... In my case it returns Connected=False after first Characteristic. Do you use win10 or Linux? May be something wrong with my BT driver, but how to be sure? It works with Train hub...

maieuticus commented 1 year ago

I am using win10 without anaconda.

  1. Created an .venv
  2. pip install -U pylgbst[bleak]
  3. modified your code with my MoveHub-Address and run it

PS: Im new in GitHub and i am in the learningPhase of developing things. So i hope, i can help you with my feedback. But could you help me with a short example in addition to your code, to run one motor of the MoveHub?

Because the demo.py and the code below dosn't work for me:

from pylgbst.hub import MoveHub

hub = MoveHub()
hub.motor_A.timed(0.5, 0.8)