Add sysfs method to get battery charge for linux
This commit is contained in:
@@ -2,7 +2,12 @@ package lib
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/distatus/battery"
|
||||
@@ -11,9 +16,6 @@ import (
|
||||
// UpdateBatteryInfo updates info about battery charge.
|
||||
func (c *MyConfig) UpdateBatteryInfo() {
|
||||
var (
|
||||
ch int
|
||||
status string
|
||||
Batts string
|
||||
InitialDelay = 100 * time.Millisecond
|
||||
LoopIterationDelay = 5 * time.Second
|
||||
Delay = InitialDelay
|
||||
@@ -26,9 +28,82 @@ func (c *MyConfig) UpdateBatteryInfo() {
|
||||
ticker.Reset(Delay)
|
||||
}
|
||||
|
||||
batteries, _ := battery.GetAll()
|
||||
// In theory, this module should give for each entry its separate err, but in practice it gives
|
||||
// one single err for all entries, so we cannot detemine whist exatly entry errored.
|
||||
var (
|
||||
batteries []*battery.Battery = []*battery.Battery{}
|
||||
Batts string
|
||||
ch int
|
||||
status string
|
||||
)
|
||||
|
||||
if c.Battery.UseSysfs {
|
||||
for _, file := range c.Battery.SysfsFiles {
|
||||
var batt battery.Battery
|
||||
|
||||
_, err := os.Stat(file)
|
||||
|
||||
// If file exists.
|
||||
if !os.IsNotExist(err) {
|
||||
var (
|
||||
myCharge string
|
||||
myStatus string
|
||||
)
|
||||
|
||||
b, err := os.ReadFile(file)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Unable to read file %s: %s", file, err)
|
||||
continue
|
||||
}
|
||||
|
||||
myCharge = strings.Trim(string(b), "\n")
|
||||
|
||||
statusFile := filepath.Dir(file) + "/status"
|
||||
|
||||
// If file exists.
|
||||
if !os.IsNotExist(err) {
|
||||
b, err := os.ReadFile(statusFile)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Unable to read file %s: %s", statusFile, err)
|
||||
continue
|
||||
}
|
||||
|
||||
myStatus = strings.Trim(string(b), "\n")
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
|
||||
// Make stub battery class :) .
|
||||
switch myStatus {
|
||||
case "Charging":
|
||||
batt.State.Raw = battery.Charging
|
||||
case "Discharging":
|
||||
batt.State.Raw = battery.Discharging
|
||||
case "Empty":
|
||||
batt.State.Raw = battery.Empty
|
||||
case "Full":
|
||||
batt.State.Raw = battery.Full
|
||||
default:
|
||||
batt.State.Raw = battery.Unknown
|
||||
}
|
||||
|
||||
ch, err := strconv.Atoi(myCharge)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Unable to convert string from file %s to integer", file)
|
||||
continue
|
||||
}
|
||||
|
||||
batt.Current = float64(ch)
|
||||
|
||||
batteries = append(batteries, &batt)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
batteries, _ = battery.GetAll()
|
||||
// In theory, this module should give for each entry its separate err, but in practice it gives
|
||||
// one single err for all entries, so we cannot detemine whist exatly entry errored.
|
||||
}
|
||||
|
||||
var (
|
||||
battsInfo string
|
||||
@@ -49,7 +124,11 @@ func (c *MyConfig) UpdateBatteryInfo() {
|
||||
|
||||
// N.B. there can be case when battery is overcharged and shows >100%. It also can indicate that
|
||||
// calibration data is out of date and battery should be re-calibrated.
|
||||
ch = int(math.Round((b.Full - (b.Full - b.Current)) * (100 / b.Full)))
|
||||
if c.Battery.UseSysfs {
|
||||
ch = int(b.Current)
|
||||
} else {
|
||||
ch = int(math.Round((b.Full - (b.Full - b.Current)) * (100 / b.Full)))
|
||||
}
|
||||
|
||||
switch {
|
||||
case ch <= 500 && ch >= 84:
|
||||
|
||||
@@ -134,14 +134,16 @@ type MyConfig struct {
|
||||
} `json:"clock,omitempty"`
|
||||
|
||||
Battery struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Color string `json:"color,omitempty"`
|
||||
Background string `json:"background,omitempty"`
|
||||
Font string `json:"font,omitempty"`
|
||||
FontSize string `json:"font_size,omitempty"`
|
||||
Symbol string `json:"symbol,omitempty"`
|
||||
SymbolFont string `json:"symbol_font,omitempty"`
|
||||
SymbolFontSize string `json:"symbol_font_size,omitempty"`
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
UseSysfs bool `json:"use_sysfs,omitempty"`
|
||||
SysfsFiles []string `json:"sysfs_files,omitempty"`
|
||||
Color string `json:"color,omitempty"`
|
||||
Background string `json:"background,omitempty"`
|
||||
Font string `json:"font,omitempty"`
|
||||
FontSize string `json:"font_size,omitempty"`
|
||||
Symbol string `json:"symbol,omitempty"`
|
||||
SymbolFont string `json:"symbol_font,omitempty"`
|
||||
SymbolFontSize string `json:"symbol_font_size,omitempty"`
|
||||
|
||||
ChargeColor struct {
|
||||
Full string `json:"full,omitempty"`
|
||||
@@ -778,6 +780,15 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
||||
}
|
||||
|
||||
// sampleConfig.Battery.Enabled will be false if not set in config
|
||||
// sampleConfig.Battery.UseSysfs will be false if not set in config
|
||||
|
||||
if len(sampleConfig.Battery.SysfsFiles) == 0 {
|
||||
sampleConfig.Battery.SysfsFiles = append(
|
||||
sampleConfig.Battery.SysfsFiles,
|
||||
"/sys/class/power_supply/BAT0/capacity",
|
||||
)
|
||||
}
|
||||
|
||||
if sampleConfig.Battery.Color == "" {
|
||||
sampleConfig.Battery.Color = sampleConfig.Color
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user