Making a simple AwesomeWM widget Sun, Jun 18, 2017
It's been a long time since I switched to Linux, but I've been running Arch Linux instead of Mint for a few years now. My current workstation is a Dell XPS 13, which is a really lightweight, pleasantly designed device whose hardware is all well-supported on Linux.
The main weak point is its integrated graphics card, which I found couldn't drive an external 1080p monitor on its own without stuttering. I bought the Dell TB16 Dock to drive the monitor, which fixed the problem nicely with minimal fuss. Now I can use an external monitor like a normal person!
But! The fans are always on high when I'm plugged into the dock and using the external monitor. I got concerned about the cpu temperature, so started monitoring it with a simple watch command:
$ watch -n 1 sensors
Every 1.0s: sensors xps13-arch: Sun Jun 18 14:47:16 2017
coretemp-isa-0000
Adapter: ISA adapter
Package id 0: +53.0°C (high = +100.0°C, crit = +100.0°C)
Core 0: +52.0°C (high = +100.0°C, crit = +100.0°C)
Core 1: +52.0°C (high = +100.0°C, crit = +100.0°C)
acpitz-virtual-0
Adapter: Virtual device
temp1: +25.0°C (crit = +107.0°C)
temp2: +27.8°C (crit = +105.0°C)
temp3: +29.8°C (crit = +105.0°C)
iwlwifi-virtual-0
Adapter: Virtual device
temp1: +37.0°C
pch_skylake-virtual-0
Adapter: Virtual device
temp1: +49.5°C
I thought it would be cool to see temperature in a more minimal way on my taskbar. Since I used Awesome as my window manager, I have pretty fine-grained control over the UI, so instead of installing a standalone app just for the temperature, I decided to learn a little bit about Awesome's text widget api so I can translate my command line call into data that drives a text widget. This is what I came up with:
-- Instantiate a new textbox widget
local tempwidget = wibox.widget.textbox()
-- The shell command to run. In this case, we call sensors in a for loop,
-- sleeping 5s in between each call. We pass -u to sensors to get raw
-- unformatted data from it, and coretemp-isa-0000 tells it to get just
-- my cpu's temperature. We pipe that output into awk to get just the
-- numeric value.
local cmd = [[bash -c "
while true; do
sensors -u coretemp-isa-0000 | awk '/temp1_input/ { print }'
sleep 5
done
"]]
-- The shell command is a blocking call but we don't want to block
-- the rest of the UI waiting on it, so we use Awesome's
-- awful.spawn.with_line_callback() to spawn a subprocess for the
-- command and call our callback whenever there's new stdout data.
-- Awesome handles this subprocess communication in a nonblocking
-- way so the rest of the UI stays responsive.
awful.spawn.with_line_callback(cmd, {
stdout = function(line)
-- This callback gets called whenever there's a new stdout line,
-- so in our command's case, every new temperature sample.
-- We do some simple string formatting on the value and update
-- the widget's value. Note that tempwidget is a closure on
-- the widget we instantiated earlier.
tempwidget:set_markup(string.format(' CPU: %.0f°C ', tonumber(line)))
end,
stderr = function(line)
-- Here we just post Awesome notifications if there's anything in stderr
-- in case the sensors command writes some errors to stderr.
naughty.notify({ text = "ERR:"..line})
end,
})
-- I'm omitting a lot of other layout code that probably already exists in your
-- theme, but I'm assuming there's a layout for the right side of your taskbar
right_layout:add(tempwidget)
This all feels nicely Linuxly. I didn't have to spin up a new app with complicated GUI dependencies just to get a simple value that I could already get from command line.