diff --git a/internal/providers/battery.go b/internal/providers/battery.go index e754034..58d4302 100644 --- a/internal/providers/battery.go +++ b/internal/providers/battery.go @@ -3,9 +3,12 @@ package providers import ( "fmt" "io/ioutil" + "os" "path" "strconv" "strings" + "os/exec" + "path/filepath" "github.com/codemicro/bar/internal/i3bar" ) @@ -29,6 +32,7 @@ type Battery struct { name string previousWasBackgroundWarning bool isAlert bool + previousValue string } func NewBattery(deviceName string, fullThreshold, okThreshold, warningThreshold float32) i3bar.BlockGenerator { @@ -120,17 +124,31 @@ func (g *Battery) Block(colors *i3bar.ColorSet) (*i3bar.Block, error) { if err != nil { return nil, err } - + state, err := g.getState() if err != nil { return nil, err } + percentageString := fmt.Sprintf("%.1f", percentage) + shortPercentageString := strings.Split(percentageString, ".")[0] + if g.previousValue != shortPercentageString && state == batteryStateDischarging { + switch shortPercentageString { + case "20": + _ = g.SendNotification("Battery is getting low", "At 20% and discharging. Consider plugging in.", "low") + case "12": + _ = g.SendNotification("Battery is getting lower", "At 12% and discharging. Plug in now.", "normal") + case "5": + _ = g.SendNotification("Battery is really low", "At 5% and discharging. PLUG IN NOW.", "critical") + } + } + g.previousValue = shortPercentageString + block := &i3bar.Block{ Name: g.name, Instance: g.DeviceName, - FullText: fmt.Sprintf("%s %.1f%%", state, percentage), - ShortText: fmt.Sprintf("%.1f%%", percentage), + FullText: fmt.Sprintf("%s %s%%", state, percentageString), + ShortText: percentageString, } if percentage < g.WarningThreshold && g.WarningThreshold != 0 { @@ -173,3 +191,19 @@ func (g *Battery) Block(colors *i3bar.ColorSet) (*i3bar.Block, error) { func (g *Battery) GetNameAndInstance() (string, string) { return g.name, g.DeviceName } + +func (g *Battery) SendNotification(summary, message, priority string) error { + fname, err := exec.LookPath("notify-send") + if err == nil { + fname, err = filepath.Abs(fname) + } + if err != nil { + return err + } + process, err := os.StartProcess(fname, []string{fname, "--urgency", priority, summary, message}, &os.ProcAttr{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}}) + if err != nil { + return err + } + _ = process.Release() + return nil +} \ No newline at end of file