I am trying to automatically run this script, whenever I connect to my bluetooth headset.
I have created the file /etc/udev/rules.d/80-bt-headset.rules with the line
ACTION=="add", SUBSYSTEM=="input" ATTR{name}=="00:22:37:3D:DA:50" RUN+="/home/USER/.local/bin/a2dp.py 00:22:37:3D:DA:50"
but it doesn't do anything. The conditions are fine, a simple test comand is triggered when I enter that instead. The script itself also works fine when run manually.
What is going wrong here?
Update: There is an error when running the script with sudo -u USER
(see below for details). Could this be the problem? And how does sudo-ing to the same user break things?
Update 2: After replacing all instances of pacmd
with pactl
in a2dp.py
(and replacing list-sinks
with list sinks
to make it a valid pactl command), sudo -u USER
works, however, the udev rule still doesn't. In /var/log/syslog
I just see the line
systemd-udevd[32629]: Process '/home/USER/.local/bin/a2dp_2.py 00:22:37:3D:DA:50' failed with exit code 1.
Update 3 (Solution): The modified skript (pacmd -> pactl, see Update 2) with the environment variables DISPLAY=:0
and XAUTHORITY=/home/USER/.Xauthority
did the trick. The udev rule:
ACTION=="add", SUBSYSTEM=="input" ATTR{name}=="00:22:37:3D:DA:50" ENV{DISPLAY}=":0" ENV{XAUTHORITY}="/home/USER/.Xauthority" RUN+="/home/USER/.local/bin/a2dp_2.py 00:22:37:3D:DA:50"
is working as intended.
(Now the only remaining problem is, that the script itself will trigger the rule, as it reconnects the headset, resulting in an infinite loop. However, that is a separate question, and it should not be too hard to find a workaround. In fact I was expecting that behaviour when I started this thread.)
What works:
The conditions are fine: The line:
ACTION=="add", SUBSYSTEM=="input" ATTR{name}=="00:22:37:3D:DA:50" RUN+="/bin/mkdir /tmp/testme"
will create a new directory when I connect to the headset.
The script a2dp.py itself works fine when run from the terminal via
/home/USER/.local/bin/a2dp.py 00:22:37:3D:DA:50
Running a simply Python script via udev:
ACTION=="add", SUBSYSTEM=="input" ATTR{name}=="00:22:37:3D:DA:50" RUN+="/home/USER/.local/bin/atestscript.py"
where atestscript.py contains:
#!/usr/bin/python # -*- coding: utf-8 -*- import subprocess def main(): subprocess.Popen(['mkdir', '/tmp/atestdir']) if __name__ == '__main__': main()
will again create a folder when the device is connected.
What works after replacing pacmd with pactl:
Running the script from the terminal with
sudo -u USER
or evensudo -u root
now works as intended (For the originial script this resulted in:USER@MACHINE:~$ sudo -u USER /usr/local/bin/a2dp.py 00:22:37:3D:DA:50 Connection MADE Device MAC: 00:22:37:3D:DA:50 Command: pacmd list-sinks failed with status: 1 stderr: No PulseAudio daemon running, or not running as session daemon. Exiting bluetoothctl
What does not work:
Running the script as above or with any of the following lines as the
RUN+=
part:/usr/bin/sudo -u USER /usr/bin/python3 /home/USER/.local/bin/a2dp.py 00:22:37:3D:DA:50 /usr/bin/sudo -u USER /home/USER/.local/bin/a2dp.py 00:22:37:3D:DA:50 /usr/bin/python3.5 /usr/local/bin/a2dp.py 00:22:37:3D:DA:50 ENV{DISPLAY}=":0" RUN+="/usr/local/bin/a2dp.py 00:22:37:3D:DA:50"
Even the modified script will not work:
ENV{DISPLAY}=":0" ENV{PULSE_RUNTIME_PATH}="/run/user/1000/pulse/" RUN+="sudo -u USER /home/USER/.local/bin/a2dp_2.py 00:22:37:3D:DA:50"
Further information: udevadm monitor output on connecting to headset:
KERNEL[104388.664737] add /devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0/bluetooth/hci0/hci0:256 (bluetooth)
UDEV [104388.667185] add /devices/pci0000:00/0000:00:14.0/usb3/3-7/3-7:1.0/bluetooth/hci0/hci0:256 (bluetooth)
KERNEL[104390.848157] add /devices/virtual/input/input46 (input)
UDEV [104390.849150] add /devices/virtual/input/input46 (input)
KERNEL[104390.849471] add /devices/virtual/input/input46/event17 (input)
UDEV [104390.864692] add /devices/virtual/input/input46/event17 (input)
RUN+=
part doesn't pass MAC address of the headset as argument to script, you just run the script alone. See here for an example: stackoverflow.com/a/14982520/3701431export DISPLAY=:0
it may be not enough forpactl
used by that script. Look at this post answers, they contain some interesting env variables askubuntu.com/q/458194/26246 . otherwise search forudev pactl
ENV{DISPLAY}=":0"
beforeRUN+=
, ref: reactivated.net/writing_udev_rules.html#env , or use another shell script to wrap the target python script.XAUTHORITY
(I just added all variables thatprintenv
showed in a normal user terminal to a wrapper script, saw that it worked, then repeatedly removed half the variables until it broke again, etc.; In hindsight, I could have guessed it.) Thank you very much for your help.