Jump to content

Bluetooth Controller


Recommended Posts

Hi,

 

I was a bit tired of handling all my bluetooth devices manually, and couldn't find any cover-all bluetooth workflows out there, so I made this one.

 

alfredbluetooth.gif

 

Features:

  • Turn on/off/toggle bluetooth
  • Connect to device from list of paired bluetooth devices
  • Set favorite device for quick access
  • User friendly notifications for all actions

 

Dependencies (see README on git repo):

  • Blueutil
  • Python3

 

Feel free to give me feedback, and report bugs if you find any.

 

Githubhttps://github.com/vegardinho/alfred_bluetooth_controller

Download: https://github.com/vegardinho/alfred_bluetooth_controller/releases/latest

 

Cheers,

Vegard

Edited by vegardinho
Edited link to release
Link to post

Hi,

 

This looks like a workflow that I'll get a lot of use out of. I'm having a bit of trouble with it, though. Specifically when I use btd + devicename, or try to configure btsetfavorite, it only gives me the option to search Google for "btd devicename" etc. 

 

I tried following your instructions to install blueutil and python, so I don't think the problem is there. 

 

I'm using all the latest stable versions of all software on an MBP, if that matters.

Link to post
Posted (edited)
6 hours ago, sr_navarre said:

Hi,

 

This looks like a workflow that I'll get a lot of use out of. I'm having a bit of trouble with it, though. Specifically when I use btd + devicename, or try to configure btsetfavorite, it only gives me the option to search Google for "btd devicename" etc. 

 

I tried following your instructions to install blueutil and python, so I don't think the problem is there. 

 

I'm using all the latest stable versions of all software on an MBP, if that matters.

Hi,

 

Glad to hear the workflow is useful!

 

Can you make sure you are typing the same thing as in the gif above? The format should be "btd", then space, followed by whatever device you are searching for. Just typing "btd" should give you a list of all the previously paired bluetooth devices.

 

Also keep in mind that currently only results that are exact matches from the start of the word, are matched. That means "device" will not match the device "mydevice", but "mydev" will. I am working on changing this, but currently this is a limitation to the workflow you have to account for. 

Update: The newest release now includes smart search, i.e. it matches ever item where every search argument is found in the device name ("device" will now match "mydevice"; so will "device 45" for hypothetical device "mydevice tx45")

 

If this doesn't help you: Could you run the workflow while in debug mode? Find the workflow in preferences, click the little spider on the top right, and then open the alfred search bar and type in what you would type to get the error. Copy whatever shows up in the debug text field, and paste it in the forum, so I can have a look at it.

 

I've also already killed a bug, so I recommend you download the new release anyway (though the fix it is not related to your problem).

 

Hope that helps!

 

Edited by vegardinho
Updated info from new release
Link to post

Thank you for getting back to me. I'm pasting the results from the debugger below. The first is from running btd, the second is btsetfavorite.

 

[21:51:52.387] Logging Started...

[21:52:01.294] Bluetooth Controller[Script Filter] Queuing argument '(null)'

[21:52:01.513] Bluetooth Controller[Script Filter] Script with argv '(null)' finished

[21:52:01.516] ERROR: Bluetooth Controller[Script Filter] Code 1: Traceback (most recent call last):

  File "./return_device_json.py", line 41, in <module>

    device['address'], device_name) + "},")

AttributeError: 'NoneType' object has no attribute 'lower'

___________________________________________________________________________________________________

[21:52:40.137] Bluetooth Controller[Script Filter] Queuing argument '(null)'

[21:52:40.320] Bluetooth Controller[Script Filter] Script with argv '(null)' finished

[21:52:40.322] ERROR: Bluetooth Controller[Script Filter] Code 1: Traceback (most recent call last):

  File "./return_device_json.py", line 41, in <module>

    device['address'], device_name) + "},")

AttributeError: 'NoneType' object has no attribute 'lower'

Link to post
Posted (edited)
7 hours ago, sr_navarre said:

Thank you for getting back to me. I'm pasting the results from the debugger below. The first is from running btd, the second is btsetfavorite.

 

[21:51:52.387] Logging Started...

[21:52:01.294] Bluetooth Controller[Script Filter] Queuing argument '(null)'

