6 battery.lua - wmiirc-lua plugin for battery percentage
11 wmii.load_plugin("battery")
13 -- To configure (after loading plugin)
16 wmii.set_conf("battery.names", "BAT0,BAT1");
18 -- Polling rate (in seconds)
19 wmii.set_conf("battery.poll_rate", 30)
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.
34 A comma-separated list of battery names to poll for status. This allows the
35 widget to display multiple battery names. If left blank, will display all
40 =item battery.poll_rate
42 Time in seconds to wait between checks for battery status.
48 Provide a "low battery" warning at this percentage of remaining capacity.
49 Colour of widget will change to the defined value, and the low_action, if any,
54 =item battery.low_fgcolor
56 Foreground colour of widget when in low battery state.
60 =item battery.low_bgcolor
62 Background colour of widget when in low battery state.
66 =item battery.low_action
68 Shell command to invoke on entering low battery state.
72 echo "Low battery" | xmessage -center -buttons quit:0 -default quit -file -
74 =item battery.critical
76 Provide a "critical battery" warning at this percentage of remaining capacity.
77 Colour of widget will change to the defined value, and the critical_action, if any,
82 =item battery.critical_fgcolor
84 Foreground colour of widget when in critical battery state.
88 =item battery.critical_bgcolor
90 Background colour of widget when in critical battery state.
94 =item battery.critical_action
96 Shell command to invoke on entering critical battery state.
100 echo "Critical battery" | xmessage -center -buttons quit:0 -default quit -file -
102 =item battery.practically_full_percentage
104 This is a workaround for faulty batteries. Set this lower if you want your battery to report being
105 full at a lower percentage than 100.
111 =head1 BUGS AND LIMITATIONS
113 Please report problems to the author.
120 You can't have different low/critical warning thresholds or colours per
121 battery. If you actually want this, please send a patch.
127 L<wmii(1)>, L<lua(1)>
131 Dave O'Neill <dmo@dmo.ca>
132 Bart Trojanowski <bart@jukie.net>
134 Based on a port by Stefan Riegler <sr@bigfatflat.net> of the ruby-wmiirc
135 standard-plugin.rb battery handling originally written Mauricio Fernandez.
137 =head1 LICENCE AND COPYRIGHT
139 Copyright (c) 2007, Stefan Riegler <sr@bigfatflat.net>
140 Copyright (c) 2008, Dave O'Neill <dmo@dmo.ca>
141 Copyright (c) 2010, Bart Trojanowski <bart@jukie.net>
143 This is free software. You may redistribute copies of it under the terms of
144 the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>. There
145 is NO WARRANTY, to the extent permitted by law.
151 local wmii
= require("wmii")
152 local io
= require("io")
153 local os
= require("os")
154 local string = require("string")
155 local posix
= require("posix")
157 local tostring = tostring
163 -- Configuration Settings
165 wmii
.set_conf ("battery.poll_rate", 30)
167 wmii
.set_conf ("battery.names", "") -- leave empty to use all available batteries
169 wmii
.set_conf ("battery.low", 15)
170 wmii
.set_conf ("battery.low_fgcolor", "#000000")
171 wmii
.set_conf ("battery.low_bgcolor", "#FFFF66")
172 wmii
.set_conf ("battery.low_action", 'echo "Low battery" | xmessage -center -buttons quit:0 -default quit -file -')
174 wmii
.set_conf ("battery.critical", 5)
175 wmii
.set_conf ("battery.critical_fgcolor", "#000000")
176 wmii
.set_conf ("battery.critical_bgcolor", "#FF0000")
177 wmii
.set_conf ("battery.critical_action", 'echo "Critical battery" | xmessage -center -buttons quit:0 -default quit -file -')
179 wmii
.set_conf ("battery.practically_full_percentage", 99)
181 -- Should not need to be modified on Linux
182 wmii
.set_conf ("battery.sysdir", "/sys/class/power_supply")
183 -- ... see http://wiki.openmoko.org/wiki/GTA02_sysfs#power_supply_battery_information for more info
185 wmii
.set_conf ("battery.showtime", true)
186 wmii
.set_conf ("battery.showrate", true)
191 local batteries
= { }
193 -- read a /sys file, return the first line
194 local function read_sys_line(file
, fmt
)
196 local fd
= io
.open(file
)
198 ret
= fd
:read(fmt
or "*l")
202 local function read_sys_number(file
)
203 local ret
= read_sys_line(file
, "*n")
204 if type(ret
) ~= type(1) then
210 -- The actual work performed here.
211 -- parses info, state file and preps for display
212 local function update_single_battery ( name
)
214 local battery
= batteries
[name
]
218 widget
= wmii
.widget
:new ("901_battery_" .. name
),
222 battery
= batteries
[name
]
225 local printout
= "N/A"
226 local colors
= wmii
.get_ctl("normcolors")
228 local sysdir
= string.format("%s/%s", wmii
.get_conf("battery.sysdir"), name
)
230 local batt_present
= read_sys_number(sysdir
.. '/present') -- 0 or 1
231 local batt_energy_now
= read_sys_number(sysdir
.. '/energy_now') -- µWh
232 local batt_energy_full
= read_sys_number(sysdir
.. '/energy_full') -- µWh
233 local batt_current_now
= read_sys_number(sysdir
.. '/current_now') -- µAh
234 local batt_power_now
= read_sys_number(sysdir
.. '/power_now') -- µW
235 local batt_status
= read_sys_line(sysdir
.. '/status') -- Full, Charging, Discharging, Unknown
237 -- the /sys reporting interface is not present
238 if not batt_present
or not batt_energy_now
or not batt_energy_full
or not batt_status
then
239 return battery
["widget"]:show(printout
, colors
)
242 local batt_percent
= batt_energy_now
/ batt_energy_full
* 100
243 if batt_percent
> 100 then
247 local low
= wmii
.get_conf ("battery.low")
248 local critical
= wmii
.get_conf ("battery.critical")
249 local practically_full
= wmii
.get_conf ("battery.practically_full_percentage")
251 -- Take action in case battery is low/critical
252 if batt_percent
<= critical
then
253 if batt_status
== "Discharging" and not battery
["warned_crit"] then
254 wmii
.log("Warning about critical battery.")
255 os
.execute(wmii
.get_conf("battmon.critical_action"), "&")
256 battery
["warned_crit"] = true
258 colors
= string.gsub(colors
, "^%S+ %S+",
259 wmii
.get_conf ("battery.critical_fgcolor")
261 .. wmii
.get_conf ("battery.critical_bgcolor"),
263 elseif batt_percent
<= low
then
264 if batt_status
== "Discharging" and not battery
["warned_low"] then
265 wmii
.log("Warning about low battery.")
266 os
.execute(wmii
.get_conf("battmon.low_action"), "&")
267 battery
["warned_low"] = true
269 colors
= string.gsub(colors
, "^%S+ %S+",
270 wmii
.get_conf ("battery.low_fgcolor")
272 .. wmii
.get_conf ("battery.low_bgcolor"),
275 battery
["warned_low"] = true
276 battery
["warned_crit"] = true
280 -- If percent is 100 and state is discharging then
281 -- the battery is full and not discharging.
282 local batt_state
= "?"
283 if batt_status
== "Unknown" then
285 elseif (batt_status
== "Full") or (batt_percent
>= practically_full
) then
287 elseif batt_status
== "Charging" then
289 elseif batt_status
== "Discharging" then
293 -- done calculating, compose the output
296 if wmii
.get_conf(battery
.showrate
) and batt_power_now
then
297 printout
= printout
.. string.format("%.2fW ", batt_power_now
/ 1000000)
300 if wmii
.get_conf(battery
.showtime
) and batt_current_now
and batt_current_now
~= 0 then
302 if batt_state
== "^" then
303 hours
= (batt_energy_full
- batt_energy_now
) / batt_current_now
305 hours
= batt_energy_now
/ batt_current_now
307 printout
= printout
.. string.format("%d:%0.2d ", hours
, (hours
*60) % 60)
310 printout
= printout
.. '(' .. batt_state
.. string.format("%.0f", batt_percent
) .. batt_state
.. ')'
312 battery
["widget"]:show(printout
, colors
)
315 -- ------------------------------------------------------------
316 -- The battery status update function (wmii.timer function)
317 local function update_batt_data (time_since_update
)
319 local batt_names
= wmii
.get_conf("battery.names");
321 if type(batt_names
) == type("") and batt_names
~= "" then
322 for name
in batt_names
:gmatch("%w+") do
323 update_single_battery(name
)
326 local sysdir
= wmii
.get_conf("battery.sysdir")
327 for name
in posix
.files(sysdir
) do
328 local type_file
= string.format("%s/%s/type", sysdir
, name
)
329 local batt_type
= read_sys_line(type_file
)
330 if batt_type
== "Battery" then
331 update_single_battery(name
)
336 return wmii
.get_conf("battery.poll_rate")
340 local timer
= wmii
.timer
:new (update_batt_data
, 1)