]> git.madduck.net Git - etc/awesome.git/blob - widget/contrib/tp_smapi.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge pull request #420 from sim590/unpack-lua51-compat
[etc/awesome.git] / widget / contrib / tp_smapi.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2018, Luca CPZ
5       * (c) 2013, Conor Heine
6
7 --]]
8
9 local helpers = require("lain.helpers")
10 local focused = require("awful.screen").focused
11 local gears   = require("gears")
12 local naughty = require("naughty")
13 local wibox   = require("wibox")
14 local string  = string
15
16 -- ThinkPad battery infos and widget creator
17 -- http://www.thinkwiki.org/wiki/Tp_smapi
18 -- lain.widget.contrib.tp_smapi
19
20 local function factory(apipath)
21     local tp_smapi = {
22         path = apipath or "/sys/devices/platform/smapi"
23     }
24
25     function tp_smapi.get(batid, feature)
26         return helpers.first_line(string.format("%s/%s/%s", tp_smapi.path, batid or "BAT0", feature or ""))
27     end
28
29     function tp_smapi.installed(batid)
30         return tp_smapi.get(batid, "installed") == "1"
31     end
32
33     function tp_smapi.status(batid)
34         return tp_smapi.get(batid, "state")
35     end
36
37     function tp_smapi.percentage(batid)
38         return tp_smapi.get(batid, "remaining_percent")
39     end
40
41     -- either running or charging time
42     function tp_smapi.time(batid)
43         local status = tp_smapi.status(batid)
44         local mins_left = tp_smapi.get(batid, string.match(string.lower(status), "discharging") and "remaining_running_time" or "remaining_charging_time")
45         if not string.find(mins_left, "^%d+") then return "N/A" end
46         return string.format("%02d:%02d", math.floor(mins_left / 60), mins_left % 60) -- HH:mm
47     end
48
49     function tp_smapi.hide()
50         if not tp_smapi.notification then return end
51         naughty.destroy(tp_smapi.notification)
52         tp_smapi.notification = nil
53     end
54
55     function tp_smapi.show(batid, seconds, scr)
56         if not tp_smapi.installed(batid) then return end
57
58         local mfgr   = tp_smapi.get(batid, "manufacturer") or "no_mfgr"
59         local model  = tp_smapi.get(batid, "model") or "no_model"
60         local chem   = tp_smapi.get(batid, "chemistry") or "no_chem"
61         local status = tp_smapi.get(batid, "state")
62         local time   = tp_smapi.time(batid)
63         local msg    = ""
64
65         if status and status ~= "idle" then
66             msg = string.format("[%s] %s %s", status, time ~= "N/A" and time or "unknown remaining time",
67                   string.lower(status):gsub(" ", ""):gsub("\n", "") == "charging" and " until charged" or " remaining")
68         else
69             msg = "On AC power"
70         end
71
72         tp_smapi.hide()
73         tp_smapi.notification = naughty.notify {
74             title   = string.format("%s: %s %s (%s)", batid, mfgr, model, chem),
75             text    = msg,
76             timeout = seconds or 0,
77             screen  = scr or focused()
78         }
79     end
80
81     function tp_smapi.create_widget(args)
82         local args      = args or {}
83         local pspath    = args.pspath or "/sys/class/power_supply/"
84         local batteries = args.batteries or (args.battery and {args.battery}) or {}
85         local timeout   = args.timeout or 30
86         local settings  = args.settings or function() end
87
88         if #batteries == 0 then
89             helpers.line_callback("ls -1 " .. pspath, function(line)
90                 local bstr = string.match(line, "BAT%w+")
91                 if bstr then batteries[#batteries + 1] = bstr end
92             end)
93         end
94
95         local all_batteries_installed = true
96
97         for i, battery in ipairs(batteries) do
98             if not tp_smapi.installed(battery) then
99                 naughty.notify {
100                     preset = naughty.config.critical,
101                     title  = "tp_smapi: error while creating widget",
102                     text   = string.format("battery %s is not installed", battery)
103                 }
104                 all_batteries_installed = false
105                 break
106             end
107         end
108
109         if not all_batteries_installed then return end
110
111         tpbat = {
112             batteries = batteries,
113             widget    = args.widget or wibox.widget.textbox()
114         }
115
116         function tpbat.update()
117             tpbat_now = {
118                 n_status = {},
119                 n_perc   = {},
120                 n_time   = {},
121                 status   = "N/A"
122             }
123
124             for i = 1, #batteries do
125                 tpbat_now.n_status[i] = tp_smapi.status(batteries[i]) or "N/A"
126                 tpbat_now.n_perc[i] = tp_smapi.percentage(batteries[i])
127                 tpbat_now.n_time[i] = tp_smapi.time(batteries[i]) or "N/A"
128
129                 if not tpbat_now.n_status[i]:lower():match("full") then
130                     tpbat_now.status = tpbat_now.n_status[i]
131                 end
132             end
133
134             widget = tpbat.widget -- backwards compatibility
135             settings()
136         end
137
138         helpers.newtimer("thinkpad-batteries", timeout, tpbat.update)
139
140         return tpbat
141     end
142
143     return tp_smapi
144 end
145
146 return factory