first commit

This commit is contained in:
nojhan 2011-02-05 18:53:19 +01:00
commit 985c38af5e
3 changed files with 710 additions and 0 deletions

View file

@ -0,0 +1,112 @@
-- statusbar_workspace.lua
--
-- Show current workspace name or number in the statusbar.
--
-- Put any of these in cfg_statusbar.lua's template-line:
-- %workspace_name
-- %workspace_frame
-- %workspace_pager
-- %workspace_name_pager
-- %workspace_num_name_pager
--
-- This is an internal statusbar monitor and does NOT require
-- a dopath statement (effective after a 2006-02-12 build).
--
-- version 1
-- author: Rico Schiekel <fire at paranetic dot de>
--
-- version 2
-- added 2006-02-14 by Canaan Hadley-Voth:
-- * %workspace_pager shows a list of workspace numbers
-- with the current one indicated:
--
-- 1i 2i [3f] 4p 5c
--
-- i=WIonWS, f=WFloatWS, p=WPaneWS, c=WClientWin/other
--
-- * %workspace_frame - name of the active frame.
--
-- * Added statusbar_ to the filename (since it *is*
-- an internal statusbar monitor) so that it works without
-- a "dopath" call.
--
-- * Removed timer. Only needs to run on hook.
-- Much faster this way.
--
-- version 3
-- update for ion-3rc-20070506 on 2007-05-09
-- by Kevin Granade <kevin dot granade at gmail dot com>
--
-- Updated to use new wx_ api
-- Replaced region_activated_hook with region_notify_hook
-- Added %workspace_name_pager, which works similarly to %workspace_pager,
-- but instead displays the name of each workspace
-- Added display for WGroupWS to %workspace_pager, displayed as 'g'
--
local function update_frame()
local fr
ioncore.defer( function()
local cur=ioncore.current()
if obj_is(cur, "WClientWin") and
obj_is(cur:parent(), "WMPlex") then
cur=cur:parent()
end
fr=cur:name()
mod_statusbar.inform('workspace_frame', fr)
mod_statusbar.update()
end)
end
local function update_workspace()
local scr=ioncore.find_screen_id(0)
local curws = scr:mx_current()
local wstype, c
local pager=""
local name_pager=""
local name_pager_plus=""
local curindex = scr:get_index(curws)+1
n = scr:mx_count(1)
for i=1,n do
tmpws=scr:mx_nth(i-1)
wstype=obj_typename(tmpws)
if wstype=="WIonWS" then
c="i"
elseif wstype=="WFloatWS" then
c="f"
elseif wstype=="WPaneWS" then
c="p"
elseif wstype=="WGroupWS" then
c="g"
else
c="c"
end
if i==curindex then
name_pager_plus=name_pager_plus.."["..tmpws:name().."]"
name_pager=name_pager.."["..tmpws:name().."]"
pager=pager.."["..(i).."]"
--pager=pager.." ["..(i)..c.."] "
else
name_pager_plus=name_pager_plus.." "..(i)..":"..tmpws:name()
name_pager=name_pager.." "..tmpws:name()
pager=pager.." "..(i).." "
--pager=pager.." "..(i)..c.." "
end
end
local fr,cur
-- Older versions without an ioncore.current() should
-- skip update_frame.
update_frame()
ioncore.defer( function()
mod_statusbar.inform('workspace_pager', pager)
mod_statusbar.inform('workspace_name', curws:name())
mod_statusbar.inform('workspace_name_pager', name_pager)
mod_statusbar.inform('workspace_num_name_pager', name_pager_plus)
mod_statusbar.update()
end)
end
ioncore.get_hook("region_notify_hook"):add(update_workspace)

View file

