]> 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:

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