'Retrieve List of Bluetooth Devices Using Python 3 and Terminal
When using the Linux terminal inside the Raspberry pi, i have to use only 3 commands to retrieve a list of Bluetooth capable devices in the area. These are the commands that are executed in order:
- "sudo bluetoothctl"
- "agent on"
- "scan on"
the final command above will over-time retrieve a list of scanned devices. When i manually put it into my raspberry pi terminal it works (found instrustions from here: Instruction Link)
QUESTION: how do i translate the series of commands above into a Python 3 script using the standard subprocess module?
I Tried:
import time
import subprocess
arguments = ["sudo", "bluetoothctl"] #to be able to access Bluetooth commands
output = subprocess.Popen(arguments, shell=True)
time.sleep(0.1)
arguments = ["agent", "on"]
output = subprocess.Popen(arguments, shell=True)
time.sleep(0.1)
arguments = ["scan", "on"]
output = subprocess.check_output(arguments, shell=True)
time.sleep(0.1)
print(output) #not even close huh.. yea..
As you can see i'm pretty new to both Linux terminal commands and the subprocess module. Therefore any help and guidance is greatly appreciated!
UPDATE: i am able to get my first command sudo bluetoothctl
to work as it returns list of previously paired devices. However when i get to the next command output = subprocess.Popen("agent on", shell=True)
it returns a message: /bin/sh: 1: agent: not found
. How do i get my other commands to work?
New code:
import time
import subprocess
output = subprocess.Popen("sudo bluetoothctl", shell=True)
time.sleep(0.1)
output = subprocess.Popen("agent on", shell=True)
time.sleep(0.1)
output = subprocess.check_output("scan on", shell=True)
time.sleep(2)
What the terminal spits out:
[NEW] Controller XX:XX:XX:XX:XX:XX raspberrypi [default]
[NEW] Device XX:XX:XX:XX:XX:XX Galaxy J3 Emerge
[bluetooth]# /bin/sh: 1: agent: not found
/bin/sh: 1: scan: not found
Traceback (most recent call last):
File "/home/pi/pywork/test.py", line 9, in <module>
output = subprocess.check_output("scan on", shell=True)
File "/usr/lib/python3.5/subprocess.py", line 316, in check_output
**kwargs).stdout
File "/usr/lib/python3.5/subprocess.py", line 398, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'scan on' returned non-zero exit status 127
Process finished with exit code 1
Any ideas on how to get this second command to work?
Solution 1:[1]
TLDR;
The issue of the above is related to the invocation of suprocess.check_output
, with parameter shell=True
, you should use string instead of a list of arguments
Here are some details.
UPDATE:
I assume that the reason is that it's not invoked in the same shell session, so it didn't find an agent. Depending on what you're trying to achieve, you should either use the same session (for example as in this case) or use a python library like PyBluez to control the Bluetooth devices (which I would recommend)
Solution 2:[2]
I am currently doing a similar function. Have you realized this function yet? After sending Bluetooth CTL with Popen, a pipeline will be opened. The subsequent agent on and scan on must be sent in the opened pipeline, rather than opening a new pipeline with Popen.
Solution 3:[3]
Regardless of the fact this question was posted years ago some wanderer might find the line below useful. Nevermind sudo
as not necessary.
bt = subprocess.Popen(["sudo", "bluetoothctl", "scan", "on"], stdin=subprocess.PIPE)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | hunter |
Solution 3 | parovelb |