@ -0,0 +1,213 @@
-- statusd_laptopstatus.lua v0.0.2 (last modified 2005-06-13)
--
-- Copyright (C) 2005 Jari Eskelinen <jari.eskelinen@iki.fi>
-- modified by René van Bevern <rvb@pro-linux.de> for error handling
--
-- Permission to copy, redistirbute, modify etc. is granted under the terms
-- of GNU GENERAL PUBLIC LICENSE Version 2.
--
-- This is script for displaying some interesting information about your
-- laptops power saving in Ion's status monitor. Script is very Linux
-- specific (uses /proc interface) and needs ACPI -support new enough (don't
-- know exactly but 2.6.x kernels should be fine). Also if you have some
-- kind of exotic hardware (multiple processors, multiple batteries etc.)
-- this script probably will fail or show incorrect information.
--
-- Just throw this script under ~/.ion3 and add following keywords to your
-- cfg_statusbar.lua's template-line with your own taste:
--
-- %laptopstatus_cpuspeed
-- %laptopstatus_temperature
-- %laptopstatus_batterypercent
-- %laptopstatus_batterytimeleft
-- %laptopstatus_batterydrain
--
-- Template example: template="[ %date || load:% %>load || CPU: %laptopstatus_cpuspeed %laptopstatus_temperature || BATT: %laptopstatus_batterypercent %laptopstatus_batterytimeleft %laptopstatus_batterydrain ]"
--
-- You can also run this script with lua interpreter and see if you get
-- right values.
--
-- NOTICE: This is my first ion/lua-script, so probably this can be done better.
-- Feel free to improve this script.
--
-- TODO: * Is it stupid to use file:read("*all"), can this cause infinite
-- loops in some weird situations?
-- * Do not poll for information not defined in template to be used
-- * Auto-detect right acpi devices instead of hardcoded BATT0 etc.
--
-- SETTINGS
--
if not statusd_laptopstatus then
statusd_laptopstatus = {
interval = 10, -- Polling interval in seconds
temperature_important = 66, -- Temperature which will cause important hint
temperature_critical = 71, -- Temperature which will cause critical hint
batterypercent_important = 10, -- Battery percent which will cause important hint
batterypercent_critical = 5, -- Battery percent which will cause critical hint
batterytimeleft_important = 600, -- Battery time left (in secs) which will cause important hint
batterytimeleft_critical = 300, -- Battery time left (in secs) which will cause critical hint
ac_state = {"/proc/acpi/ac_adapter/AC/state",
"/proc/acpi/ac_adapter/ACAD/state",
"/proc/acpi/ac_adapter/ADP0/state",
"/proc/acpi/ac_adapter/ADP1/state"},
temp_info = {"/proc/acpi/thermal_zone/THRM/temperature",
"/proc/acpi/thermal_zone/THM/temperature",
"/proc/acpi/thermal_zone/THM0/temperature",
"/proc/acpi/thermal_zone/THM1/temperature"},
bat_info = {"/proc/acpi/battery/BAT0/info",
"/proc/acpi/battery/BAT1/info"},
bat_state = {"/proc/acpi/battery/BAT0/state",
"/proc/acpi/battery/BAT1/state"}
}
end
statusd_laptopstatus=table.join(statusd.get_config("laptopstatus"), statusd_laptopstatus)
--
-- CODE
--
local laptopstatus_timer
function try_open(files, mode)
for _, file in pairs(files) do
local fd = io.open(file, mode)
if fd then return fd, file end
end
end
local function get_cpu()
local mhz, hint
if pcall(function ()
local status
local file = io.open("/proc/cpuinfo", "r")
status, _, mhz = string.find(file:read("*all"),
"cpu MHz%s+: (%d+)")
if not status then error("could not get MHz") end
file:close()
end)
then return {speed=string.format("%4dMHz", math.ceil(mhz/5)*5),
hint=hint}
else return {speed="n/a", hint=hint} end
end
local function get_ac()
local file = try_open(statusd_laptopstatus.ac_state, "r")
if not string.find(file:read("*all"), "state:%s+on.line") then return 0
else return 1 end
file:close()
end
local function get_thermal()
local temp, hint = nil, "normal"
if pcall(function ()
local status
local file=try_open(statusd_laptopstatus.temp_info, "r")
status, _, temp = string.find(file:read("*all"),
"temperature:%s+(%d+).*")
if not status then error("could not get temperature") end
temp = tonumber(temp)
file:close();
end)
then if temp >= statusd_laptopstatus.temperature_important then
hint = "important" end
if temp >= statusd_laptopstatus.temperature_critical then
hint = "critical" end
return {temperature=string.format("%02dC", temp), hint=hint}
else return {temperature="n/a", hint = "hint"} end
end
local function get_battery()
local percenthint = "normal"
local timelefthint = "normal"
local lastfull, rate, rateunit, remaining
if pcall(function ()
local status
local file=try_open(statusd_laptopstatus.bat_info, "r")
local infocontents = file:read("*all")
file:close();
local file=try_open(statusd_laptopstatus.bat_state, "r")
local statecontents = file:read("*all")
file:close();
status, _, lastfull = string.find(infocontents, "last full capacity:%s+(%d+).*")
if not status then error("could not get full battery capacity") end
lastfull = tonumber(lastfull)
if string.find(statecontents, "present rate:%s+unknown.*") then
rate = -1
else
status, _, rate, rateunit = string.find(statecontents, "present rate:%s+(%d+)(.*)")
if not status then error("could not get battery draining-rate") end
rate = tonumber(rate)
end
status, _, remaining = string.find(statecontents, "remaining capacity:%s+(%d+).*")
if not status then error("could not get remaining capacity") end
remaining = tonumber(remaining)
end) then
local percent = math.floor(remaining / lastfull * 100 + 5/10)
local timeleft
local hours, secs, mins
if get_ac() == 1 then
timeleft = " *AC*"
elseif rate <= 0 then
timeleft = "n/a"
else
secs = 3600 * (remaining / rate)
mins = secs / 60
hours = math.floor(mins / 60)
mins = math.floor(mins - (hours * 60))
timeleft = string.format("%02d:%02d", hours, mins)
end
if secs ~= nil and secs <= statusd_laptopstatus.batterytimeleft_important then timelefthint = "important" end
if secs ~= nil and secs <= statusd_laptopstatus.batterytimeleft_critical then timelefthint = "critical" end
if percent <= statusd_laptopstatus.batterypercent_important then percenthint = "important" end
if percent <= statusd_laptopstatus.batterypercent_critical then percenthint = "critical" end
return { percent=string.format("%02d%%", percent), timeleft=timeleft, drain=tostring(rate)..rateunit, percenthint=percenthint, timelefthint=timelefthint}
else return { percent="n/a", timeleft="n/a", drain="n/a", percenthint=percenthint, timelefthint=timelefthint} end
end
local last_timeleft = nil
local function update_laptopstatus ()
cpu = get_cpu()
thermal = get_thermal()
battery = get_battery()
-- Informing statusd OR printing to stdout if statusd not present
if statusd ~= nil then
statusd.inform("laptopstatus_cpuspeed", cpu.speed)
statusd.inform("laptopstatus_cpuspeed_template", "xxxxMHz")
statusd.inform("laptopstatus_cpuspeed_hint", cpu.hint)
statusd.inform("laptopstatus_temperature", thermal.temperature)
statusd.inform("laptopstatus_temperature_template", "xxxC")
statusd.inform("laptopstatus_temperature_hint", thermal.hint)
statusd.inform("laptopstatus_batterypercent", battery.percent)
statusd.inform("laptopstatus_batterypercent_template", "xxx%")
statusd.inform("laptopstatus_batterypercent_hint", battery.percenthint)
if battery.timeleft ~= "n/a" or last_timeleft == " *AC*" then
statusd.inform("laptopstatus_batterytimeleft", battery.timeleft)
last_timeleft = battery.timeleft
end
statusd.inform("laptopstatus_batterytimeleft_template", "hh:mm")
statusd.inform("laptopstatus_batterytimeleft_hint", battery.timelefthint)
statusd.inform("laptopstatus_batterydrain", battery.drain)
laptopstatus_timer:set(statusd_laptopstatus.interval*1000, update_laptopstatus)
else
io.stdout:write("CPU: "..cpu.speed.." "..thermal.temperature.." || BATT: "..battery.percent.." "..battery.timeleft.."\n")
end
end
if statusd ~= nil then
laptopstatus_timer = statusd.create_timer()
end
update_laptopstatus()

