SimpleConkyScript/lua/system.lua

135 lines
4.6 KiB
Lua

-- HorlogeSkynet's Lua script (for Conky) -- System module
-- <https://git.forestier.app/HorlogeSkynet/SimpleConkyScript.git>
local json = require('cjson.safe')
local system = {}
-- `config` object is passed as parameter here.
local _settings = (...).get_entries('settings')
-- Handy wrapper to `io.popen` to execute, read output from and pre-format the passed command.
function system.get_subcommand_output(command)
local handle = io.popen(command)
local output = handle:read('*all')
io.close(handle)
-- No output could be fetched from STDOUT.
if #output == 0 then return end
-- Replace new-lines characters by regular space.
output = string.gsub(output, '\n', ' ')
-- Right-trim the final output.
output = string.gsub(output, "^(.-) *$", '%1')
return output
end
-- Simple function to extract and return screen dimensions from a subcommand output as `${WIDTH}x${HEIGHT}`.
function system.get_screen_resolution()
local xdpyinfo_output = system.get_subcommand_output(_settings.display.resolution_exec)
local width, height = string.match(xdpyinfo_output, "(%d+)x(%d+)")
return tonumber(width), tonumber(height)
end
-- Compute and return the average value measured from the specified sensor chip sub-features values.
-- `is_fan` is a boolean that MUST be set to `true` when dealing with a fan control chip.
function system.compute_avg_chip_value(chip_name, is_fan)
-- Due to <https://github.com/lm-sensors/lm-sensors/pull/196>, we won't use LM-SENSORS's `-f` option at the moment.
local sensors_output = system.get_subcommand_output(
string.format("sensors -A -j \'%s\'", chip_name))
if not sensors_output then
io.stderr:write("Couldn\'t execute `sensors` subcommand.\n")
return
end
local chip_output, error_message = json.decode(sensors_output)
if not chip_output then
io.stderr:write(
string.format("Couldn\'t decode `sensors` JSON output : %s.\n", error_message))
return
end
if not chip_output[chip_name] then
io.stderr:write(
string.format("Specified sensor (\'%s\') could not be found.\n", chip_name))
return
end
local count, average_value = 0, 0.0
for _, subfeatures in pairs(chip_output[chip_name]) do
for name, value in pairs(subfeatures) do
-- These conditions check whether this sub-feature value is a correct candidate, as :
-- * It might be an input value for an unwanted control chip type ;
-- * Some chips/adapters might return null (temperatures) values.
-- According to LM-SENSORS, sub-features input values are labeled as `{fan,temp}\d_input`.
if name:match(((is_fan and 'fan') or 'temp') .. "%d_input") and (value ~= 0.0 or is_fan) then
count, average_value = count + 1, average_value + value
-- There is only one `${chip_type}*_input` field per sub-feature.
-- We may stop stop the current iteration at this step.
break
end
end
end
if count == 0 then
io.stderr:write(string.format("Couldn\'t retrieve any value from \'%s\' chip.\n", chip_name))
return
end
-- For temperature, and when Fahrenheit unit is specified, let's perform a manual conversion.
if not is_fan and string.upper(_settings.temperature.unit) == 'F' then
average_value = (average_value * (9 / 5.)) + 32
end
return (average_value / count)
end
-- Return the temperature of the passed drive name.
function system.get_drive_temp(drive_name, wake_up)
local hddtemp_output = system.get_subcommand_output(
string.format(
"hddtemp \'%s\' -n -u \'%s\' %s",
drive_name,
_settings.temperature.unit,
((wake_up and '-w') or '')))
return tonumber(hddtemp_output)
end
-- Specific function to compute the ratio percentage between current and maximum brightness values.
function system.get_brightness_value(cur_file, max_file)
local handle
handle = io.open(cur_file)
local cur_brightness = tonumber(handle:read('*all'))
io.close(handle)
handle = io.open(max_file)
local max_brightness = tonumber(handle:read('*all'))
io.close(handle)
return (cur_brightness / max_brightness) * 100
end
-- Simple function to ask Conky about a network interface status (up/down).
-- See `if_up_strictness` Conky configuration option, as the result hard-depends on it.
function system.is_network_interface_up(if_name)
local if_up = conky_parse(string.format("${if_up %s}1${else}0${endif}", if_name))
return (if_up == '1')
end
return system