Switching between AC power and battery power should generate an event on the D-Bus system bus. Run dbus-monitor --system and watch what events are generated on your system.
If you have upower running, you get more specialized notifications from upower -m.
Some people reported my earlier udev solution sent the notification too many times when the power cable was plugged in. I couldn't reproduce that but I wrote this python script to utilize dbus instead of udev. Save it as a .py file somewhere on your hard drive. Mark the file executable by running:
sudo chmod +x yourFile.py
and add it to your startup applications as described here. This script requires the package acpi be installed.
#!/usr/bin/python
import dbus
from dbus.mainloop.glib import DBusGMainLoop
import gobject
import subprocess
dbus_loop = DBusGMainLoop()
bus = dbus.SystemBus(mainloop=dbus_loop)
onMessage="Power plugged in!"
offMessage="Power unplugged!"
onImage="/usr/share/icons/gnome/32x32/devices/ac-adapter.png"
offImage="/usr/share/icons/gnome/32x32/status/battery-full.png"
def callback():
state = subprocess.check_output(["acpi", "-a"]).split(':')[1].strip()
if state == "on-line":
subprocess.call(["notify-send", "-i", onImage, onMessage])
elif state == "off-line":
subprocess.call(["notify-send", "-i", offImage, offMessage])
bus.add_signal_receiver(callback, 'Changed', 'org.freedesktop.UPower.Device', 'org.freedesktop.UPower', '/org/freedesktop/UPower/devices/line_power_AC')
loop = gobject.MainLoop()
loop.run()
udev
With a little experimentation (and a little help) I was able to utilize a udev rule to accomplish this. Some people have reported that it sometimes sends the notification more than once but I have not had any problems. YMMV.
Create a script with the following contents:
#!/bin/bash
# Set this to your username
USER="some_user"
if [ "$POWER" == "on" ]
then
DISPLAY=:0 /bin/su $USER -c '/usr/bin/notify-send -i /usr/share/icons/gnome/32x32/devices/ac-adapter.png "Power cable plugged in."'
elif [ "$POWER" == "off" ]
then
DISPLAY=:0 /bin/su $USER -c '/usr/bin/notify-send -i /usr/share/icons/gnome/32x32/status/battery-full.png "Power cable unplugged."'
fi
replacing some_user with your username. Mark the file executable by running:
sudo chmod +x /path/to/script.sh
replacing /path/to/script.sh with the path to where you saved the script.
Next create a file in /etc/udev/rules.d named 10-power.rules with the contents:
#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: [email protected]
# Date: March 11, 2016
# Purpose: Script to detect connection/disconnection
# of the ac adapter
#
#
# Written for: http://askubuntu.com/q/542986/295286
# Tested on: Ubuntu 14.04 LTS
# Version: 0.2
###########################################################
# Copyright: Serg Kolo , 2016
#
# Permission to use, copy, modify, and distribute this software is hereby granted
# without fee, provided that the copyright notice above and this permission statement
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#set -x
ARGV0="$0"
ARGC=$#
test_presence()
{
on_ac_power
echo $?
}
notify_change()
{
pgrep -f '/usr/bin/X' > /dev/null && GUI=true
connected='AC adapter connected'
disconnected='AC adapter disconnected'
if [ $1 -eq 0 ]
then
wall <<< $connected
$GUI && DISPLAY=:0 notify-send 'AC adapter connected'
else
wall <<< $connected
$GUI && DISPLAY=:0 notify-send 'AC adapter disconnected'
fi
}
main()
{
FLAG=$(test_presence)
while true
do
STATUS=$(test_presence)
if [ $STATUS -eq $FLAG ]
then
continue
else
notify_change $STATUS
FLAG=$STATUS
fi
sleep 3 #0.25
done
}
main
Getting the script
The script is also added to my github ; that version will be updated and developed a tiny bit more.
You can get it by doing the following:
sugo apt-get install git
cd /opt
git clone https://github.com/SergKolo/sergrep.git
The script will be in /opt/sergrep directory, named notify_ac_change.sh
Concept/Design
The key questions are "How do we check presence of the AC adapter ?" and "How do we detect changes?"
Well, this issue has been solved long ago by other developers. Ubuntu comes by default with a script called on_ac_power, which is stored in /usr/bin/on_ac_power. Power adapter can be mentioned under different subsystems in the kernel ( ACPI or APM ) , but this script makes our job simpler - authors have covered a lot of possible variations. It return only exit status so it's appropriate for use in if statements.
Why is on_ac_power is good choice ? Because it relies on checking multiple subsystems. It also provides simple enough command to work with - the result is either true or false.
Thus we have presence detecting tool, but what about logic ? We need to poll the presence and detect change in the state. What we can do is to store exit status of on_ac_power and continuously compare current state with what we have saved, once it changes - send notification, save the status again, and keep comparing again,looping. Basic idea is the use of flags.
In short, we initialize a snapshot of the state, and then continuously poll for change from the snapshot; once change occurs - notify and reset snapshot.
Switching between AC power and battery power should generate an event on the D-Bus system bus. Run
dbus-monitor --system
and watch what events are generated on your system.If you have upower running, you get more specialized notifications from
upower -m
.You can also get events from
acpi_listen
.Run this script when you want to start seeing notifications, or add it to your session startup.
dbus
Some people reported my earlier udev solution sent the notification too many times when the power cable was plugged in. I couldn't reproduce that but I wrote this python script to utilize dbus instead of udev. Save it as a
.py
file somewhere on your hard drive. Mark the file executable by running:and add it to your startup applications as described here. This script requires the package
acpi
be installed.udev
With a little experimentation (and a little help) I was able to utilize a udev rule to accomplish this. Some people have reported that it sometimes sends the notification more than once but I have not had any problems. YMMV.
Create a script with the following contents:
replacing
some_user
with your username. Mark the file executable by running:replacing
/path/to/script.sh
with the path to where you saved the script.Next create a file in
/etc/udev/rules.d
named10-power.rules
with the contents:again replacing
/path/to/script.sh
with the path to the script you created earlier.Now reload the udev rules by running:
Unplug the power cable. You should get a notification.
Script Source
Getting the script
The script is also added to my github ; that version will be updated and developed a tiny bit more.
You can get it by doing the following:
sugo apt-get install git
cd /opt
git clone https://github.com/SergKolo/sergrep.git
The script will be in
/opt/sergrep
directory, namednotify_ac_change.sh
Concept/Design
The key questions are "How do we check presence of the AC adapter ?" and "How do we detect changes?"
Well, this issue has been solved long ago by other developers. Ubuntu comes by default with a script called on_ac_power, which is stored in
/usr/bin/on_ac_power
. Power adapter can be mentioned under different subsystems in the kernel ( ACPI or APM ) , but this script makes our job simpler - authors have covered a lot of possible variations. It return only exit status so it's appropriate for use inif
statements.Why is
on_ac_power
is good choice ? Because it relies on checking multiple subsystems. It also provides simple enough command to work with - the result is either true or false.Thus we have presence detecting tool, but what about logic ? We need to poll the presence and detect change in the state. What we can do is to store exit status of
on_ac_power
and continuously compare current state with what we have saved, once it changes - send notification, save the status again, and keep comparing again,looping. Basic idea is the use of flags.In short, we initialize a snapshot of the state, and then continuously poll for change from the snapshot; once change occurs - notify and reset snapshot.