[UP] change update interval.
[arrow.git] / archlinux_conf / etc / ion3 / statusd_laptopstatus.lua
blob65371ac857c2ffcf79f9a61d58392647d59e3b01
1 -- statusd_laptopstatus.lua v0.0.2 (last modified 2005-06-13)
2 --
3 -- Copyright (C) 2005 Jari Eskelinen <jari.eskelinen@iki.fi>
4 -- modified by René van Bevern <rvb@pro-linux.de> for error handling
5 --
6 -- Permission to copy, redistirbute, modify etc. is granted under the terms
7 -- of GNU GENERAL PUBLIC LICENSE Version 2.
8 --
9 -- This is script for displaying some interesting information about your
10 -- laptops power saving in Ion's status monitor. Script is very Linux
11 -- specific (uses /proc interface) and needs ACPI -support new enough (don't
12 -- know exactly but 2.6.x kernels should be fine). Also if you have some
13 -- kind of exotic hardware (multiple processors, multiple batteries etc.)
14 -- this script probably will fail or show incorrect information.
16 -- Just throw this script under ~/.ion3 and add following keywords to your
17 -- cfg_statusbar.lua's template-line with your own taste:
19 -- %laptopstatus_cpuspeed
20 -- %laptopstatus_temperature
21 -- %laptopstatus_batterypercent
22 -- %laptopstatus_batterytimeleft
23 -- %laptopstatus_batterydrain
24 --
25 -- Template example: template="[ %date || load:% %>load || CPU: %laptopstatus_cpuspeed %laptopstatus_temperature || BATT: %laptopstatus_batterypercent %laptopstatus_batterytimeleft %laptopstatus_batterydrain ]"
27 -- You can also run this script with lua interpreter and see if you get
28 -- right values.
30 -- NOTICE: This is my first ion/lua-script, so probably this can be done better.
31 -- Feel free to improve this script.
33 -- TODO: * Is it stupid to use file:read("*all"), can this cause infinite
34 -- loops in some weird situations?
35 -- * Do not poll for information not defined in template to be used
36 -- * Auto-detect right acpi devices instead of hardcoded BATT0 etc.
39 -- SETTINGS
42 if not statusd_laptopstatus then
43 statusd_laptopstatus = {
44 interval = 10, -- Polling interval in seconds
45 temperature_important = 66, -- Temperature which will cause important hint
46 temperature_critical = 71, -- Temperature which will cause critical hint
47 batterypercent_important = 10, -- Battery percent which will cause important hint
48 batterypercent_critical = 5, -- Battery percent which will cause critical hint
49 batterytimeleft_important = 600, -- Battery time left (in secs) which will cause important hint
50 batterytimeleft_critical = 300, -- Battery time left (in secs) which will cause critical hint
51 ac_state = {"/proc/acpi/ac_adapter/AC/state",
52 "/proc/acpi/ac_adapter/ACAD/state",
53 "/proc/acpi/ac_adapter/ADP0/state",
54 "/proc/acpi/ac_adapter/ADP1/state"},
55 temp_info = {"/proc/acpi/thermal_zone/THRM/temperature",
56 "/proc/acpi/thermal_zone/THM/temperature",
57 "/proc/acpi/thermal_zone/THM0/temperature",
58 "/proc/acpi/thermal_zone/THM1/temperature"},
59 bat_info = {"/proc/acpi/battery/BAT0/info",
60 "/proc/acpi/battery/BAT1/info"},
61 bat_state = {"/proc/acpi/battery/BAT0/state",
62 "/proc/acpi/battery/BAT1/state"}
64 end
66 if statusd == nil then
67 return
68 end
69 statusd_laptopstatus=table.join(statusd.get_config("laptopstatus"), statusd_laptopstatus)
72 -- CODE
74 local laptopstatus_timer
76 function try_open(files, mode)
77 for _, file in pairs(files) do
78 local fd = io.open(file, mode)
79 if fd then return fd, file end
80 end
81 end
83 local function get_cpu()
84 local mhz, hint
85 if pcall(function ()
86 local status
87 local file = io.open("/proc/cpuinfo", "r")
88 status, _, mhz = string.find(file:read("*all"),
89 "cpu MHz%s+: (%d+)")
90 if not status then error("could not get MHz") end
91 file:close()
92 end)
93 then return {speed=string.format("%4dMHz", math.ceil(mhz/5)*5),
94 hint=hint}
95 else return {speed="n/a", hint=hint} end
96 end
99 local function get_ac()
100 local file = try_open(statusd_laptopstatus.ac_state, "r")
101 if not string.find(file:read("*all"), "state:%s+on.line") then return 0
102 else return 1 end
103 file:close()
107 local function get_thermal()
108 local temp, hint = nil, "normal"
110 if pcall(function ()
111 local status
112 local file=try_open(statusd_laptopstatus.temp_info, "r")
113 status, _, temp = string.find(file:read("*all"),
114 "temperature:%s+(%d+).*")
115 if not status then error("could not get temperature") end
116 temp = tonumber(temp)
117 file:close();
118 end)
119 then if temp >= statusd_laptopstatus.temperature_important then
120 hint = "important" end
121 if temp >= statusd_laptopstatus.temperature_critical then
122 hint = "critical" end
123 return {temperature=string.format("%02dC", temp), hint=hint}
124 else return {temperature="n/a", hint = "hint"} end
128 local function get_battery()
129 local percenthint = "normal"
130 local timelefthint = "normal"
131 local lastfull, rate, rateunit, remaining
133 if pcall(function ()
134 local status
135 local file=try_open(statusd_laptopstatus.bat_info, "r")
136 local infocontents = file:read("*all")
137 file:close();
139 local file=try_open(statusd_laptopstatus.bat_state, "r")
140 local statecontents = file:read("*all")
141 file:close();
143 status, _, lastfull = string.find(infocontents, "last full capacity:%s+(%d+).*")
144 if not status then error("could not get full battery capacity") end
145 lastfull = tonumber(lastfull)
146 if string.find(statecontents, "present rate:%s+unknown.*") then
147 rate = -1
148 else
149 status, _, rate, rateunit = string.find(statecontents, "present rate:%s+(%d+)(.*)")
150 if not status then error("could not get battery draining-rate") end
151 rate = tonumber(rate)
153 status, _, remaining = string.find(statecontents, "remaining capacity:%s+(%d+).*")
154 if not status then error("could not get remaining capacity") end
155 remaining = tonumber(remaining)
156 end) then
157 local percent = math.floor(remaining / lastfull * 100 + 5/10)
158 local timeleft
159 local hours, secs, mins
160 if get_ac() == 1 then
161 timeleft = " AC"
162 elseif rate <= 0 then
163 timeleft = "n/a"
164 else
165 secs = 3600 * (remaining / rate)
166 mins = secs / 60
167 hours = math.floor(mins / 60)
168 mins = math.floor(mins - (hours * 60))
169 timeleft = string.format("%02d:%02d", hours, mins)
172 if secs ~= nil and secs <= statusd_laptopstatus.batterytimeleft_important then timelefthint = "important" end
173 if secs ~= nil and secs <= statusd_laptopstatus.batterytimeleft_critical then timelefthint = "critical" end
174 if percent <= statusd_laptopstatus.batterypercent_important then percenthint = "important" end
175 if percent <= statusd_laptopstatus.batterypercent_critical then percenthint = "critical" end
177 return { percent=string.format("%02d%%", percent), timeleft=timeleft, drain=tostring(rate)..rateunit, percenthint=percenthint, timelefthint=timelefthint}
178 else return { percent="n/a", timeleft="n/a", drain="n/a", percenthint=percenthint, timelefthint=timelefthint} end
181 local last_timeleft = nil
183 local function update_laptopstatus ()
184 cpu = get_cpu()
185 thermal = get_thermal()
186 battery = get_battery()
188 -- Informing statusd OR printing to stdout if statusd not present
189 if statusd ~= nil then
190 statusd.inform("laptopstatus_cpuspeed", cpu.speed)
191 statusd.inform("laptopstatus_cpuspeed_template", "xxxxMHz")
192 statusd.inform("laptopstatus_cpuspeed_hint", cpu.hint)
193 statusd.inform("laptopstatus_temperature", thermal.temperature)
194 statusd.inform("laptopstatus_temperature_template", "xxxC")
195 statusd.inform("laptopstatus_temperature_hint", thermal.hint)
196 statusd.inform("laptopstatus_batterypercent", battery.percent)
197 statusd.inform("laptopstatus_batterypercent_template", "xxx%")
198 statusd.inform("laptopstatus_batterypercent_hint", battery.percenthint)
199 if battery.timeleft ~= "n/a" or last_timeleft == " AC" then
200 statusd.inform("laptopstatus_batterytimeleft", battery.timeleft)
201 last_timeleft = battery.timeleft
203 statusd.inform("laptopstatus_batterytimeleft_template", "hh:mm")
204 statusd.inform("laptopstatus_batterytimeleft_hint", battery.timelefthint)
205 statusd.inform("laptopstatus_batterydrain", battery.drain)
206 laptopstatus_timer:set(statusd_laptopstatus.interval*1000, update_laptopstatus)
207 else
208 io.stdout:write("CPU: "..cpu.speed.." "..thermal.temperature.." || BATT: "..battery.percent.." "..battery.timeleft.."\n")
209 laptopstatus_timer:set(statusd_laptopstatus.interval*2*1000, update_laptopstatus)
214 if statusd ~= nil then
215 laptopstatus_timer = statusd.create_timer()
217 update_laptopstatus()