385
.ion3/statusd_vv.lua Normal file
View file

@ -0,0 +1,385 @@
require "lfs"
local settings = {
-- refresh intervall in milliseconds
interval = 1000,
-- only monitors below will be updated
-- numbers are multipliers of refresh intervall
monitors = {
--cpufreq = 1,
cpucharge = 1,
--temperature = 5,
memory = 1,
network = 1,
battery = 3,
mail = 5,
disk = 60,
sound = 1,
uptime = 60},
-- default settings
cpu0_important = 50,
cpu0_critical = 90,
cpu1_important = 50,
cpu1_critical = 90,
cpu2_important = 50,
cpu2_critical = 90,
cpufreq_important = 801,
cpufreq_critical = 2800,
temperature_important = 50,
temperature_critical = 70,
memfree_important = 2^20,
memfree_critical = 500*2^10,
battery_important = 10,
battery_critical = 5,
rxbytes_important = 5*10^5,
rxbytes_critical = 10^6,
rxtotal_important = 10^6,
rxtotal_critical = 10^9,
txbytes_important = 5*10^5,
txbytes_critical = 10^6,
txtotal_important = 10^6,
txtotal_critical = 10^9,
directories = {"/", "/home"},
disk__important = 2*2^20,
disk__critical = 1*2^20,
disk_home_important = 2*2^20,
disk_home_critical = 1*2^20,
disk_tmp_important = 2^20,
disk_tmp_critical = 500*2^10,
mailbox = "mail/inbox",
sound_file = "/tmp/sound-modified"
}
settings = table.join(statusd.get_config("vv"), settings)
------------------------------------------------------------------------------------------------------------------------
--
-- Helpers
--
------------------------------------------------------------------------------------------------------------------------
local function read_file(file, mode)
local file, value = io.open(file), nil
if file then value = file:read(mode) file:close() end
return value
end
local function read_string(file) return read_file(file, "*l") end
local function read_number(file) return read_file(file, "*n") end
local function read_popen(cmd, mode)
local file, value = io.popen(cmd), nil
if file then value = file:read("*a") file:close() end
return value
end
local function read_string(file) return read_file(file, "*l") end
local function read_number(file) return read_file(file, "*n") end
local modified_table = {}
local function modified(file)
local modif = lfs.attributes(file, "change")
if not modif or modif == modified_table[file] then return false end
modified_table[file] = modif
return true
end
local function mkunit(n)
if n > 2^20 then return string.format("%.1fG", n / 2^20)
elseif n > 2^10 then return string.format("%.1fM", n / 2^10)
else return n.."k" end
end
------------------------------------------------------------------------------------------------------------------------
--
-- statusd.inform wrappers
--
------------------------------------------------------------------------------------------------------------------------
local function inform1(name, value, hint)
statusd.inform("vv_"..name, value)
end
function inform_hint(monitor, val)
local critical = settings[monitor.."_critical"]
local important = settings[monitor.."_important"]
if not critical or not important then return end
local dir = important <= critical
if (dir and val >= critical) or (not dir and val <= critical) then inform1(monitor.."_hint", "critical")
elseif (dir and val >= important) or (not dir and val <= important) then inform1(monitor.."_hint", "important")
else inform1(monitor.."_hint", "normal") end
end
local function inform(name, value, hint)
inform1(name, value)
if hint then inform_hint(name, hint) end
end
------------------------------------------------------------------------------------------------------------------------
--
-- CPU frequency
--
------------------------------------------------------------------------------------------------------------------------
local nb_cpus = 2
--tonumber(string.match(read_string("/sys/devices/system/cpu/online"), "(%d+)$")) + 1
function get_cpufreq()
local cpu = ""
for i = 0, nb_cpus - 1 do
if i > 0 then cpu = cpu.." " end
cpu = cpu..(read_number("/sys/devices/system/cpu/cpu"..i.."/cpufreq/scaling_cur_freq") / 1000).."MHz"
end
inform("cpufreq", "("..cpu..")", cpufreq)
end
------------------------------------------------------------------------------------------------------------------------
--
-- CPU charge
--
------------------------------------------------------------------------------------------------------------------------
local user, nice, system, idle = {}, {}, {}, {}
for i = 0, nb_cpus do user[i], nice[i], system[i], idle[i] = 0, 0, 0, 0 end
function get_cpucharge()
local file = io.open("/proc/stat")
for i = 0, nb_cpus do
local n_user, n_nice, n_system, n_idle = string.match( file:read("*l"), "^cpu%d*%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)")
local charge = n_user - user[i] + n_nice - nice[i] + n_system - system[i]
local allcharge = charge + n_idle - idle[i]
local cpu = (allcharge == 0 and 100) or math.ceil(100 * charge / allcharge)
user[i], nice[i], system[i], idle[i] = n_user, n_nice, n_system, n_idle
inform("cpu"..i, string.sub(cpu.."%", 1, 4), cpu)
end
file:close()
end
------------------------------------------------------------------------------------------------------------------------
--
-- CPU temperature
--
------------------------------------------------------------------------------------------------------------------------
function get_temperature()
local temperature = read_number("/sys/class/thermal/thermal_zone0/temp") / 1000
inform("temperature", math.ceil(temperature).."°C", temperature)
end
------------------------------------------------------------------------------------------------------------------------
--
-- Memory usage
--
------------------------------------------------------------------------------------------------------------------------
function get_memory()
local mem = {}
for line in io.lines("/proc/meminfo") do
local attribute, qty = string.match(line, "^(%S+):%s+(%d+) kB$")
if attribute then string.gsub(attribute, "[()]", "")
mem[attribute] = qty
end
end
local memfree = tonumber(mem.MemFree) + tonumber(mem.Buffers) + tonumber(mem.Cached)
inform("memfree", mkunit(memfree), memfree)
inform("swapused", mkunit(tonumber(mem.SwapTotal) - tonumber(mem.SwapFree)))
end
------------------------------------------------------------------------------------------------------------------------
--
-- Network load
--
------------------------------------------------------------------------------------------------------------------------
local interfaces, iface_old, last_rx_bytes, last_tx_bytes = {}, nil, 0, 0
for iface in lfs.dir("/sys/class/net/") do
table.insert(interfaces, iface)
end
function get_network()
local function mkunit(rx)
if rx > 10^9 then return string.sub(string.format("%.1fG", rx / 10^9), 1, 6)
elseif rx > 10^6 then return string.sub(string.format("%.1fM", rx / 10^6), 1, 6)
else return string.sub(string.format("%.1fk", rx / 1000), 1, 6) end
end
local path = "/sys/class/net/"
local iface
if old_iface and read_string(path..old_iface.."/operstate") == "up" then iface = old_iface
else
for _, i in ipairs(interfaces) do
if read_string(path..i.."/operstate") == "up" then iface, old_iface = i, i break end
end
end
if iface then
local rx = read_number(path..iface.."/statistics/rx_bytes")
local tx = read_number(path..iface.."/statistics/tx_bytes")
local rx2, tx2 = rx - last_rx_bytes, tx - last_tx_bytes
last_rx_bytes, last_tx_bytes = rx, tx
inform("iface", iface..":")
inform("rxbytes", mkunit(rx2), rx2)
inform("rxtotal", mkunit(rx), rx)
inform("txbytes", mkunit(tx2), tx2)
inform("txtotal", mkunit(tx), tx)
else
inform("iface", "net: off")
inform("rxbytes", "")
inform("rxtotal", "")
inform("txbytes", "")
inform("txtotal", "")
end
end
------------------------------------------------------------------------------------------------------------------------
--
-- Disk usage
--
------------------------------------------------------------------------------------------------------------------------
local dirnames = {}
for i, dir in ipairs(settings.directories) do
dirnames[i] = "disk"..string.gsub(dir, "/", "_")
end
function get_disk()
local df = read_popen("/bin/df")
if df then
for i, dir in ipairs(settings.directories) do
local unused_s, used = string.match(df, "(%d+)%s+(%S+)%s+"..dir.."\n")
local unused = tonumber(unused_s)
if used then inform(dirnames[i], dir.." "..used.." "..mkunit(unused), unused) end
end
end
end
------------------------------------------------------------------------------------------------------------------------
--
-- Sound (alsa)
--
------------------------------------------------------------------------------------------------------------------------
function get_sound()
if modified(settings.sound_file) then
local function snd ()
local master, status = string.match(read_popen("/usr/bin/amixer get Master"), "%[(.+)%] %[.+%[(.+)%]")
local hint = (status == "on" and "critical") or "normal"
inform("master", master)
inform("master_hint", hint)
inform("pcm", string.match(read_popen("/usr/bin/amixer get PCM"), "Front.*%[(.+)%] %[.+%].*Front"))
inform("pcm_hint", hint)
end
if not pcall(snd) then lfs.touch(settings.sound_file) end
end
end
------------------------------------------------------------------------------------------------------------------------
--
-- Uptime
--
------------------------------------------------------------------------------------------------------------------------
function get_uptime()
local sec = read_number("/proc/uptime")
local min = math.floor(sec / 60)
local hours = math.floor(min / 60)
local days = math.floor(hours / 24)
days = (days > 1 and days.." days, ") or (days > 0 and days.." day, ") or ""
inform("uptime", string.format(days.."%02d:%02d", hours % 24, min % 60))
end
------------------------------------------------------------------------------------------------------------------------
--
-- Mail (Maildir format)
--
------------------------------------------------------------------------------------------------------------------------
inform("mailnew_hint", "critical")
inform("mailunread_hint", "important")
function get_mail()
local function read_dir(mailbox)
if not modified(mailbox) then return nil end
local old, new = 0, -2
for line in lfs.dir(mailbox) do
if string.match(line, "S$") then old = old + 1 else new = new + 1 end
end
return new, old
end
local new = read_dir(settings.mailbox.."/new")
local unread, old = read_dir(settings.mailbox.."/cur")
if new then
if new > 0 then inform("mailnew", "("..new.." new) ")
else inform("mailnew", "") end
end
if old then
if unread > 0 then inform("mailunread", "("..unread.." unread) ")
else inform("mailunread", "") end
inform("mailold", old.." ")
end
end
------------------------------------------------------------------------------------------------------------------------
--
-- Battery usage
--
------------------------------------------------------------------------------------------------------------------------
function get_battery(num)
local charge_now_total, charge_full_total, percent_max, charging, rate, status = 0, 0, 0, false, nil
local path = "/sys/class/power_supply/"
for device in lfs.dir(path) do
local batt = path..device
if read_string(batt.."/type") == "Battery" then
local state = read_string(batt.."/status")
local charge_full = read_number(batt.."/charge_full")
local charge_now = math.min(read_number(batt.."/charge_now"), charge_full)
local percent = math.floor(charge_now / charge_full * 100)
percent_max = math.max(percent, percent_max)
status = ((status and status.."|") or "")..percent.."%"
if state == "Discharging" then rate = (rate or 0) + read_number(batt.."/current_now")
elseif state == "Charging" then charging = true end
charge_now_total = charge_now_total + charge_now
charge_full_total = charge_full_total + charge_full
end
end
if not status then status = "none"
elseif charging then status = status.." - charging"
elseif rate then
local hours = charge_now_total / rate
status = status..string.format(" %02d:%02d %dmW", hours, hours * 60 % 60, rate / 1000)
end
inform("battery", status, percent_max)
end
------------------------------------------------------------------------------------------------------------------------
--
-- Main
--
------------------------------------------------------------------------------------------------------------------------
local cycle = 0
local vv_timer = statusd.create_timer()
local monitors = {}
inform("debug", "")
inform("debug_hint", "critical")
for name, factor in pairs(settings.monitors) do
if factor > 0 then monitors[_G["get_"..name]] = factor end
end
local function update_vv ()
for func, factor in pairs(monitors) do
if cycle % factor == 0 then
local ret, mess = pcall(func)
if not ret then inform("debug", "err: "..mess) end
end
end
cycle = cycle + 1
vv_timer:set(settings.interval, update_vv)
end
update_vv()