rewrite of the battery plugin which gathers data from /sys
[wmiirc-lua.git] / src / plugins / battery.lua
blob21540228056e7b12d30fdd270375d4cf45a978c2
1 --[[
2 =pod
4 =head1 NAME
6 battery.lua - wmiirc-lua plugin for battery percentage
8 =head1 SYNOPSIS
10 -- in your wmiirc
11 wmii.load_plugin("battery")
13 -- To configure (after loading plugin)
15 -- Multiple batteries
16 wmii.set_conf("battery.names", "BAT0,BAT1");
18 -- Polling rate (in seconds)
19 wmii.set_conf("battery.poll_rate", 30)
21 =head1 DESCRIPTION
23 This plugin module provides a battery usage display.
25 =head1 CONFIGURATION AND ENVIRONMENT
27 There are several configurable options at the moment, most of which will not
28 need to be modified from the defaults for most users.
30 =over 4
32 =item battery.names
34 A comma-separated list of battery names to poll for status. This allows the
35 widget to display multiple battery names.
37 Defaults to "BAT0"
39 =item battery.poll_rate
41 Time in seconds to wait between checks for battery status.
43 Defaults to 30
45 =item battery.low
47 Provide a "low battery" warning at this percentage of remaining capacity.
48 Colour of widget will change to the defined value, and the low_action, if any,
49 will be invoked.
51 Defaults to 15
53 =item battery.low_fgcolor
55 Foreground colour of widget when in low battery state.
57 Defaults to #000000
59 =item battery.low_bgcolor
61 Background colour of widget when in low battery state.
63 Defaults to #FFFF66
65 =item battery.low_action
67 Shell command to invoke on entering low battery state.
69 Defaults to
71 echo "Low battery" | xmessage -center -buttons quit:0 -default quit -file -
73 =item battery.critical
75 Provide a "critical battery" warning at this percentage of remaining capacity.
76 Colour of widget will change to the defined value, and the critical_action, if any,
77 will be invoked.
79 Defaults to 5
81 =item battery.critical_fgcolor
83 Foreground colour of widget when in critical battery state.
85 Defaults to #000000
87 =item battery.critical_bgcolor
89 Background colour of widget when in critical battery state.
91 Defaults to #FF0000
93 =item battery.critical_action
95 Shell command to invoke on entering critical battery state.
97 Defaults to
99 echo "Critical battery" | xmessage -center -buttons quit:0 -default quit -file -
101 =back
103 =head1 BUGS AND LIMITATIONS
105 Please report problems to the author.
106 Patches are welcome.
108 =over 4
110 =item *
112 You can't have different low/critical warning thresholds or colours per
113 battery. If you actually want this, please send a patch.
115 =back
117 =head1 SEE ALSO
119 L<wmii(1)>, L<lua(1)>
121 =head1 AUTHOR
123 Dave O'Neill <dmo@dmo.ca>
124 Bart Trojanowski <bart@jukie.net>
126 Based on a port by Stefan Riegler <sr@bigfatflat.net> of the ruby-wmiirc
127 standard-plugin.rb battery handling originally written Mauricio Fernandez.
129 =head1 LICENCE AND COPYRIGHT
131 Copyright (c) 2007, Stefan Riegler <sr@bigfatflat.net>
132 Copyright (c) 2008, Dave O'Neill <dmo@dmo.ca>
133 Copyright (c) 2010, Bart Trojanowski <bart@jukie.net>
135 This is free software. You may redistribute copies of it under the terms of
136 the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>. There
137 is NO WARRANTY, to the extent permitted by law.
139 =cut
141 --]]
143 local wmii = require("wmii")
144 local io = require("io")
145 local os = require("os")
146 local string = require("string")
147 local type = type
149 module("battery")
150 api_version=0.1
153 -- Configuration Settings
155 wmii.set_conf ("battery.poll_rate", 30)
157 wmii.set_conf ("battery.names", "BAT0")
159 wmii.set_conf ("battery.low", 15)
160 wmii.set_conf ("battery.low_fgcolor", "#000000")
161 wmii.set_conf ("battery.low_bgcolor", "#FFFF66")
162 wmii.set_conf ("battery.low_action", 'echo "Low battery" | xmessage -center -buttons quit:0 -default quit -file -')
164 wmii.set_conf ("battery.critical", 5)
165 wmii.set_conf ("battery.critical_fgcolor", "#000000")
166 wmii.set_conf ("battery.critical_bgcolor", "#FF0000")
167 wmii.set_conf ("battery.critical_action", 'echo "Critical battery" | xmessage -center -buttons quit:0 -default quit -file -')
169 -- Should not need to be modified on Linux
170 wmii.set_conf ("battery.sysdir", "/sys/class/power_supply/%s")
171 -- ... see http://wiki.openmoko.org/wiki/GTA02_sysfs#power_supply_battery_information for more info
173 wmii.set_conf ("battery.showtime", true)
174 wmii.set_conf ("battery.showrate", true)
177 -- Local Variables
179 local batteries = { }
181 -- read a /sys file, return the first line
182 local function read_sys_line(file, fmt)
183 local ret = nil
184 local fd = io.open(file)
185 if fd then
186 ret = fd:read(fmt or "*l")
188 return ret
190 local function read_sys_number(file)
191 local ret = read_sys_line(file, "*n")
192 if type(ret) ~= type(1) then
193 ret = 0
195 return ret
198 -- The actual work performed here.
199 -- parses info, state file and preps for display
200 local function update_single_battery ( battery )
202 local printout = "N/A"
203 local colors = wmii.get_ctl("normcolors")
205 local sysdir = string.format(wmii.get_conf("battery.sysdir"), battery["name"])
207 local batt_present = read_sys_number(sysdir .. '/present') -- 0 or 1
208 local batt_energy_now = read_sys_number(sysdir .. '/energy_now') -- µWh
209 local batt_energy_full = read_sys_number(sysdir .. '/energy_full') -- µWh
210 local batt_current_now = read_sys_number(sysdir .. '/current_now') -- µAh
211 local batt_power_now = read_sys_number(sysdir .. '/power_now') -- µW
212 local batt_status = read_sys_line(sysdir .. '/status') -- Full, Charging, Discharging, Unknown
214 -- the /sys reporting interface is not present
215 if not batt_present or not batt_energy_now or not batt_energy_full or not batt_status then
216 return battery["widget"]:show(printout, colors)
219 -- Special case when a second battery is drained and not charging
220 if batt_status == 'Unknown' and batt_current_now == 0 then
221 return battery["widget"]:show(printout, colors)
224 local batt_percent = batt_energy_now / batt_energy_full * 100
226 local low = wmii.get_conf ("battery.low")
227 local critical = wmii.get_conf ("battery.critical")
229 -- Take action in case battery is low/critical
230 if batt_percent <= critical then
231 if batt_status == "Discharging" and not battery["warned_crit"] then
232 wmii.log("Warning about critical battery.")
233 os.execute(wmii.get_conf("battmon.critical_action"), "&")
234 battery["warned_crit"] = true
236 colors = string.gsub(colors, "^%S+ %S+",
237 wmii.get_conf ("battery.critical_fgcolor")
238 .. " "
239 .. wmii.get_conf ("battery.critical_bgcolor"),
241 elseif batt_percent <= low then
242 if batt_status == "Discharging" and not battery["warned_low"] then
243 wmii.log("Warning about low battery.")
244 os.execute(wmii.get_conf("battmon.low_action"), "&")
245 battery["warned_low"] = true
247 colors = string.gsub(colors, "^%S+ %S+",
248 wmii.get_conf ("battery.low_fgcolor")
249 .. " "
250 .. wmii.get_conf ("battery.low_bgcolor"),
252 else
253 battery["warned_low"] = true
254 battery["warned_crit"] = true
258 -- If percent is 100 and state is discharging then
259 -- the battery is full and not discharging.
260 batt_state = "?"
261 if (batt_status == "Full") or (batt_status == "Discharging" and batt_percent >= 97) then
262 batt_state = "="
263 elseif batt_status == "Charging" then
264 batt_state = "^"
265 elseif batt_status == "Discharging" then
266 batt_state = "v"
269 -- done calculating, compose the output
270 printout = ""
272 if wmii.get_conf(battery.showrate) and batt_power_now then
273 printout = printout .. string.format("%.2fW ", batt_power_now / 1000000)
276 if wmii.get_conf(battery.showtime) and batt_current_now and batt_energy_now ~= 0 then
277 if batt_state == "^" then
278 hours = (batt_energy_full - batt_energy_now) / batt_current_now
279 else
280 hours = batt_energy_now / batt_current_now
282 printout = printout .. string.format("%d:%0.2d ", hours, (hours*60) % 60)
285 printout = printout .. '(' .. batt_state .. string.format("%.0f",batt_percent) .. batt_state .. ')'
287 battery["widget"]:show(printout, colors)
290 -- ------------------------------------------------------------
291 -- The battery status update function (wmii.timer function)
292 local function update_batt_data (time_since_update)
294 local batt_names = wmii.get_conf("battery.names");
296 for battery in batt_names:gmatch("%w+") do
297 if( not batteries[battery] ) then
298 batteries[battery] = {
299 name = battery,
300 widget = wmii.widget:new ("901_battery_" .. battery),
301 warned_low = false,
302 warned_crit = false,
305 update_single_battery( batteries[battery] )
308 return wmii.get_conf("battery.poll_rate")
312 local timer = wmii.timer:new (update_batt_data, 1)