You are not logged in.
I am trying to create a udev rule to automatically send a desktop notification when the battery of my device is low. I am following two guides from the Wiki:
I checked if the batteries in my device emit discharge events and found that events are emitted on particular levels (e.g. 5%) only, by running
$ udevadm monitor --property
I created a udev rule to trigger a desktop notification, that looks like this:
/etc/udev/rules.d/99-lowbat.rules
SUBSYSTEM=="power_supply", \
ATTR{status}=="Discharging", \
ATTR{capacity}=="[0-5]", \
ENV{DISPLAY}=":0", \
ENV{XAUTHORITY}="$HOME/.Xauthority", \
RUN+="/usr/bin/sudo -u $USER /usr/bin/notify-send 'Warning' 'Low Battery'"
The desktop notification is not displayed and I don't know why it is not working.
As pointed out by V1del and ooo the solution consists of two steps:
define the DBUS_SESSION_BUS_ADDRESS environment variable
replace /usr/bin/sudo in the run command of the udev rule with /usr/bin/su (or alternatively use the -E option of the sudo command: /usr/bin/sudo -E)
/etc/udev/rules.d/99-lowbat.rules
SUBSYSTEM=="power_supply", \
ATTR{status}=="Discharging", \
ATTR{capacity}=="[0-5]", \
ENV{DBUS_SESSION_BUS_ADDRESS}="unix:path=/run/user/$UID/bus", \
RUN+="/usr/bin/su $USER -c /path/to/battery_notification"
battery_notification
#!/usr/bin/env bash
/usr/bin/notify-send 'Warning' 'Low Battery'
Note: DBUS_SESSION_BUS_ADDRESS can alternatively be exported in the wrapper script instead of defining it in the udev rule.
Last edited by hakunamatata (2018-06-22 08:26:33)
Offline
You aren't defining the DBUS_SESSION_ADDRESS and what does $USER resolve to? Read the udev example you linked again, and it really might be better to call a wrapper script which properly sets these values.
Offline
In fact I hardcode the actual values (for now) and do not use variables (e.g. $USER) in the actual rule. Should have said that in my initial post.
What confuses me about the example you mention is, all these variables seem to be defined twice (once in the rule and once in the wrapper script itself). Is this really necessary?
Also what should I set DBUS_SESSION_ADDRESS to? Does it matter that I am using i3 as a window manager (I vaguely remember some issues with i3 and DBUS)?
Last edited by hakunamatata (2018-06-20 15:20:29)
Offline
You can get your DBUS address from printenv and, as long as you are starting your session correctly, i3 should have no issues with dbus.
Offline
Yeah you likely don't need to define them twice, but the dbus_session_address is pretty vital here, I'd even argue you can omit the others but you have to have set the DBUS address
Offline
Neither defining DBUS_SESSION_BUS_ADDRESS nor using a wrapper script does seem to help.
Approach 1:
/etc/udev/rules.d/99-lowbat.rules
... ENV{DBUS_SESSION_BUS_ADDRESS}="unix:path=/run/user/$UID/bus" ...
Approach 2 (using a wrapper script):
/etc/udev/rules.d/99-lowbat.rules
... RUN+="/usr/bin/sudo -u $USER /path/to/battery_notification"
battery_notification
#!/usr/bin/env bash
export XAUTHORITY=$HOME/.Xauthority
export DISPLAY=:0
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$UID/bus"
/usr/bin/notify-send 'Warning' 'Low Battery'
Last edited by hakunamatata (2018-06-20 15:22:02)
Offline
Does the '/usr/bin/sudo -u $USER /path/to/battery_notification' command work, if you run it manually as root?
Is there a reason for using '/bin/sudo' instead of '/bin/su' as in the example?
Offline
Ah nice catch, that will definitely contribute.
sudo clears certain aspects of the environment by default. Try either su as suggested or sudo -Eu $user
Edit: But then it should still work in the script case...
Also just to verify... You are otherwise running in an environment that would create a notification? Can you notify-send on your own from a standalone terminal as your user? Which notification daemon are you running?
Last edited by V1del (2018-06-20 13:19:51)
Offline
Does the '/usr/bin/sudo -u $USER /path/to/battery_notification' command work, if you run it manually as root?
Is there a reason for using '/bin/sudo' instead of '/bin/su' as in the example?
In fact I tried both approaches.
# /usr/bin/su $USER -c /path/to/battery_notification
# /usr/bin/sudo -u $USER /path/to/battery_notification
And yes both commands above produce the expected result when run manually as root.
Last edited by hakunamatata (2018-06-20 13:50:43)
Offline
Ah nice catch, that will definitely contribute.
sudo clears certain aspects of the environment by default. Try either su as suggested or sudo -Eu $user
Edit: But then it should still work in the script case...
Also just to verify... You are otherwise running in an environment that would create a notification? Can you notify-send on your own from a standalone terminal as your user? Which notification daemon are you running?
Yes, other notifications are working and when running the script manually the result is as expected (i.e. the notification is shown).
Last edited by hakunamatata (2018-06-20 14:49:49)
Offline
Does the following command output some sane values (Charging/Discharging and the actual battery percentage)?
$ cat /sys/class/power_supply/BAT0/{status,capacity}
Offline
$ cat /sys/class/power_supply/BAT0/{status,capacity}
Discharging
5
$ cat /sys/class/power_supply/BAT1/{status,capacity}
Unknown
4
Note: I am using a device with two internal batteries.
Last edited by hakunamatata (2018-06-20 15:20:52)
Offline
Solved. I think ooo spotted the mistake. I tried again (probably messed something up the last time) with /usr/bin/su instead of /usr/bin/sudo and it is working. Solution can be found in the initial post.
Finally, I would like to thank everyone for their contributions.
Last edited by hakunamatata (2018-06-20 16:44:19)
Offline