summaryrefslogtreecommitdiff
path: root/battery.lua
blob: 85dca93dcf02397f90da94d058ccac17c11da6a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
local gio       = require("lgi").Gio

local object    = require("gears.object")

local utils     = require("utils")

local Battery = {}
Battery.__index = Battery

setmetatable(Battery, {
    __call = function (cls, ...) return cls.new(...) end,
})

Battery.STATUS = {
    UNKNOWN             = 'Unknown',
    DISCHARGING         = 'Discharging',
    CHARGING            = 'Charging',
    ['NOT CHARGING']    = 'Not charging',
    FULL                = 'Full',
}

function Battery:_readfile(name)
    local file = gio.File.new_for_path(self._path  .. name)
    local contents = file:load_contents(nil)

    -- remove trailing newline
    if contents then
        contents = string.gsub(contents, "%s$", "")
        return string.len(contents) > 0 and contents or nil
    end

    return nil
end

function Battery:_readnum(name)
    local val = self:_readfile(name)
    return tonumber(val)
end

function Battery:update()
    local status = string.upper(self:_readfile('status') or '')
    self.status = self.STATUS[status]
    if self.status == nil then
        utils.log('Battery/' .. self.name, 'Error updating status: %s', tostring(status))
        return false
    end

    self.capacity       = self:_readnum('capacity')
    self.capacity_level = self:_readfile('capacity_level')

    local energy        = self:_readnum('energy_now')
    local energy_full   = self:_readnum('energy_full')
    local power         = self:_readnum('power_now')

    -- try to compute remaining seconds to charge/discharge,
    -- if we have the information
    self.remaining_seconds = nil

    if self.status == self.STATUS.DISCHARGING then
        if energy and power and power > 0 then
            self.remaining_seconds = 3600 * energy / power
        end
    elseif self.status == self.STATUS.CHARGING then
        if energy and energy_full and power and power > 0 then
            self.remaining_seconds = 3600 * (energy_full - energy) / power
        end
    end

    if power ~= nil then
        self.power = power / 1e6
    end

    self:emit_signal('updated')

    return true
end

function Battery.new(name)
    local self = object({class = Battery})

    self.name  = name
    self._path = '/sys/class/power_supply/' .. name .. '/'

    -- skip non-battery power supplies, we don't handle them
    local type = self:_readfile('type')
    if type ~= 'Battery' then
        return nil
    end

    -- build description string
    local desc = nil

    -- first try manufacturer+model
    local manufacturer = self:_readfile('manufacturer')
    local model        = self:_readfile('model_name')
    if manufacturer or model then
        desc = (manufacturer or '') .. (manufacturer and ' ' or '') .. (model or '')
    end

    if not desc then
        local technology = self:_readfile('technology')
        desc = (technology or '') .. (technology and ' ' or '') .. type
    end

    self.desc = desc

    if not self:update() then
        return nil
    end

    return self
end

return Battery