I know about the problem with decimal points from original post. Therefore I wanted to replace the exec calls.
My problem in using hwmon from conky: I don't know how to enumerate sensors instead of inputs.
I have 4 sensors of type nvme ...
... that's why I wanted to go for /system filesystem directly.
Any way - I got it with the help from conky forum.
If you're interested, here are the new working files (and the best: new version takes only half of system load
Code: Select all
--[[
#
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2021-2025 django013
#
# project: conky.arcs theme for conky
# purpose: lua script which processes config.lua file and draws
# system monitor with conky provided values
# All customizable stuff is placed in config.lua
# this file contains code to process that config file
# and for so no need to change this script
]]--
require 'cairo'
cfg = require 'config'
settings = cfg.setup()
function splitString(str, sep)
if sep == nil then
sep = "%s"
end
local t = {}
for s in string.gmatch(str, "([^"..sep.."]+)") do
table.insert(t, s)
end
return t
end
function printTemperature(path, unit)
local f = io.open(path, "rb")
if not f then return 0 end
local rv = f:read("*a")
f:close()
if (not unit == nil) then
return string.format('%s°', tonumber(rv))
else
return string.format('%s', tonumber(rv))
end
end
function printTemperatureMilli(path, unit)
local f = io.open(path, "rb")
if not f then return 0 end
local rv = f:read("*a")
f:close()
if (not unit == nil) then
return string.format('%s°', tonumber(rv) / 1000.0)
else
return string.format('%s', tonumber(rv) / 1000.0)
end
end
function drawBackground(ctx, xOff, yOff, cfg)
local w = cfg['w'] * settings['lw']
local h = cfg['h'] * settings['lh']
cairo_set_line_width(ctx, 0)
cairo_rectangle(ctx, xOff, yOff, w, h)
cairo_set_source_rgba(ctx, rgb2r_g_b(settings['bgCol'], 0.5))
cairo_fill_preserve(ctx)
cairo_stroke(ctx)
end
function drawRing(ctx, xOff, yOff, rd, cfg)
local r = rd['r'] * settings['lh']
local cx = xOff + rd['x'] * settings['lw']
local cy = yOff + rd['y'] * settings['lh'] + 1.7 * settings['lh']
local s = ''
local sa = deg2rad(rd['sa'])
local ea = deg2rad(rd['ea'])
local ca = rd['ea'] - rd['sa']
if (rd['name'] == 'printTemperature') then
s = printTemperature(rd['arg'])
elseif (rd['name'] == 'printTemperatureMilli') then
s = printTemperatureMilli(rd['arg'])
else
s = conky_parse(string.format('${%s %s}', rd['name'], rd['arg']))
end
local v = tonumber(s)
if v == nil then v = 0 end
if v > 100 then v = 100 end
if rd['d'] == 'ccw' then
ca = 360 - rd['ea'] + rd['sa']
end
ca = ca / 100.0 * v
if rd['d'] == 'ccw' then
cairo_arc_negative(ctx, cx, cy, r, sa, ea)
else
cairo_arc(ctx, cx, cy, r, sa, ea)
end
local bg = rd['bg']
local ba = rd['ba']
local fg = rd['fg']
if bg == nil then bg = settings['rBgC'] end
if ba == nil then ba = settings['alpha'] end
if fg == nil then fg = settings['rCol'] end
cairo_set_source_rgba(ctx, rgb2r_g_b(bg, ba))
cairo_set_line_width(ctx, settings['lh'] * rd['h'])
cairo_stroke(ctx)
if rd['d'] == 'ccw' then
cairo_arc_negative(ctx, cx, cy, r, sa, deg2rad(rd['sa'] - ca))
else
cairo_arc(ctx, cx, cy, r, sa, deg2rad(rd['sa'] + ca))
end
cairo_set_source_rgba(ctx, rgb2r_g_b(fg, 0.8))
cairo_set_line_width(ctx, settings['lh'] * rd['h'])
cairo_stroke(ctx)
end
function printMainText(ctx, te, xOff, yOff, td, cfg)
local x = xOff + td['x'] * settings['lw']
local y = yOff + td['y'] * settings['lh']
local c = settings['color']
local a = settings['alpha']
local fs = td['s']
if fs == nil then fs = 0 end
if td['text']:sub(0, 1) == '$' then
s = conky_parse(td['text'])
if td['text']:sub(3,5) == 'fre' then
v = tonumber(s)
if v == nil then v = 0 end
local l1 = cfg['level1']
local l2 = cfg['level2']
if l1 == nil then l1 = 2000 end
if l2 == nil then l2 = 2990 end
if v > l2 then c,a = settings['col2'],1
elseif v > l1 then c,a = settings['col1'],1
end
cairo_select_font_face(ctx
, settings['font']
, CAIRO_FONT_SLANT_NORMAL
, CAIRO_FONT_WEIGHT_BOLD)
else
if fs > 0 then
cairo_set_font_size(ctx, fs)
else
cairo_select_font_face(ctx
, settings['font']
, CAIRO_FONT_SLANT_NORMAL
, CAIRO_FONT_WEIGHT_NORMAL)
end
end
elseif td['text']:sub(0,4) == 'LIF:' then
local p = splitString(td['text'], ' ')
if (p[2] == 'printTemperature') then
s = printTemperature(p[3], '°')
elseif (p[2] == 'printTemperatureMilli') then
s = printTemperatureMilli(p[3], '°')
end
else
if fs > 0 then
cairo_set_font_size(ctx, fs)
end
s = td['text']
end
if td['a'] == 'L' then
cairo_text_extents(ctx, s, te)
x = x - te.width
end
cairo_move_to(ctx, x, y)
cairo_set_source_rgba(ctx, rgb2r_g_b(c, settings['alpha']))
cairo_show_text(ctx, s)
cairo_stroke(ctx)
end
function printText(ctx, te, xOff, yOff, td)
local x = xOff + td['x'] * settings['lw']
local y = yOff + td['y'] * settings['lh']
if td['text']:sub(0,1) == '$' then
s = conky_parse(td['text'])
else
s = td['text']
end
if td['a'] == 'L' then
cairo_text_extents(ctx, s, te)
x = x - te.width
end
cairo_move_to(ctx, x, y)
cairo_show_text(ctx, s)
cairo_stroke(ctx)
end
function deg2rad(d)
return (d - 90) * math.pi / 180
end
function rgb2r_g_b(col, alpha)
local c = tonumber(col, 16)
return ((c / 0x10000) % 0x100) / 255.
, ((c / 0x100) % 0x100) / 255.
, (c % 0x100) / 255.
, alpha
end
function genStatics(ctx, te)
local xOff = settings['x'] * settings['lw']
local yOff = settings['y'] * settings['lh']
cairo_select_font_face(ctx
, settings['hFont']
, CAIRO_FONT_SLANT_NORMAL
, CAIRO_FONT_WEIGHT_NORMAL)
cairo_set_font_size(ctx, 30)
cairo_set_source_rgba(ctx, rgb2r_g_b(settings['color'], settings['alpha']))
for i in pairs(settings['uptime']) do
printMainText(ctx, te, xOff, yOff, settings['uptime'][i])
end
for i in pairs(settings['date']) do
printMainText(ctx, te, xOff, yOff, settings['date'][i])
end
for i in pairs(settings['time']) do
printMainText(ctx, te, xOff, yOff, settings['time'][i])
end
cairo_select_font_face(ctx
, settings['font']
, CAIRO_FONT_SLANT_NORMAL
, CAIRO_FONT_WEIGHT_NORMAL)
cairo_set_font_size(ctx, settings['fs'])
cairo_set_source_rgba(ctx, rgb2r_g_b(settings['color'], settings['alpha']))
for i in pairs(settings['sys']) do
printMainText(ctx, te, xOff, yOff, settings['sys'][i])
end
end
function genPanel(ctx, te, panelName)
local cfg = settings[panelName]
local xOff = cfg['x'] * settings['lw']
local yOff = cfg['y'] * settings['lh']
if settings['sb'] then drawBackground(ctx, xOff, yOff, cfg) end
for i in pairs(cfg['rings']) do
drawRing(ctx, xOff, yOff, cfg['rings'][i], cfg)
end
for i in pairs(cfg['main']) do
printMainText(ctx, te, xOff, yOff, cfg['main'][i], cfg)
end
local fg = cfg['color']
if fg == nil then fg = settings['col3'] end
cairo_set_source_rgba(ctx, rgb2r_g_b(fg, settings['alpha']))
for i in pairs(cfg['sub']) do
printText(ctx, te, xOff, yOff, cfg['sub'][i])
end
end
function conky_main()
if conky_window == nil then return end
local cs = cairo_xlib_surface_create(conky_window.display
, conky_window.drawable
, conky_window.visual
, conky_window.width
, conky_window.height)
local ctx = cairo_create(cs)
local updates = conky_parse('${updates}')
nUpdate = tonumber(updates)
if nUpdate > 2 then
local te = cairo_text_extents_t:create()
tolua.takeownership(te)
cairo_select_font_face(ctx
, settings['font']
, CAIRO_FONT_SLANT_NORMAL
, CAIRO_FONT_WEIGHT_NORMAL)
cairo_set_font_size(ctx, settings['fs'])
cairo_text_extents(ctx, 'Wy', te)
-- calculate position units based on font size
settings['lh'] = te.height
settings['lw'] = te.width * 0.4
genStatics(ctx, te)
cairo_select_font_face(ctx
, settings['font']
, CAIRO_FONT_SLANT_NORMAL
, CAIRO_FONT_WEIGHT_NORMAL)
cairo_set_font_size(ctx, settings['fs'])
genPanel(ctx, te, 'cpu')
genPanel(ctx, te, 'io')
genPanel(ctx, te, 'mem')
genPanel(ctx, te, 'sensors')
genPanel(ctx, te, 'hddTemp')
genPanel(ctx, te, 'hdd')
end
cairo_surface_destroy(cs)
cairo_destroy(ctx)
end
... and the installer that checks existing hardware:
Code: Select all
#!/usr/bin/env python3
#
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2021-2025 django013
#
# project: conky.arcs theme for conky
# purpose: installation script for conky.arcs theme
# Script explores running system and generates matching
# gui elements for conky system monitor.
import os
import sys
import glob
import array
import logging as log
import pathlib
import subprocess
from operator import itemgetter, attrgetter, methodcaller
def conkyCAPsFailed(app):
print(f'conky [{app}] is not capable to run conky.arcs theme.')
print('conky.arcs needs conky with lua and cairo support.')
print('Try to install "conky-all" or use an appimage from ')
print('https://github.com/brndnmtthws/conky/releases')
print('')
exit(-1)
def first(iterable, condition = lambda x: True):
return next(x for x in iterable if condition(x))
def usage():
print('conky.arc is a theme for system monitor app "conky"')
print('this install-script evaluates your system and generates')
print('matching config file.')
print('')
print('if conky is not found by PATH environment, ...')
print('please provide the path to conky application as commandline ')
print('argument. Install script then checks capability of conky.')
print('')
exit(0)
class ConfigReader:
def __init__(self, conky):
hasLua, hasCairo = self.evalConky(conky)
if not hasLua or not hasCairo:
conkyCAPsFailed(conky)
self.app = conky
self.curdir = os.getcwd()
self.homedir = pathlib.Path.home()
self.sensors = self.getSensors()
self.nCPU = self.countCPU()
self.netIF = self.networkIF()
self.md = self.mounted_drives()
self.hds = self.harddisks()
self.hdTemps = self.driveTemps()
self.cpuFreqs()
def countCPU(self, maxCPU = 6):
cpus0 = glob.glob('/sys/devices/system/cpu/cpu?')
cpus1 = glob.glob('/sys/devices/system/cpu/cpu??')
cpus = sorted(cpus0 + cpus1)
return len(cpus)
def cpuFreqs(self):
f0 = 10000
f1 = 0
with open('/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq') as f:
for line in f:
f0 = int(line) / 1000
with open('/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq') as f:
for line in f:
f1 = int(line) / 1000
self.fCPU0 = f0
self.fCPU1 = f1
def driveTemps(self):
driveTemps = []
for d in glob.glob('/tmp/temps/*'):
p = d.split('/')
dt = {}
dt['name'] = p[3]
dt['path'] = d
driveTemps.append(dt)
return driveTemps
def evalConky(self, app):
p = pathlib.Path(app)
if not p.exists():
print('conky NOT found. Please install "conky-all"')
print('')
exit(0)
p = subprocess.Popen([app, '--version'], stdout=subprocess.PIPE)
line = p.stdout.readline()
hasLua = False
hasCairo = False
while line:
if line.strip().startswith(b'Lua bind'):
hasLua = True
line = p.stdout.readline()
while line.strip().startswith(b'*'):
parts = line.strip().split(b' ')
if parts[1] == b'Cairo':
hasCairo = True
return [hasLua, hasCairo]
line = p.stdout.readline()
line = p.stdout.readline()
return [hasLua, hasCairo]
def getSensors(self):
sensors = []
paths = glob.glob('/sys/class/hwmon/hwmon*')
for i in range(0, len(paths)):
sensor = {}
with open('/sys/class/hwmon/hwmon{}/name'.format(i)) as f:
name = f.read().strip()
sensor['type'] = name
sensor['name'] = name
if ('nvme' in name):
subname = first(glob.glob('/sys/class/hwmon/hwmon{0}/device/nvme*'.format(i)))
subname = os.path.basename(subname)
sensor['name'] = subname
elif ('spd5118' in name):
subname = 'SMBus PIIX4'
sensor['name'] = subname
temp = 0
path = '/sys/class/hwmon/hwmon{}/temp1_input'.format(i)
p = pathlib.Path(path)
if not p.exists():
continue
sensor['path'] = path
with open(path) as ft:
temp = float(ft.read()) / 1000.0
sensor['temp'] = temp
sensors.append(sensor)
sensors.sort(key=lambda x: x['name'], reverse=False)
return sensors
def mounted_drives(self):
drives = []
check = [] # avoid duplicates
with open('/proc/mounts') as f:
for line in f:
if not line.startswith('/'):
continue
if 'loop' in line:
continue
parts = line.split()
mountPoint = {}
if parts[0] in check:
continue
else:
check.append(parts[0])
sp = parts[0].split('/')
mountPoint['part'] = sp[2]
mountPoint['mounted'] = parts[1]
drives.append(mountPoint)
drives.sort(key=lambda x: x['mounted'], reverse=False)
return drives
def harddisks(self):
disks0 = sorted(glob.glob('/dev/sd?'))
disks1 = sorted(glob.glob('/dev/nvme?n?'))
hdds = {}
for d in disks0:
parts = d.split('/')
hdds[parts[2]] = d
for d in disks1:
parts = d.split('/')
hdds[parts[2]] = d
return hdds
def networkIF(self):
nif = []
with open('/proc/net/dev') as f:
for line in f:
ifName = line.split()[0]
if ifName == 'Inter-|' or ifName == 'face' or ifName == 'lo:':
continue
nif.append(ifName.split(':')[0])
return nif
def dump(self):
print('============================================================')
print('conky [{0}] has lua and cairo support'.format(self.app))
print('curdir:\t' + self.curdir)
print('homedir:\t' + str(self.homedir))
print('found {0} cpu cores'.format(self.nCPU))
if len(self.sensors) < 2:
print('NO temperatures for gpu!')
print('network interfaces:')
for n in self.netIF:
print('\tfound interface:\t{0}'.format(n))
print('harddisks:')
for d in self.hds:
print('\tfound disk:\t{0}'.format(d))
print('mounted partitions:')
for d in self.md:
print('\t{0}\twith path:\t{1}'.format(d['part'], d['mounted']))
print('sensors')
for s in self.sensors:
print('sensor {0} has temp {1}\t\tat: {2}'.format(s['name'], s['temp'], s['path']))
print('drive temperatures:')
for d in self.hdTemps:
print('drive {0} with temp-path {1}'.format(d['name'], d['path']))
print('============================================================')
class ConfigWriter:
def __init__(self, cfgReader):
self.cr = cfgReader
self.base = str(self.cr.homedir) + '/.conky/MX-Circles'
self.LuaTemplates = {}
self.ConkyTemplates = {}
self.ConkyTemplates['intro'] = """conky.config = {
background = false,
update_interval = 2,
cpu_avg_samples = 2,
net_avg_samples = 2,
temperature_unit = 'celsius',
double_buffer = true,
no_buffers = true,
text_buffer_size = 2048,
gap_x = 2,
gap_y = 50,
minimum_width = 1020,
minimum_height = 1200,
own_window = true,
own_window_type = 'normal',
own_window_transparent = true,
own_window_argb_visual = true,
own_window_hints = 'undecorated,below,sticky,skip_taskbar,skip_pager',
border_inner_margin = 0,
border_outer_margin = 0,
alignment = 'top_right',
draw_shades = false,
draw_outline = false,
draw_borders = false,
draw_graph_borders = false,
override_utf8_locale = true,
use_xft = true,
xftalpha = 0.5,
font = 'Cuprum:size=7',
top_cpu_separate = true,
lua_load = './conky.arcs.lua',
lua_draw_hook_post = 'main'
}
conky.text = [[
${voffset 460}"""
self.ConkyTemplates['diskRead'] = '\n${{goto {0}}}${{diskiograph_read 44, 300 ADFF2F 32CD32 -t -l}}'
self.ConkyTemplates['diskWrite'] = '\n${{goto {0}}}${{diskiograph_write 44, 300 FF0000 8B0000 -t -l}}'
self.ConkyTemplates['netDown'] = '\n${{goto {0}}}${{downspeedgraph {1} 21, 240 ADFF2F 32CD32 -t -l}}'
self.ConkyTemplates['netUp'] = '\n${{goto {0}}}${{upspeedgraph {1} 21, 240 FF0000 8B0000 -t -l}}'
self.ConkyTemplates['fin'] = '\n]]'
self.LuaTemplates['intro'] = """local config = {}
function config.setup()
return {"""
self.LuaTemplates['inter0'] = """
},
sub = {"""
self.LuaTemplates['inter1'] = """
},
rings = {"""
self.LuaTemplates['fin'] = """
}
end
return config"""
self.LuaTemplates['main0'] = """
x = 11,
y = 0,
fs = 18,
font = 'Cuprum',
hFont = 'Vast Shadow',
rCol = '95275C',
rBgC = '565656',
color = 'FFFFFF',
col1 = 'F2B70E',
col2 = 'E90812',
col3 = 'CDCDCD',
bgCol = '993636',
alpha = 0.9,
sb = false,
uptime = {
--[[
x/y the position where the text should be aligned to
a: L means text ends at x/y or is on the left side of position
a: R means text starts at x/y or is on the right side of position
text starting with '$' will be translated by conky engine
]]--
{ x = 37, y = 2, a = 'L', s = 30, text = 'Uptime' },
{ x = 38, y = 2, a = 'R', s = 30, text = '${uptime_short}' },
},
date = {"""
self.LuaTemplates['mainDate'] = """
{{ x = 27, y = {0}, a = 'L', s = 40, text = '${{time %A}}' }},
{{ x = 29, y = {0}, a = 'R', s = 40, text = '${{time %x}}' }},
}},
"""
self.LuaTemplates['mainTime'] = """
time = {{
{{ x = 35, y = {0}, a = 'L', s = 80, text = '${{time %H}}' }},
{{ x = 37, y = {0}, a = 'R', s = 80, text = ':' }},
{{ x = 41, y = {0}, a = 'R', s = 80, text = '${{time %M}}' }},
}},
sys = {{"""
self.LuaTemplates['main1'] = """
{{ x = 37, y = {0}, a = 'L', s = 20, text = 'public IP:' }},
{{ x = 38, y = {0}, a = 'R', s = 20, text = "${{execi 5 wget -q -O - checkip.dyndns.org | sed -e 's/[^[:digit:]\\\\|.]//g'}}" }},
{{ x = 15, y = {1}, a = 'R', s = 30, text = "${{execi 3600 cat /etc/mx-version | awk '{{ print $1 \\" \\" $2; }}' | sed -e 's/_/ /g'}}" }},
{{ x = 15, y = {2}, a = 'R', s = 20, text = "${{execi 3600 grep PRETTY_NAME /etc/os-release | sed -e 's/=/ /' | awk '{{ print $2 \\" \\" $3 \\" \\" $4 \\" \\" $5; }}' | sed -e 's/\\"//g'}}" }},"""
self.LuaTemplates['IOheaders'] = """
{{ x = 87, y = {0}, a = 'R', s = 25, text = 'network Traffic' }},
{{ x = 87, y = {1}, a = 'R', s = 25, text = 'disk Traffic' }},
}},
"""
self.LuaTemplates['netMain'] = "\n {{ x = 37, y = {0}, a = 'L', s = 20, text = 'local {1}:' }},\n {{ x = 38, y = {0}, a = 'R', s = 20, text = '${{addr {1}}}' }},"
self.LuaTemplates['cpuInit'] = """
cpu = {
x = 79,
y = 0,
w = 30,
h = 13,
level1 = 3500,
level2 = 4500,
main = {"""
self.LuaTemplates['cpuMain0'] = """
{{ x = 0, y = {0}, a = 'R', text = 'CPU' }},
{{ x = 15, y = {0}, a = 'L', text = '${{cpu cpu{1}}}%' }},"""
self.LuaTemplates['cpuMainN'] = """
{{ x = 0, y = {0}, a = 'R', text = 'CPU {1}' }},
{{ x = 10, y = {0}, a = 'L', text = '${{freq {1}}}' }},
{{ x = 15, y = {0}, a = 'L', text = '${{cpu cpu{1}}}%' }},"""
self.LuaTemplates['cpuTop'] = """
{{ x = 6, y = {0}, a = 'R', text = '${{top name {1}}}' }},
{{ x = 26, y = {0}, a = 'L', text = '${{top cpu {1}}}%' }},"""
self.LuaTemplates['cpuRing0'] = "\n {{ x = 15, y = {0}, r = {1}, h = 0.9, d = 'cw', name = 'cpu', arg = '', max = 100, sa = 0, ea = 300, ba = {2}, fg = 'F38A07' }},"
self.LuaTemplates['cpuRingN'] = "\n {{ x = 15, y = {0}, r = {1}, h = 0.9, d = 'cw', name = 'cpu', arg = 'cpu{2}', max = 100, sa = 0, ea = 300, ba = {3} }},"
self.LuaTemplates['cpuFin'] = """
},
},
"""
self.LuaTemplates['memInit'] = """
mem = {
x = 49,
y = 38,
w = 36,
h = 16,
main = {
{ x = 15, y = 1, a = 'R', text = 'Mem:' },
{ x = 28, y = 1, a = 'L', text = '${mem}' },
{ x = 29, y = 1, a = 'L', text = '/' },
{ x = 30, y = 1, a = 'R', text = '${memmax}' },
{ x = 15, y = 2, a = 'R', text = 'Swap:' },
{ x = 28, y = 2, a = 'L', text = '${swap}' },
{ x = 29, y = 2, a = 'L', text = '/' },
{ x = 30, y = 2, a = 'R', text = '${swapmax}' },
},
sub = {"""
self.LuaTemplates['memVal'] = """
{{ x = 15, y = {0}, a = 'R', text = '{2} Down' }},
{{ x = 36, y = {0}, a = 'L', text = '${{totaldown {2}}}' }},
{{ x = 15, y = {1}, a = 'R', text = '{2} UP' }},
{{ x = 36, y = {1}, a = 'L', text = '${{totalup {2}}}' }},
"""
self.LuaTemplates['memTop'] = """
{{ x = 10, y = {0}, a = 'R', text = '${{top_mem name {1}}}' }},
{{ x = 28, y = {0}, a = 'L', text = '${{top_mem mem {1}}}%' }},"""
self.LuaTemplates['memRing0'] = """
{{ x = 15, y = {0}, r = {1}, h = 0.9, d = 'ccw', name = 'memperc', arg = '', max = 100, sa = 0, ea = 65, ba = 0.8 }},
{{ x = 15, y = {0}, r = {2}, h = 0.5, d = 'ccw', name = 'swapperc', arg = '', max = 100, sa = 0, ea = 60, ba = 0.8 }},"""
self.LuaTemplates['memRingN'] = """
{{ x = 15, y = {0}, r = {1}, h = 0.8, d = 'ccw', name = 'downspeedf', arg = '{2}', max = 100, sa = 0, ea = 55, ba = {3} }},
{{ x = 15, y = {0}, r = {4}, h = 0.9, d = 'ccw', name = 'upspeedf', arg = '{2}', max = 100, sa = 0, ea = 45, ba = {3} }},"""
self.LuaTemplates['memFin'] = """ },
},
"""
self.LuaTemplates['hddInit'] = """
lh = 1,
lw = 1,
hdd = {
x = 87,
y = 60,
w = 29,
h = 6,
main = {"""
self.LuaTemplates['hddMain'] = """
{{ x = 11.5, y = {0}, a = 'R', text = '{1}' }},"""
self.LuaTemplates['hddSub'] = """
{{ x = 22, y = {0}, a = 'R', text = '{1}' }},"""
self.LuaTemplates['hddRing'] = """
{{ x = 11, y = {0}, r = {1}, h = 0.7, d = 'cw', name = 'fs_used_perc', arg = '{2}', max = 100, sa = 180, ea = 455, ba = {3} }},"""
self.LuaTemplates['hddFin'] = """ },
},
"""
self.LuaTemplates['sensorsInit'] = """
sensors = {
x = 36,
y = 17,
w = 31,
h = 16,
main = {"""
self.LuaTemplates['sensorsMain'] = """
{{ x = 10, y = {0}, a = 'R', text = 'LIF: printTemperatureMilli {1}' }},"""
self.LuaTemplates['sensorsName'] = """
{{ x = 9, y = {0}, a = 'L', text = '{1}' }},"""
self.LuaTemplates['sensorsRing'] = """
{{ x = 15, y = {0}, r = {1}, h = 0.8, d = 'cw', name = 'printTemperatureMilli', arg = '{2}', max = 90, sa = 0, ea = 270, ba = {3}}},"""
self.LuaTemplates['sensorsFin'] = """
},
},
"""
self.LuaTemplates['hddTempInit'] = """
hddTemp = {
x = 43,
y = 57,
w = 31,
h = 16,
main = {"""
self.LuaTemplates['hddTempMain'] = """
{{ x = 10, y = {0}, a = 'R', text = 'LIF: printTemperature {1}' }},"""
self.LuaTemplates['hddTempName'] = """
{{ x = 9, y = {0}, a = 'L', text = '{1}' }},"""
self.LuaTemplates['hddTempRing'] = """
{{ x = 15, y = {0}, r = {1}, h = 0.8, d = 'cw', name = 'printTemperature', arg = '{2}', max = 90, sa = 0, ea = 270, ba = {3}}},"""
self.LuaTemplates['hddTempFin'] = """
},
},"""
def copyFonts(self):
fd = '/usr/share/fonts/truetype/freefonts'
print("need to install some fonts\n")
subprocess.check_call(['sudo', 'mkdir', '-p', fd])
fonts = glob.glob('fonts/*.ttf')
for f in fonts:
subprocess.check_call(['sudo', 'cp', f, fd])
def install(self):
p = pathlib.Path(self.base)
if not p.exists():
os.makedirs(self.base)
self.copyFonts()
subprocess.check_call(['cp', 'conky.arcs.lua', self.base])
self.writeConkyConfig()
self.writeLuaConfig()
def writeConkyConfig(self):
with open(self.base + '/MX-Circles', 'w') as f:
f.write(self.ConkyTemplates['intro'])
for ifn in self.cr.netIF:
f.write(self.ConkyTemplates['netDown'].format(750, ifn))
for ifn in self.cr.netIF:
f.write(self.ConkyTemplates['netUp'].format(750, ifn))
f.write(self.ConkyTemplates['diskRead'].format(710))
f.write(self.ConkyTemplates['diskWrite'].format(710))
f.write(self.ConkyTemplates['fin'])
def writeLuaConfig(self):
with open(self.base + '/config.lua', 'w') as f:
f.write(self.LuaTemplates['intro'])
self.writeMainSection(f)
self.writeCpuSection(f)
self.writeIOSection(f)
self.writeMemSection(f)
self.writeHddSection(f)
self.writeSensorsSection(f)
self.writeHddTempSection(f)
f.write(self.LuaTemplates['fin'])
def writeMainSection(self, f):
f.write(self.LuaTemplates['main0'])
y = 5 + len(self.cr.netIF)
f.write(self.LuaTemplates['mainDate'].format(y))
y = 9 + len(self.cr.netIF)
f.write(self.LuaTemplates['mainTime'].format(y))
y = 3
for ifn in self.cr.netIF:
f.write(self.LuaTemplates['netMain'].format(y, ifn))
y += 1
y0 = y
y1 = 8 + y
y2 = 9 + y
f.write(self.LuaTemplates['main1'].format(y0, y1, y2))
y0 = 30 + len(self.cr.netIF) * 2
y1 = 36 + len(self.cr.netIF) * 3
f.write(self.LuaTemplates['IOheaders'].format(y0, y1))
def writeCpuSection(self, f):
f.write(self.LuaTemplates['cpuInit'])
f.write(self.LuaTemplates['cpuMain0'].format(1, 0))
for i in range(1, 1 + self.cr.nCPU):
f.write(self.LuaTemplates['cpuMainN'].format(1 + i, i))
f.write(self.LuaTemplates['inter0'])
for i in range(0, min(10, self.cr.nCPU)):
f.write(self.LuaTemplates['cpuTop'].format(3 + self.cr.nCPU + i, 1 + i))
f.write(self.LuaTemplates['inter1'])
trans = 0.7
f.write(self.LuaTemplates['cpuRing0'].format(1 + self.cr.nCPU, 2 + self.cr.nCPU, trans))
for i in range(0, self.cr.nCPU):
if (i % 2 == 0):
trans -= 0.1
trans = max(0.3, trans)
f.write(self.LuaTemplates['cpuRingN'].format(1 + self.cr.nCPU, 1 + self.cr.nCPU - i, 1 + i, trans))
f.write(self.LuaTemplates['cpuFin'])
def writeIOSection(self, f):
f.write("""
io = {
x = 73,
y = 28,
w = 35,
h = 9,
main = {
{ x = 15, y = 5, a = 'R', text = 'Disk Reads' },
{ x = 14, y = 5, a = 'L', text = '${diskio_read}' },
{ x = 15, y = 6, a = 'R', text = 'Disk Writes' },
{ x = 14, y = 6, a = 'L', text = '${diskio_write}' },
},
sub = {
{ x = 15, y = 7, a = 'R', text = '${top_io name 1}' },
{ x = 14, y = 7, a = 'L', text = '${top_io io_write 1}' },
{ x = 15, y = 8, a = 'R', text = '${top_io name 2}' },
{ x = 14, y = 8, a = 'L', text = '${top_io io_write 2}' },
{ x = 15, y = 9, a = 'R', text = '${top_io name 3}' },
{ x = 14, y = 9, a = 'L', text = '${top_io io_write 3}' },
},
rings = {
{ x = 6, y = 3, r = 2, h = 0.8, d = 'ccw', name = 'top_io io_perc 1', arg = '', max = 100, sa = 80, ea = 180, ba = 0.3 },
{ x = 6, y = 3, r = 3, h = 0.8, d = 'ccw', name = 'top_io io_perc 2', arg = '', max = 100, sa = 80, ea = 180, ba = 0.45 },
{ x = 6, y = 3, r = 4, h = 0.8, d = 'ccw', name = 'top_io io_perc 3', arg = '', max = 100, sa = 80, ea = 180, ba = 0.6 },
},
},
""")
def writeMemSection(self, f):
f.write(self.LuaTemplates['memInit'])
n=0
for nif in self.cr.netIF:
f.write(self.LuaTemplates['memVal'].format(3 + n, 4 + n, nif))
n += 2
mx = 2 * len(self.cr.netIF)
for i in range(1, min(8, 2 + mx)):
f.write(self.LuaTemplates['memTop'].format(3 + mx + i, i))
f.write(self.LuaTemplates['inter1'])
f.write(self.LuaTemplates['memRing0'].format(2 + mx, 3 + mx, 2 + mx))
n=0
trans = 0.6
for nif in self.cr.netIF:
f.write(self.LuaTemplates['memRingN'].format(2 + mx, 1 + mx - n, nif, trans, mx - n))
trans -= 0.2
n += 2
trans = max(0.3, trans)
f.write(self.LuaTemplates['memFin'])
def writeHddSection(self, f):
f.write(self.LuaTemplates['hddInit'])
mx = len(self.cr.md)
n=0
for mp in self.cr.md:
f.write(self.LuaTemplates['hddMain'].format(4 + n, mp['part']))
n += 1
f.write(self.LuaTemplates['inter0'])
n=0
for mp in self.cr.md:
f.write(self.LuaTemplates['hddSub'].format(4 + n, mp['mounted']))
n += 1
f.write(self.LuaTemplates['inter1'])
revDrives = self.cr.md
revDrives.sort(key=lambda x: x['mounted'], reverse=True)
trans = 0.9
n=0
for mp in revDrives:
f.write(self.LuaTemplates['hddRing'].format(0, 1 + mx - n, mp['mounted'], trans))
n += 1
if (n % 2 == 1):
trans -= 0.1
trans = max(0.3, trans)
f.write(self.LuaTemplates['hddFin'])
def writeSensorsSection(self, f):
f.write(self.LuaTemplates['sensorsInit'])
n=0
for s in self.cr.sensors:
f.write(self.LuaTemplates['sensorsMain'].format(1 + n, s['path']))
n += 1
f.write(self.LuaTemplates['inter0'])
n=0
for s in self.cr.sensors:
f.write(self.LuaTemplates['sensorsName'].format(1 + n, s['name']))
n += 1
f.write(self.LuaTemplates['inter1'])
mx = len(self.cr.sensors)
trans = 0.9
n=0
for s in self.cr.sensors:
f.write(self.LuaTemplates['sensorsRing'].format(mx, 1 + mx - n, s['path'], trans))
n += 1
trans -= 0.1
trans = max(0.3, trans)
f.write(self.LuaTemplates['sensorsFin'])
def writeHddTempSection(self, f):
f.write(self.LuaTemplates['hddTempInit'])
n=0
for d in self.cr.hdTemps:
f.write(self.LuaTemplates['hddTempMain'].format(1 + n, d['path']))
n += 1
f.write(self.LuaTemplates['inter0'])
n=0
for d in self.cr.hdTemps:
f.write(self.LuaTemplates['hddTempName'].format(1 + n, d['name']))
n += 1
f.write(self.LuaTemplates['inter1'])
mx = len(self.cr.hdTemps)
trans = 0.9
n=0
for d in self.cr.hdTemps:
f.write(self.LuaTemplates['hddTempRing'].format(mx, 1 + mx - n, d['path'], trans))
n += 1
trans -= 0.1
trans = max(0.3, trans)
f.write(self.LuaTemplates['hddTempFin'])
if __name__ == "__main__":
tmp = subprocess.check_output(["/bin/bash", "which", "conky"])
if not tmp:
usage()
conkyapp = tmp.decode('utf-8').strip()
if len(sys.argv) > 1:
if sys.argv[1] == '--help':
usage()
else:
p = pathlib.Path(sys.argv[1])
if p.exists():
conkyapp = sys.argv[1]
else:
usage()
cr = ConfigReader(conkyapp)
cr.dump()
cw = ConfigWriter(cr)
cw.install()
I need a bit to understand your setup hints, but I'll go for it.
... about polishing:
the installer is about to create the config setup from existing hardware.
As each group of rings is a single gui element, manual polishing by adjusting just x/y from the group is a question of few minutes.
As I noted, that the nvme-sensor does not reflect the temperature of the drive, but possibly the temperature of the mainboard chip, I added former used drive temperatures like this:
Can you post the config.lua from the installer on your system together with a screen shot?
Then I could check what to optimize.