Creating a simple laptop notification
Tutorial – Desktop Bash
With Bash, keeping a task simple often means using several different tools that all do their jobs well. Here's an easy, effective way to create a notification for when your laptop is unplugged.
If you trawl forums where newbies hang out (like I do), you'll often come across people yearning to learn Linux and asking things like: "Where can I learn about [insert some technology here]?" "Some technology" being anything ranging from the very basic stuff, like "the shell" or "the filesystem," to the quite advanced, like "systemd" or "Docker."
That, I think, is the wrong question to ask and, hence, tutorials often get the answer wrong and center on one tool and one tool alone. This forces the creator of the tutorial to jump through hoops to be able to do everything they have set out to explain with that single tool. It can be taken to the extreme with the author writing about how you can use LibreOffice Writer to open a socket to a remote host – probably not the best way to get data from the network.
A better question may be what are the best tools to carry out this specific task? The answer is usually whatever is easiest and most effective, regardless of whether you have to use four or 40 different tools to achieve your aim. And even with an easy task, you often have to resort to several things in the Linux box of tricks to make sure the project is effectively tackled.
In this article, let's look at how to make a warning system that is as simple as possible. We will make a notification pop up from your tray when your laptop is unplugged from the electrical outlet. That's it. Sounds easy, and it kind of is – except that, to avoid over-complicating things or getting into serious programming, you need to use at least four different tools.
The rationale for this utility could be that, while desktops often do show that the laptop is unplugged by popping a battery icon into the tray, this is often easy to miss. If it plays a sound, it makes the warning easier to catch, but if you are listening to music, have the sound down, or are hard of hearing, you may miss that, too. If you have the icon, the sound, and a pop-up notification, it is your own silly fault if you inadvertently drain your battery.
UPower
The first tool you're going to have to get familiar with is UPower [1]. UPower is a utility developed by freedesktop.org and is designed to, among other things, give you information about what is happening with the power sources on your machine.
Apart from an API to reach this information from several programming languages, UPower also comes with a handy human interface, ideal for quick and dirty scripting.
Try this, for example:
upower -e
This is a list of power sources available to your laptop. On your particular machine, they may have slightly different names from what you see in Figure 1, but you can be pretty sure that the entry for the battery will have the word "battery" in it and the entry for the electricity coming from the power outlet will have the words "line" and "power" in it.
But UPower's -e
option doesn't tell you to which power source your machine is connected. For that you use the -i
option. Following from the example shown in Figure 1:
upower -i /org/freedesktop/UPower/devices/line_power_ACAD
will show whether the electrical power source is connected. Figure 2 shows that it is – check the line that says online: yes
.
Likewise,
upower -i /org/freedesktop/UPower/devices/battery_BAT1
will show you information about your battery, including the make, model, serial number, level of charge, and all sorts of technical information. (Remember that the exact name of the devices you want to query will probably be slightly different on your machine – again check upower -e
to see the exact names for your computer).
The third thing you'll find useful for this project is UPower's -m
option. This monitors changes in the state of the power supplies.
Run
upower -m
and then disconnect your laptop from the outlet. UPower will print information about the changes (in this case, that it is switching from line power to battery) to the terminal.
Now you know what power sources are available (upower -e
), you can find out whether they are connected or disconnected (upower -i source
). When that status changes (upower -m
), you have the foundations of your project.
systemd Units
The next thing you need are some systemd units. Units are systemd's equivalent to the old init scripts: You describe a series of rules in them and systemd makes them happen. The rules lay out what state you want the system to be in and when. For example, a unit may tell systemd that you want networking at a certain point in the boot process, or that systemd should mount external USB storage devices when they are connected, or hundreds of other things.
Systemd provides several kinds of units [2]. Some run services, others set tasks to run at certain times or on certain days or mount devices, and there are some that monitor files and directories. The latter should prove useful, since in today's task you want systemd to monitor the changes in the power source.
But first you need something to monitor. As mentioned above upower -m
pushes out changes to the power sources to the terminal and doesn't stop until you hit Ctrl+C. You can use this to pipe the output to a file using something like
upower -m > upower.log
However, if you run this from the command line, it will tie up your terminal. The best way to run this is as a systemd service. As systemd units cannot process Bash commands chained together, you have to wrap the command in a script (Listing 1).
Listing 1
upowerlog.sh
#!/bin/bash upower -m > /home/[username]/.local/share/upower.log
Save that as upowerlog.sh
to a directory on your path (I saved it to /home/paul/.local/bin/
), make it executable with
chmod a+x /home/[username]/.local/bin/upowerlog.sh
and you can then run it from a service unit like the one you see in Listing 2.
Listing 2
upowerlog.service
01 [Unit] 02 Description= logging changes in power supply to laptop 03 Documentation= http://www.linux-magazine.com/Issues/2020/233 04 05 [Service] 06 Type= simple 07 ExecStart= /home/[username]/.local/bin/upowerlog.sh
In case you are not familiar with systemd units, they are split into sections. The [Unit]
section often contains information about the unit for humans to read and directives that tell systemd how the unit is related to other services in the system. If this service needs another service to run for it to work correctly, for example, you would put that here; if the service needs a task to run before it starts, you would also put that here; and so on.
In this case, all you have are the optional Description
and Documentation
directives. The former tells a human user what the service does, and the latter contains a link to where you can read up more about the unit itself.
The [Service]
section contains information that tells systemd what to do. In upowerlog.service
, the service is a simple
service, which means it just needs to start and runs until it is told to stop or the system powers down, while the ExecStart
directive tells systemd what it has to run, in this case, the upowerlog.sh
script.
You don't have to go to the hassle of becoming root and saving your units in /etc/systemd/system/
, which is where they usually live. Non-root users can have their own services, too!
Save the contents of Listing 2 as upowerlog.service
in /home/[username]/.config/systemd/user/
.You can then start it with:
systemctl --user start upowerlog
and you'll see a file called upower.log
pop up in /home/[username]/.local/share/
.
You can then see its contents change with
tail -f /home/[username]/.local/share/upower.log
Plug in and then unplug your laptop several times and you'll see something like what is shown in Figure 3.
Stop the service with
systemctl --user stop upowerlog
while you build the monitoring part of your service.
Notifications
Sending a notification to a standardized Linux desktop is very easy:
notify-send 'Hello!'
This will show a notification with the message "Hello!" popping up from your tray (Figure 4).
You can, of course, spruce the notification up a bit. The -a
option, for example, allows you to change the title of the pop-up box from the default notify-send
to whatever you want, and the -i
flag lets you set an icon. If you choose an icon from /usr/share/icons
, you don't need to specify the path. You can also leave out the extension. Another thing you can do is specify how long the notification will be shown with the -t
option. The duration is specified in milliseconds.
The following line
name="Jane"; notify-send -a "Calendar information" -i food-cake -t 5000 "$name's birthday" "Your contact $name is celebrating!"
will show what you can see in Figure 5.
To show a notification when the computer is disconnected from the electrical outlet, you can do the following.
Use upower -e
to find the name of the line power source:
upower -e | grep line
Use that to get information about it:
upower -i $(upower -e | grep line)
Grab the line that tells you if it is online:
upower -i $(upower -e | grep line) | grep online
Extract the "yes" or "no" and remove excessive spaces:
upower -i $(upower -e | grep line) | grep online | cut -d':' -f 2 | tr -d ' '
And fold the whole lot into a script like the one shown in Listing 3.
Listing 3
powerchange.sh
01 #!/bin/bash 02 03 if [ $(upower -i $(upower -e | grep line) | grep online | cut -d':' -f 2 | tr -d ' ') = 'no' ] 04 then 05 notify-send -a "Power source information" -i dialog-warning -t 5000 "Laptop unplugged" "Check you haven't kicked the charger by accident." 06 fi
Save the script as powerchange.sh
in /home/[username]/.local/bin/
and test it with your laptop both plugged in and unplugged. When you run powerchange.sh
with your laptop unplugged, you will see a notification like the one shown in Figure 6.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
Halcyon Creates Anti-Ransomware Protection for Linux
As more Linux systems are targeted by ransomware, Halcyon is stepping up its protection.
-
Valve and Arch Linux Announce Collaboration
Valve and Arch have come together for two projects that will have a serious impact on the Linux distribution.
-
Hacker Successfully Runs Linux on a CPU from the Early ‘70s
From the office of "Look what I can do," Dmitry Grinberg was able to get Linux running on a processor that was created in 1971.
-
OSI and LPI Form Strategic Alliance
With a goal of strengthening Linux and open source communities, this new alliance aims to nurture the growth of more highly skilled professionals.
-
Fedora 41 Beta Available with Some Interesting Additions
If you're a Fedora fan, you'll be excited to hear the beta version of the latest release is now available for testing and includes plenty of updates.
-
AlmaLinux Unveils New Hardware Certification Process
The AlmaLinux Hardware Certification Program run by the Certification Special Interest Group (SIG) aims to ensure seamless compatibility between AlmaLinux and a wide range of hardware configurations.
-
Wind River Introduces eLxr Pro Linux Solution
eLxr Pro offers an end-to-end Linux solution backed by expert commercial support.
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.
-
Rhino Linux Announces Latest "Quick Update"
If you prefer your Linux distribution to be of the rolling type, Rhino Linux delivers a beautiful and reliable experience.