[21:52:01.513] Bluetooth Controller[Script Filter] Script with argv '(null)' finished

[21:52:01.516] ERROR: Bluetooth Controller[Script Filter] Code 1: Traceback (most recent call last):

  File "./return_device_json.py", line 41, in <module>

    device['address'], device_name) + "},")

AttributeError: 'NoneType' object has no attribute 'lower'

___________________________________________________________________________________________________

[21:52:40.137] Bluetooth Controller[Script Filter] Queuing argument '(null)'

[21:52:40.320] Bluetooth Controller[Script Filter] Script with argv '(null)' finished

[21:52:40.322] ERROR: Bluetooth Controller[Script Filter] Code 1: Traceback (most recent call last):

  File "./return_device_json.py", line 41, in <module>

    device['address'], device_name) + "},")

AttributeError: 'NoneType' object has no attribute 'lower'

 

It seems one of your devices has a non-existing name (type None), which is what causes the crash. I've now updated to check whether name actually exists before attempting to call any actions on it. Version 1.2.2 (out now) should fix the problem for you.

 

I'm a little unsure why the device doesn't appear to have a name; you could try running "blueutil --paired --format json-pretty" (note: double dashes) manually, to see if you can spot something abnormal in the output.

Edited by vegardinho
Link to post

I have Blueutil and Python3 (running 'python3 --version' in terminal outputs 'Python 3.7.6') installed using Homebrew, but it does not work and the debugger reports: 

[17:17:30.841] ERROR: Bluetooth Controller[Script Filter] Code 127: /bin/bash: python3: command not found

I'm using version 1.2.2 of the workflow on Alfred 4.0.9 and macOS 10.14.6. Any tips how it may be fixed? 

Edited by cands
Link to post
5 hours ago, sr_navarre said:

It seems to work just fine now. Thanks! It's awesome when a developer is so responsive.

 

Great to hear it works! I guess time is one of the benefits of these corona times;)

Link to post
Posted (edited)
7 hours ago, cands said:

I have Blueutil and Python3 (running 'python3 --version' in terminal outputs 'Python 3.7.6') installed using Homebrew, but it does not work and the debugger reports: 


[17:17:30.841] ERROR: Bluetooth Controller[Script Filter] Code 127: /bin/bash: python3: command not found

I'm using version 1.2.2 of the workflow on Alfred 4.0.9 and macOS 10.14.6. Any tips how it may be fixed? 

 

It seems bash is not finding your Python3 interpreter, so it is probably located somewhere else than where mine is. I've added a fix to search for logical placement of python interpreter, so hopefully that does it (v.1.2.3).

 

If the fix doesn't work, make sure python3 is working (entering "python3" in terminal should suffice), as well as check where the interpreter lies ("which python"). You could also do a clean install of python3, I had a lot of different versions of python lying around, some by homebrew, and some old; and that eventually caused a lot of trouble, which was straightened out by the clean install.

Edited by vegardinho
Link to post
  • 1 month later...
On 3/24/2020 at 4:00 PM, vegardinho said:

 

It seems bash is not finding your Python3 interpreter, so it is probably located somewhere else than where mine is. I've added a fix to search for logical placement of python interpreter, so hopefully that does it (v.1.2.3).

 

If the fix doesn't work, make sure python3 is working (entering "python3" in terminal should suffice), as well as check where the interpreter lies ("which python"). You could also do a clean install of python3, I had a lot of different versions of python lying around, some by homebrew, and some old; and that eventually caused a lot of trouble, which was straightened out by the clean install.

 

I'm having the same issue as "cands". I've uninstalled and reinstalled python3, verified it's installed as well as the location `/usr/bin/python`, but I still get "ERROR: Bluetooth Controller[Script Filter] Code 127: env: python3: No such file or directory".

 

Any suggestions on what I can do to fix this?

 

Edit: I'm on v1.4.1 of the workflow.

Edited by Naters
Link to post
2 hours ago, Naters said:

`/usr/bin/python`

 

That's Python 2.

 

The workflow is only compatible with Catalina because it's the only version of macOS that has Python 3 installed by default.

 

