I am trying to script a Bluetooth connection to a device that requires a PIN to be paired from a Linux machine. None of pygatt
or pybluez
can handle the PIN input. I figured out that subprocesses would be the right solution! The problem is, however, that pairing bluetooth devices requires sequential commands and analyzing the output so I can't just run commands from Python.
What I was able to do until now:
from subprocess import Popen, PIPE
p = Popen(['bluetoothctl'], stdin=PIPE, stdout=PIPE, bufsize=1)
p.stdin.write(b'agent') # First command in my procedurebluetoothctl
p.stdin.close()
for line in iter(p.stdout.readline, b''):
print line,
p.stdout.close()
p.wait()
This works just fine! It prompts me agent registered
, which is what I would get if I ran bluetoothctl
then "agent on" in a terminal.
However, I would like to go on and keep writing to this process, for example "scan on" to start scanning for devices or "devices" to list available devices. As far as I can understand, this is not possible as my code is written. Once the command is sent, the bridge is closed and if I try to do:
p.stdin.write(b'devices')
I'll get an error writing to closed file
.
My question: What is the correct way to keep sending and reading with this subprocess? Or a suitable alternative? I have read about subprocess.communicate()
but wasn't able to get any improvement, it closes anyway.
I also have read about pexpect
but I don't see how to use it to solve my problem.