ukBaz / python-bluezero

A simple Python interface to Bluez
MIT License
395 stars 112 forks source link

Error "bad combination of inputs: found nothing" #209

Closed ukBaz closed 5 years ago

ukBaz commented 5 years ago

Originally posted by @stingwraith in https://github.com/ukBaz/python-bluezero/issues/208#issuecomment-471118053

Is this what is leading to the error "bad combination of inputs: found nothing" ?

ukBaz commented 5 years ago

Hi @stingwraith,

I have moved this to it's own issue because I would like #208 to cover known API changes only.

You will need to give me a little more context for me to answer this with any degree of confidence.

However, this error is raised at the following location in the code: https://github.com/ukBaz/python-bluezero/blob/ff538103c94026ccc5479eaaea3270c08c573ca5/bluezero/dbus_tools.py#L119-L120

This is normally raised when you have given a bad combination of adapter address, device address, service UUID, and/or characteristic UUID

This can be tested with the get_dbus_path function: https://github.com/ukBaz/python-bluezero/blob/ff538103c94026ccc5479eaaea3270c08c573ca5/bluezero/dbus_tools.py#L130-L134

For example

$ python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from bluezero import dbus_tools     
>>> dbus_tools.get_dbus_path('B8:27:EB:22:57:E0')
dbus.ObjectPath('/org/bluez/hci0')
>>> dbus_tools.get_dbus_path('B8:27:EB:22:57:E0', 'FD:6B:11:CD:4A:9B')
dbus.ObjectPath('/org/bluez/hci0/dev_FD_6B_11_CD_4A_9B')

If I put in an adapter address that is not found it will return nothing

>>> dbus_tools.get_dbus_path('AA:AA:AA:AA:AA:AA')
>>> 

If I use a bad address for the adapter it will error out when it gets to trying to find the path for the device address

>>> dbus_tools.get_dbus_path('AA:AA:AA:AA:AA:AA', 'FD:6B:11:CD:4A:9B')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/python/python-bluezero/bluezero/dbus_tools.py", line 164, in get_dbus_path
    device)
  File "/home/pi/python/python-bluezero/bluezero/dbus_tools.py", line 120, in _get_dbus_path2
    raise ValueError('Bad combination of inputs: found nothing')
ValueError: Bad combination of inputs: found nothing
>>> 

So my suggestion would be that check the addresses and UUIDs you are using. Let me know if that helps.

stingwraith commented 5 years ago

Oh my, Thanks for such an informative response, it is very much appreciated! I am getting the addresses from bluetoothctl as follows:

        Controller XX:XX:YY:XX:ZZ:XX
        Name: chip
        Alias: chip
        Class: 0x000000
        Powered: yes
        Discoverable: no
        Pairable: yes
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v1D6Bp0246d052B
        Discovering: no
[bluetooth]# devices
Device XX:XX:YY:XX:ZZ:XX BBC micro:bit [votet]
[bluetooth]#

Then I simply copied and pasted those addresses into the following script:

import time
from bluezero import microbit
ubit = microbit.Microbit(adapter_addr='38:A2:8C:65:70:E9',
                         device_addr='C9:9C:3F:13:1F:D4')
ubit.connect()
while ubit.button_a < 1:
    ubit.pixels = [0b00000, 0b01000, 0b11111, 0b01000, 0b00000]
    time.sleep(0.5)
    ubit.clear_display()
while ubit.button_b < 1:
    ubit.pixels = [0b00000, 0b00010, 0b11111, 0b00010, 0b00000]
    time.sleep(0.5)
    ubit.clear_display()
ubit.disconnect()

This setup is what's resulting in the error. Any more insight would again be greatly appreciated! thanks

EDIT: I've tried reinstalling bluezero with pip and pip3, tried running with different versions of python, still no luck. The weirdest part is that the Microbit is showing that Bluetooth is properly connected.

Also here is the actual error I am getting in case there's something pertinent in there:

Traceback (most recent call last):
  File "bt.py", line 4, in <module>
    ubit.connect()
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/microbit.py", line 134, in connect
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/central.py", line 84, in connect
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/central.py", line 60, in load_gatt
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/GATT.py", line 125, in resolve_gatt
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/dbus_tools.py", line 279, in get_methods
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/dbus_tools.py", line 178, in get_dbus_path
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/dbus_tools.py", line 120, in _get_dbus_path2
ValueError: Bad combination of inputs: found nothing
chip@chip:~/btmicrobit$
ukBaz commented 5 years ago

Ah! thanks for posting more details....that looks like the example from https://github.com/ukBaz/python-bluezero/blob/master/examples/microbit_poll.py

I suspect the issue here is that the Bluetooth services on the micro:bit don't match the services Bluezero is looking for. Where did the micro:bit hex come from? Or maybe more importantly, do you know what services are on it. The good news is that the latest Bluezero release (v0.1.0) there is an update to microbit.Microbit that allows you to select which services are active.

Have you seen the micro:bit workshop? This should help get you going. https://ukbaz.github.io/howto/ubit_workshop.html

If that doesn't help, then let me know what services are on the micro:bit and I'll give more guidance.

stingwraith commented 5 years ago

That guide is what I followed to get where I am. I made a hex file using makecode very similar to the one outlined on the guide(ie:. On bt connected show 'C' with LED's, on disconnected show 'D'. ) The only services I left running for bt is button, led, and pin services as that's all I need for testing. I can pastebin the hex or link a screenshot of my makecode if that'll help.

EDIT: Here you go: https://imgur.com/a/6enyHAC

ukBaz commented 5 years ago

Great, that helps.

You need to specify just those three services as available on the micro:bit.

Your code should look something like:

import time
from bluezero import microbit
ubit = microbit.Microbit(adapter_addr='38:A2:8C:65:70:E9',
                         device_addr='C9:9C:3F:13:1F:D4',
                         accelerometer_service=False,
                         button_service=True,
                         led_service=True,
                         magnetometer_service=False,
                         pin_service=True,
                         temperature_service=False)
ubit.connect()
while ubit.button_a < 1:
    ubit.pixels = [0b00000, 0b01000, 0b11111, 0b01000, 0b00000]
    time.sleep(0.5)
    ubit.clear_display()
while ubit.button_b < 1:
    ubit.pixels = [0b00000, 0b00010, 0b11111, 0b00010, 0b00000]
    time.sleep(0.5)
    ubit.clear_display()
ubit.disconnect()
stingwraith commented 5 years ago

Well, so now I've matched them up and it's throwing this error:

Traceback (most recent call last):
  File "bt.py", line 11, in <module>
    ubit.connect()
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/microbit.py", line 134, in connect
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/central.py", line 84, in connect
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/central.py", line 60, in load_gatt
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/GATT.py", line 125, in resolve_gatt
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/dbus_tools.py", line 287, in get_methods
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/dbus_tools.py", line 86, in get_dbus_obj
  File "/usr/lib/python3/dist-packages/dbus/bus.py", line 241, in get_object
    follow_name_owner_changes=follow_name_owner_changes)
  File "/usr/lib/python3/dist-packages/dbus/proxies.py", line 244, in __init__
    _dbus_bindings.validate_object_path(object_path)
TypeError: must be str, not None
ukBaz commented 5 years ago

The only way that I can reproduce this is if I don't pair the micro:bit and the Raspberry Pi. Have you paired the micro:bit about your Linux machine?

There is a section headed Pair with micro:bit that should have the information you need. The other option is to turn off the need for pair in Makecode.

stingwraith commented 5 years ago

As soon as I enable the bluetooth library on makecode I can no loner put the Microbit into pairing mode with A+B method, it just starts and runs the hex file. It just seems to always be able to be paired with. I've removed and paired it numerous times with bluetoothctl, ensuring to scan for correct address. The Microbit LED's show 'C' to indicate it is connected and paired but still getting that error...? Is it possible I need to reinstall something dbus related?

EDIT: I've tried the justworks and no pairing methods and neither will let me put it into pairing mode, just always pairs without issue.

ukBaz commented 5 years ago

As soon as I enable the bluetooth library on makecode I can no loner put the Microbit into pairing mode with A+B method, it just starts and runs the hex file. It just seems to always be able to be paired with.

This doesn't sound right. I'm missing something here.

There is some good information over on the Bitty Software website that might give you a clue that I am missing: http://www.bittysoftware.com/troubleshooting.html http://www.bittysoftware.com/Bluetooth_le_intro.html

Can you please do uname -a and post the result of that.

When you delete the devices in bluetoothctl, I would suggest you also do a: $ sudo service bluetooth restart

Having the result of: version, paired-devices, info <device-address> might be helpful also. Here is an example of what I get:

$ uname -a
Linux raspberrypi 4.14.79-v7+ #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l GNU/Linux

In Bluetoothctl:

[bluetooth]# version
Version 5.43
[bluetooth]# paired-devices 
Device F1:55:90:65:29:DC BBC micro:bit [zetuz]
[bluetooth]# info F1:55:90:65:29:DC 
Device F1:55:90:65:29:DC
    Name: BBC micro:bit
    Alias: BBC micro:bit
    Appearance: 0x0200
    Paired: yes
    Trusted: no
    Blocked: no
    Connected: no
    LegacyPairing: no
    UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
    UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
    UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
    UUID: Vendor specific           (e95d127b-251d-470a-a062-fa1922dfa9a8)
    UUID: Vendor specific           (e95d93af-251d-470a-a062-fa1922dfa9a8)
    UUID: Vendor specific           (e95d93b0-251d-470a-a062-fa1922dfa9a8)
    UUID: Vendor specific           (e95d9882-251d-470a-a062-fa1922dfa9a8)
    UUID: Vendor specific           (e95dd91d-251d-470a-a062-fa1922dfa9a8)
    UUID: Vendor specific           (e97dd91d-251d-470a-a062-fa1922dfa9a8)
stingwraith commented 5 years ago
uname -a
Linux chip 4.4.13-ntc-mlc #1 SMP Tue Dec 6 21:38:00 UTC 2016 armv7l GNU/Linux