If you want to run it on any other version, you’ll need to edit the workflow. You need to edit the Script Filter boxes and the script itself and change python3 or /usr/bin/env python3 to /usr/local/bin/python3.

 

Alternatively, you could just change python3 to python: The script also runs perfectly well on Python 2, which every version of macOS has.

 

On 3/25/2020 at 12:00 AM, vegardinho said:

If the fix doesn't work, make sure python3 is working (entering "python3" in terminal should suffice)

 

Not so, I’m afraid. Mac applications are run by launchd, not from your shell, so they don’t share the same environment. Specifically, /usr/local/bin isn’t on PATH, which is where python3 is when you install it via Homebrew.

 

As such, your instructions for installing Python 3 via Homebrew don’t actually work. You either need to edit every Script box and add export PATH=/usr/local/bin:$PATH at the top, or just change the script to use Python 2, which every version of macOS has. I realise it's essentially dead, but your workflow isn't going to be affected by any security problems that are found and not fixed, and Python 3 is an awfully large dependency for a 100-line Alfred workflow.

 

Also, why are you generating JSON by smushing strings together instead of using the actual json library? That's a marvellous way to create bugs.

Edited by deanishe
Link to post
41 minutes ago, deanishe said:

If you want to run it on any other version, you’ll need to edit the workflow. You need to edit the Script Filter boxes and the script itself and change python3 or /usr/bin/env python3 to /usr/local/bin/python3.

 

