aboutsummaryrefslogtreecommitdiff
path: root/pkg/i3status/battery.go
blob: ec2aa887bb79ec53d3eb4c44a0fa53904b363b6a (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
/*******************************************************************************
*
* Copyright 2017 Stefan Majewsky <majewsky@gmx.net>
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
*******************************************************************************/

package i3status

import (
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"
)

const (
	batteryFullPath = "/sys/class/power_supply/BAT0/energy_full"
	batteryNowPath  = "/sys/class/power_supply/BAT0/energy_now"
	powerNowPath    = "/sys/class/power_supply/BAT0/power_now"
)

func getBatteryStatus() []Block {
	//TODO: What's with /sys/class/power_supply/BAT0/uevent? Can this be used to
	//remove all the polling overhead here?

	energyFull, err := readNumberFromFile(batteryFullPath)
	if err != nil {
		return nil
	}
	energyNow, err := readNumberFromFile(batteryNowPath)
	if err != nil {
		return nil
	}
	powerNow, err := readNumberFromFile(powerNowPath)
	if err != nil {
		return nil
	}

	energyPerc := energyNow * 100 / energyFull
	charging := powerNow == 0 //i.e. when we're not drawing power from the battery
	color := "#AAAA00"
	if charging {
		color = "#00AA00"
	} else if energyPerc < 10 {
		color = "#AA0000"
	}

	return section("bat", Block{
		Name:     "battery",
		Position: PositionBattery,
		FullText: fmt.Sprintf("%d%%", energyPerc),
		Urgent:   energyPerc < 10 && !charging,
		Color:    color,
	})
}

func readNumberFromFile(path string) (int64, error) {
	buf, err := ioutil.ReadFile(path)
	if err != nil {
		return 0, err
	}
	return strconv.ParseInt(strings.TrimSpace(string(buf)), 0, 64)
}