[BBC micro:bit [votet]]# version
Version 5.43
[BBC micro:bit [votet]]# paired-devices
Device C9:9C:3F:13:1F:D4 BBC micro:bit [votet]
[BBC micro:bit [votet]]# info C9:9C:3F:13:1F:D4
Device C9:9C:3F:13:1F:D4
        Name: BBC micro:bit [votet]
        Alias: BBC micro:bit [votet]
        Appearance: 0x0200
        Paired: yes
        Trusted: no
        Blocked: no
        Connected: yes
        LegacyPairing: no
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
        UUID: Vendor specific           (e95d0753-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e95d127b-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e95d6100-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e95d93af-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e95d93b0-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e95d9882-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e95dd91d-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e95df2d8-251d-470a-a062-fa1922dfa9a8)
        UUID: Vendor specific           (e97dd91d-251d-470a-a062-fa1922dfa9a8)
[BBC micro:bit [votet]]#

I also tried restarting Bluetooth service at several point to no avail.

ukBaz commented 5 years ago

OK, I think that might have given me a clue.
What you are showing here does not match the makecode picture you shared earlier. 1800, 1801 and 180a will always be there. 0753 Accelerometer service is not needed for your above example so remove it. 127b IO Pin service is not needed for your above example so remove it. 6100 Temperature service is not needed for your above example so remove it. 93af Is the event service and Makecode puts this in by default 93b0 Is the DFU control service and Makecode puts this in by default 9882 is the button service and you need that d91d is the led service and you need that f2d8 magnetometer servce is not needed for your above example so remove it

When you have that many Bluetooth services running on the micro:bit it runs out of memory. The latter services never get started. If you look at the mirco:bit with the nRF connect app (or something similar) it is likely you will see those later services aren't formed correctly.

Run with the minimum number of services and see if that improves things.

stingwraith commented 5 years ago

IMG_20190309_162856 IMG_20190309_162940

After setting it like this I am back to the original error of bad combination of inputs:/

ukBaz commented 5 years ago

For legacy reasons some of the services are on by default. You need to specify all of the services that Bluezero supports and say if they are on or off. Not ideal maybe but that is where the library is at the moment. You need to follow the example below:

import time
from bluezero import microbit
ubit = microbit.Microbit(adapter_addr='38:A2:8C:65:70:E9',
                         device_addr='C9:9C:3F:13:1F:D4',
                         accelerometer_service=False,
                         button_service=True,
                         led_service=True,
                         magnetometer_service=False,
                         pin_service=False,
                         temperature_service=False)
ubit.connect()
while ubit.button_a < 1:
    ubit.pixels = [0b00000, 0b01000, 0b11111, 0b01000, 0b00000]
    time.sleep(0.5)
    ubit.clear_display()
while ubit.button_b < 1:
    ubit.pixels = [0b00000, 0b00010, 0b11111, 0b00010, 0b00000]
    time.sleep(0.5)
    ubit.clear_display()
ubit.disconnect()
stingwraith commented 5 years ago

Okay so that seems to have worked, somewhat...

I'm now facing this error:

Traceback (most recent call last):
  File "async_example.py", line 36, in <module>
    cmdr.connect()
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/microbit.py", line 819, in connect
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/microbit.py", line 837, in _config_pins
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/microbit.py", line 369, in set_pin
  File "/usr/local/lib/python3.4/dist-packages/bluezero-0.1.0-py3.4.egg/bluezero/microbit.py", line 399, in _pin_config
AttributeError: 'Microbit' object has no attribute '_io_pin_config'
chip@chip:~/btmicrobit/python-bluezero/examples$
ukBaz commented 5 years ago

OK, good that you got the previous example working.

It looks like you have moved on to a new example. You seem to have hit the issue I opened yesterday #210. If you are using a bit:commander from 4tronix you will need to update https://github.com/ukBaz/python-bluezero/blob/2512460f1988e13fa4b5bc1497178872370c8230/bluezero/microbit.py#L799 to properly configure the micro:bits services. Does that make sense?

If you get it working, feel free to do a pull request. If you do not, I will try to get to this over the next few days.

stingwraith commented 5 years ago

I'm not using a bit:commander... At this point I'm simply trying to have the pin information read by the chip, triggering a bash script on the chip. I couldn't locate an example script to do this with the default microbit pins.

ukBaz commented 5 years ago

You might find it easier to modify your previous example than use the async example.

You will need to configure the pin by specifying if you want it to read analogue or digital values. More information at: https://bluezero.readthedocs.io/en/stable/level1.html#bluezero.microbit.Microbit.set_pin As an example, to read analogue values on pin 2:

ubit.set_pin(2, True, True)

Then it is the pin_values property on the micro:bit that will give you the value. More information at: https://bluezero.readthedocs.io/en/stable/level1.html#bluezero.microbit.Microbit.pin_values There is an error in the docs, it should say

configured as input

not output As an example, to access the value of pin 2:

values = ubit.pin_values
p2_value = values['2']

If you share your code I am happy to review it.

stingwraith commented 5 years ago

I believe I've finally got it working:) Thanks so much for all your help!!

ukBaz commented 5 years ago

Good news! Enjoy!