I made this change but now I'm getting the following error because a lot of my bluetooth devices contain a single quotation mark `'` e.g. "Nathan's Speaker". I'd prefer to not have to update the names on all of those devices, so I will most likely not use btd or btx, unless that can be fixed. 

Still, I appreciate the workflow and thanks for helping!

 

ERROR: Bluetooth Controller[Script Filter] Code 1: Traceback (most recent call last):
  File "./return_device_json.py", line 81, in <module>
    main()
  File "./return_device_json.py", line 19, in main
    open("devices.json", "w").write(text_json)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 111: ordinal not in range(128)

 

Link to post

To answer both of you: it's probably best that I change to python 2 by default in my script, and I'll do so as soon as I have the time. I went for python3 in the first place because of the problem you just encountered; it shouldn't be too bad to fix, but I'll have to take a look at it.

 

As for the json-smushing, I just assumed it would be faster, but you are probably right that it would be better to go for the json library. I may change this eventually, as well.

 

Some of these things are still a little new to me, so input is always appreciated.

 

Link to post
Posted (edited)
9 hours ago, vegardinho said:

I just assumed it would be faster

 

I couldn’t say for sure without testing, but there’ll be little difference. json, like a lot of Python libraries, is implemented in C, so it’s very fast. And it would make very, very little difference in a program this size.

 

9 hours ago, vegardinho said:

I went for python3 in the first place because of the problem you just encountered

 

The golden rule is "encode and decode at IO boundaries". The only thing you should actually need to worry about is the user input, as the json library always returns Unicode.

 

I've submitted a pull request with the Python 2 and JSON fixes.

Edited by deanishe
Link to post
Posted (edited)
15 hours ago, deanishe said:

 

I couldn’t say for sure without testing, but there’ll be little difference. json, like a lot of Python libraries, is implemented in C, so it’s very fast. And it would make very, very little difference in a program this size.

 

 

The golden rule is "encode and decode at IO boundaries". The only thing you should actually need to worry about is the user input, as the json library always returns Unicode.

 

I've submitted a pull request with the Python 2 and JSON fixes.

 

Thanks for the pull request and input!

 

I've added a new release now with your improvements, so everything should work smoothly on prior macOS versions as well now.

Edited by vegardinho
Link to post
  • 2 weeks later...
On 5/8/2020 at 6:43 AM, Spellzy said:

Hi, I this workflow works with every other bluetooth device but I can't seem to get it to connect my airpods. 

 

Hi, I can't say for sure what the problem is, might be something peculiar about the bluetooth-connection with AirPods. Post the debugging text here if you want me to take a look at it

Link to post
  • 6 months later...

Hi, I am also having trouble getting Bluetooth Controller to work.  I am running Big Sur 11.01, Alfred is up to date.  Installed Python 3 and blueutil.

 

Here's my debug report:

 

[21:42:41.311] Logging Started...

[21:43:10.894] Bluetooth Controller[Script Filter] Queuing argument '(null)'

[21:43:11.182] Bluetooth Controller[Script Filter] Script with argv '(null)' finished

[21:43:11.189] ERROR: Bluetooth Controller[Script Filter] Code 1: Traceback (most recent call last):

  File "./return_device_json.py", line 83, in <module>

    main()

  File "./return_device_json.py", line 29, in main

    js = check_output(cmd_args)

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 216, in check_output

    process = Popen(stdout=PIPE, *popenargs, **kwargs)

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 394, in __init__

    errread, errwrite)

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1047, in _execute_child

    raise child_exception

OSError: [Errno 2] No such file or directory

Edited by jdenormandie
Link to post
2 hours ago, jdenormandie said:

Hi, I am also having trouble getting Bluetooth Controller to work.  I am running Big Sur 11.01, Alfred is up to date.  Installed Python 3 and blueutil.

 

Here's my debug report:

 

[21:42:41.311] Logging Started...

[21:43:10.894] Bluetooth Controller[Script Filter] Queuing argument '(null)'

[21:43:11.182] Bluetooth Controller[Script Filter] Script with argv '(null)' finished

[21:43:11.189] ERROR: Bluetooth Controller[Script Filter] Code 1: Traceback (most recent call last):

  File "./return_device_json.py", line 83, in <module>

    main()

  File "./return_device_json.py", line 29, in main

    js = check_output(cmd_args)

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 216, in check_output

    process = Popen(stdout=PIPE, *popenargs, **kwargs)

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 394, in __init__

    errread, errwrite)

  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1047, in _execute_child

    raise child_exception

OSError: [Errno 2] No such file or directory

 

Did the error occur after the upgrade, or was it present in Catalina as well? (I haven't upgraded yet, but I'll probably have a look at in December sometime.)

Edited by vegardinho
Link to post

I only installed it after the upgrade - I was searching for easier ways to manage bluetooth given it's new location in the menubar.  I was double-checking the status of the blueutil and noticed there were no blueutil files in usr/local/bin which made me think it didn't install correctly.  I ran the blueutil install again, and got these results in terminal:

 

justin@Justins-MacBook-Pro ~ % /Users/justin/Downloads/blueutil/Install.command ; exit;

0:112: execution error: cp: blueutil: Operation not permitted (1)

Saving session...

...copying shared history...

...saving history...truncating history files...

...completed.

 

[Process completed]

 

 

Note, I did go into Security & Privacy to allow to run.

 

Link to post
47 minutes ago, jdenormandie said:

I only installed it after the upgrade - I was searching for easier ways to manage bluetooth given it's new location in the menubar.  I was double-checking the status of the blueutil and noticed there were no blueutil files in usr/local/bin which made me think it didn't install correctly.  I ran the blueutil install again, and got these results in terminal:

 

justin@Justins-MacBook-Pro ~ % /Users/justin/Downloads/blueutil/Install.command ; exit;

0:112: execution error: cp: blueutil: Operation not permitted (1)

Saving session...

...copying shared history...

...saving history...truncating history files...

...completed.

 

[Process completed]

 

 

Note, I did go into Security & Privacy to allow to run.

 

 

Right, without having verified this, it is very likely blueutil is the cause of the problem. A current flaw with the workflow is that it's only guessing where blueutil installs. Normally you'd merely run "blueutil" in the terminal (try this and you should get it working), but because the alfred script is not running in the same environment (I'm not an expert here, but something along those lines), i have to pass the full directory of blueutil for the script to run correctly. In other words, if Homebrew has changed where blueutil installs, or you have installed it somewhere else, that would break the workflow. My first guess would be that this has something to do with the Big Sur release.

 

If you want a quick fix, until I look into it, you could probably just find the blueutil install directory,

which blueutil

and then change the references in the alfred workflow.

Link to post

I opened up blueutil's Install.command file in TextEdit and it looks like it just copies blueutil over to "/usr/local/bin".  So I did that manually, but alas it still isn't working...

 

However, when I ran "which blueutil" in terminal I do get "/usr/local/bin/blueutil"

 

Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...