Creating a simple laptop notification

Tutorial – Desktop Bash

Article from Issue 233/2020
Author(s):

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.

Figure 1: UPower tells you, among other things, what power sources your device counts on.

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.

Figure 2: You can use UPower to check the state of the power sources.

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.

Figure 3: Tracking changes in power source as a service.

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).

Figure 4: You can send custom notifications to your desktop using notify-send from the shell.

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.

Figure 5: You can make your notifications more visually attractive with icons and custom titles.

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.

Figure 6: powerchange.sh shows a notification when the laptop is unplugged.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • ACPI Tools

    Linux offers some useful command-line tools that leverage the ACPI power management framework to display detailed data on the status of a laptop battery.

  • Systemd Timers

    Systemd can start timers that automatically perform tasks at specified times. The configuration files are known as timer units.

  • Systemd Units

    Systemd units use files to control resources that Systemd manages.

  • Tutorials – Systemd

    Take control of the services running on your Linux machine

  • Systemd GUIs

    Graphical frontends make it easier to take full advantage of the Systemd process manager. We examine some leading tools for the KDE environment.

comments powered by Disqus
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.

Learn More

News