Background
I’m using Conky for monitoring the system. After a system upgrade, the CPU temperatures were gone. Conky’s standard error showed the following.
Conky: can't open '/sys/class/hwmon/hwmon0/temp3_input': No such file or
directory please check your device or remove this var from Conky...
Source of message: https://bbs.archlinux.org/viewtopic.php?id=82231
An easy fix would be to adjust the following lines in .conkyrc according to
the number N in /sys/class/hwmon/hwmonN containing the file temp3_input.
(You may adjust the number 3 according to the number of CPU of your device.)
The number of CPU can be found using grep -c ^processor /proc/cpuinfo.
CPU 1: ${hwmon 0 temp 1}°C ${cpu cpu1}% ${alignr} CPU 2: ${hwmon 0 temp 2}°C ${cpu cpu2}%
${cpugraph cpu1 60,120} ${alignr} ${cpugraph cpu2 60,120}
To find out what the above paths represent, issue tree /sys/class/hwmon
$ tree /sys/class/hwmon/
/sys/class/hwmon/
├── hwmon0 -> ../../devices/virtual/hwmon/hwmon0
├── hwmon1 -> ../../devices/platform/coretemp.0/hwmon/hwmon1
└── hwmon2 -> ../../devices/pci0000:00/0000:00:1c.0/0000:01:00.0/hwmon/hwmon2
3 directories, 0 files
coretemp.0 represents the CPU temperatures. It’s linked to hwmon1, so for
the current session, the right config should be ${hwmon 1 temp m}. However,
as written in the linked forum message, after a system upgrade, the digit would
shift.
Problem
How to configure Conky properly so that the CPU temperatures will be shown
despite the shifting of temp3_input’s path?
Difficulty
Start with a simple idea.
-
Test the existence of
temp3_inputfor directorieshwmonN, whereN = 0,...,3. Only oneNwould give positive result. Assign this to some variable${myvar}.for (( i=0; i<3; i++ )); do test -e /sys/class/hwmon/hwmon$i/temp3_crit && echo $i || echo -n done # returns `1`Wrap this shell command with
${exec ...}in.conkyrc. -
Write something like
${hwmon ${myvar} temp m}form = 1,...in.conkyrc.
This leads us to a deadend. The syntax in item 2 doesn’t
work. One has to use a Conky Lua script to make things work.
Note that the .conkyrc syntax has changed so significantly that the TEXT
section has been replaced by a conky.text = [[ ... ]] block. It
took me an hour to find the right wiki page. This line in
.conkyrc inside conky.config = { ... } calls the Lua script.
lua_load = '/home/username/scripts/script.lua'
I’m not sure whether relative path is allowed. You may test and let me know in the comments below.
Since I don’t know Lua, my script won’t be as fancy as the official sample. It took me some time to learn these basics in Conky Lua scripts.
- All Lua functions directly called from
.conkyrcwith the syntax${lua myfct[ params]}has to be written asfunction conky_myfct ([parmas])in the Lua script file. The examples that I’ve seen use${lua conky_myfct}, but skippingconky_in the previous expression still gives me the desired result, as you can see from the animated screenshot below. - The arguments for functions in
${lua myfct args}in.conkyrcdon’t need to be surrounded by parenthesis(), contrarily to the Conky Lua scriptmyfct(args). - Any function directly called by
.conkyrchas to return a string. Other return types are discarded. Usetostring()to convert other data types to strings. - Multiple argument in
print("arg1", var2, "arg3")is possible, but the output string will be delimited by tabs by default. That’s not desirable in some cases. - The syntax for string concatenation is
... Subtraction-has a higher precedence than string concatenation.., so quantities liken-1has to be enclosed with a pair of parenthesis()when used with... conky_parse("${...}")returns a string.
Solution
The actual Conky Lua script will be divided into three stages for the ease of maintenance.
-
Verify whether
file_existsby its filename.function file_exists(name) local f=io.open(name,"r") if f~=nil then io.close(f) return true else return false end end -
Find the right
Nso that/sys/class/hwmon/hwmonN/temp3_critexists.function findHwmonNum() for i = 0,10,1 do if file_exists("/sys/class/hwmon/hwmon"..i.."/temp3_crit") then return i end end end -
To replace
${hwmon N temp n}with the function${lua cputemp n}in.conkyrc, we need to read Conky’s string output withconky_parse(${...}). The string inside is the concatenation of${hwmon,findHwmonNum()(representingNin the previous section),temp,n(the input argument) and}. I’ve hard-codedCPU 1, …,CPU 3in.conkyrcbecause of the alignment of CPU info. I would like to keep the code maintainable with my basic knowledge in Lua. This gives the following function.function conky_cputemp(n) return conky_parse("${hwmon "..findHwmonNum().." temp "..n.."}") end
Visual result
