160 lines
3.4 KiB
Go
160 lines
3.4 KiB
Go
package providers
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/codemicro/bar/internal/i3bar"
|
|
)
|
|
|
|
const (
|
|
batteryStateFull = "FULL"
|
|
batteryStateDischarging = "BAT"
|
|
batteryStateCharging = "CHR"
|
|
batteryStateUnknown = "UNK"
|
|
)
|
|
|
|
type Battery struct {
|
|
FullThreshold float32
|
|
OkThreshold float32
|
|
WarningThreshold float32
|
|
|
|
DeviceName string
|
|
UseDesignMaxEnergy bool
|
|
|
|
name string
|
|
previousWasBackgroundWarning bool
|
|
}
|
|
|
|
func NewBattery(deviceName string, fullThreshold, okThreshold, warningThreshold float32) i3bar.BlockGenerator {
|
|
return &Battery{
|
|
DeviceName: deviceName,
|
|
FullThreshold: fullThreshold,
|
|
OkThreshold: okThreshold,
|
|
WarningThreshold: warningThreshold,
|
|
name: "battery",
|
|
}
|
|
}
|
|
|
|
func (g *Battery) infoPath() string {
|
|
return path.Join("/sys/class/power_supply", g.DeviceName)
|
|
}
|
|
|
|
func (g *Battery) getPercentage() (float32, error) {
|
|
// TODO: Cache the read of energy_full
|
|
var maxEnergy, energyNow int32
|
|
{
|
|
maxFile := "energy_full"
|
|
if g.UseDesignMaxEnergy {
|
|
maxFile = "energy_full_design"
|
|
}
|
|
|
|
me, err := ioutil.ReadFile(path.Join(g.infoPath(), maxFile))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
en, err := ioutil.ReadFile(path.Join(g.infoPath(), "energy_now"))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
mei, err := strconv.ParseInt(strings.TrimSpace(string(me)), 10, 32)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
eni, err := strconv.ParseInt(strings.TrimSpace(string(en)), 10, 32)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
maxEnergy = int32(mei)
|
|
energyNow = int32(eni)
|
|
}
|
|
|
|
return (float32(energyNow) / float32(maxEnergy)) * 100, nil
|
|
}
|
|
|
|
func (g *Battery) getState() (string, error) {
|
|
|
|
sa, err := ioutil.ReadFile(path.Join(g.infoPath(), "status"))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
var x string
|
|
|
|
switch strings.TrimSpace(string(sa)) {
|
|
case "Full":
|
|
x = batteryStateFull
|
|
case "Discharging":
|
|
x = batteryStateDischarging
|
|
case "Charging":
|
|
x = batteryStateCharging
|
|
case "Unknown":
|
|
fallthrough
|
|
default:
|
|
x = batteryStateUnknown
|
|
}
|
|
|
|
return x, nil
|
|
}
|
|
|
|
func (g *Battery) Block(colors *i3bar.ColorSet) (*i3bar.Block, error) {
|
|
percentage, err := g.getPercentage()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
state, err := g.getState()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
block := &i3bar.Block{
|
|
Name: g.name,
|
|
Instance: g.DeviceName,
|
|
FullText: fmt.Sprintf("%s %.1f%%", state, percentage),
|
|
ShortText: fmt.Sprintf("%.1f%%", percentage),
|
|
}
|
|
|
|
if percentage < g.WarningThreshold && g.WarningThreshold != 0 {
|
|
|
|
if g.previousWasBackgroundWarning || state == batteryStateCharging { // disable flashing when on charge
|
|
block.TextColor = colors.Bad
|
|
} else {
|
|
block.BackgroundColor = colors.Bad
|
|
}
|
|
|
|
g.previousWasBackgroundWarning = !g.previousWasBackgroundWarning
|
|
|
|
} else if percentage < g.OkThreshold && g.OkThreshold != 0 {
|
|
block.TextColor = colors.Warning
|
|
}
|
|
|
|
switch state {
|
|
case batteryStateCharging:
|
|
if percentage > g.FullThreshold && g.FullThreshold != 0 {
|
|
block.TextColor = colors.Good
|
|
} else {
|
|
// Set text/background color to white
|
|
block.BackgroundColor = nil
|
|
block.TextColor = nil
|
|
}
|
|
case batteryStateFull:
|
|
block.BackgroundColor = colors.Warning
|
|
block.TextColor = colors.Background
|
|
case batteryStateUnknown:
|
|
block.TextColor = colors.Warning
|
|
}
|
|
|
|
return block, nil
|
|
}
|
|
|
|
func (g *Battery) GetNameAndInstance() (string, string) {
|
|
return g.name, g.DeviceName
|
|
}
|