Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using a standard format for args passed to callback functions #301

Closed
Bernstern opened this issue Sep 21, 2020 · 4 comments · Fixed by #334
Closed

Using a standard format for args passed to callback functions #301

Bernstern opened this issue Sep 21, 2020 · 4 comments · Fixed by #334
Labels
Backend: BlueZ Issues and PRs relating to the BlueZ backend Backend: Core Bluetooth Issues and PRs relating to the Core Bluetooth backend Backend: pythonnet Issues or PRs relating to the .NET/pythonnet backend enhancement New feature or request

Comments

@Bernstern
Copy link
Contributor

  • bleak version: v0.8.0
  • Python version: v3.8.5
  • Operating System: macOS Catalina v10.15.6
  • BlueZ version (bluetoothctl -v) in case of Linux: N/A
  • Apple Bluetooth Software Version: 7.0.6f7

Description

Using the register_detection_callback() function to handle discovery of devices for a service, tested so far on macOS and Linux, raises the possible issue that the callback is sent different arguments depending on what backend of Bleak is being used:

CoreBluetooth

def callback(p, a, r):
    self._identifiers[p.identifier()] = a
    if self._callback:
        self._callback(p, a, r)

BluezDbus

if self._callback is not None:
    self._callback(message)

DotNet

if self._callback is not None:
      self._callback(sender, e)

Would it make sense in the bleak roadmap to use a standardized json or dictionary structure that would be passed to the callback function with all the pertinent data to avoid having to breakdown the *args depending on what platform is used to improve the platform-agnostic-ity of Bleak? If so, I'm happy to help implement the feature.

What I Did

N/A

@dlech
Copy link
Collaborator

dlech commented Sep 21, 2020

Yes, this is something I have been meaning to do. Feel free to have a go at it.

@hbldh hbldh added Backend: pythonnet Issues or PRs relating to the .NET/pythonnet backend Backend: BlueZ Issues and PRs relating to the BlueZ backend Backend: Core Bluetooth Issues and PRs relating to the Core Bluetooth backend enhancement New feature or request labels Sep 25, 2020
@hbldh
Copy link
Owner

hbldh commented Sep 25, 2020

I am not sure there is so much to do here except harmonize the number of input arguments to be equal across platforms, i.e. send all arguments as a tuple instead...

If you want to do something with the scanning results, you need do engage with the OS specific components sent in to the callback. I have no idea how to make a "standardized" container for that and not run into another plethora of problems...

The best I can think of is something like

import platform

def detection_callback(*args):
    if platform.system() == "Windows":
        # Windows specific code
    elif platform.system() == "Darwin":
         # and so forth

or by defining different callbacks depending on platform. It is safer to leave this to the user and document it better in #266 IMO.

@Bernstern
Copy link
Contributor Author

One approach would be combining the two implementations by standardizing the argument length to a tuple of length four as well as passing a dictionary of useful fields. That way a user would have the choice of a platform specific approach as you did above, or by using the dictionary.

I have an implementation right now that returns a dict with this format as the fourth item in the tuple passed to the callback across all platforms with this structure:

{
    'address': 'stub',
    'data_channel': 1,
    'manufacturer_data': {1: [1, 0, ..., 4]},
    'name': 'name',
    'rssi': 1,
    'service_data': [],
    'service_uuid': 'stub
}

In internal use, being able to create a BleDevice object with the callback the same way on every platform has helped clean up our code a lot just from getting back the address and the bulk of it's metadata from the callback.

I'm more than happy to make any changes you'd like to see, stabilize it and update the docs to reflect the changes if this is an approach you like.

@dlech
Copy link
Collaborator

dlech commented Oct 8, 2020

I like this, but would suggest inverting it. Just pass the dictionary and make the platform-specific tuple one of the dictionary entries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backend: BlueZ Issues and PRs relating to the BlueZ backend Backend: Core Bluetooth Issues and PRs relating to the Core Bluetooth backend Backend: pythonnet Issues or PRs relating to the .NET/pythonnet backend enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants