Add sysfs method to get battery charge for linux

This commit is contained in:
eleksir
2025-04-24 19:49:50 +03:00
parent 6b81991ebb
commit 757fb5e57e
3 changed files with 114 additions and 15 deletions

View File

@@ -518,6 +518,15 @@
"battery": { "battery": {
"enabled": false, "enabled": false,
// Valid only on linux, where we have mounted sysfs and /sys/class/power_supply/BAT0/capacity available
"use_sysfs": false,
// it is possible to set files here, if none set, /sys/class/power_supply/BAT0/capacity will be taken.
"sysfs_files": [
"/sys/class/power_supply/BAT0/capacity",
"/sys/class/power_supply/HIDP0/capacity"
],
// If omitted set to default color defined up here. // If omitted set to default color defined up here.
"color": "#3e78fd", "color": "#3e78fd",

View File

@@ -2,7 +2,12 @@ package lib
import ( import (
"fmt" "fmt"
"log"
"math" "math"
"os"
"path/filepath"
"strconv"
"strings"
"time" "time"
"github.com/distatus/battery" "github.com/distatus/battery"
@@ -11,9 +16,6 @@ import (
// UpdateBatteryInfo updates info about battery charge. // UpdateBatteryInfo updates info about battery charge.
func (c *MyConfig) UpdateBatteryInfo() { func (c *MyConfig) UpdateBatteryInfo() {
var ( var (
ch int
status string
Batts string
InitialDelay = 100 * time.Millisecond InitialDelay = 100 * time.Millisecond
LoopIterationDelay = 5 * time.Second LoopIterationDelay = 5 * time.Second
Delay = InitialDelay Delay = InitialDelay
@@ -26,9 +28,82 @@ func (c *MyConfig) UpdateBatteryInfo() {
ticker.Reset(Delay) ticker.Reset(Delay)
} }
batteries, _ := battery.GetAll() 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 // 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. // one single err for all entries, so we cannot detemine whist exatly entry errored.
}
var ( var (
battsInfo string 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 // 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. // calibration data is out of date and battery should be re-calibrated.
if c.Battery.UseSysfs {
ch = int(b.Current)
} else {
ch = int(math.Round((b.Full - (b.Full - b.Current)) * (100 / b.Full))) ch = int(math.Round((b.Full - (b.Full - b.Current)) * (100 / b.Full)))
}
switch { switch {
case ch <= 500 && ch >= 84: case ch <= 500 && ch >= 84:

View File

@@ -135,6 +135,8 @@ type MyConfig struct {
Battery struct { Battery struct {
Enabled bool `json:"enabled,omitempty"` Enabled bool `json:"enabled,omitempty"`
UseSysfs bool `json:"use_sysfs,omitempty"`
SysfsFiles []string `json:"sysfs_files,omitempty"`
Color string `json:"color,omitempty"` Color string `json:"color,omitempty"`
Background string `json:"background,omitempty"` Background string `json:"background,omitempty"`
Font string `json:"font,omitempty"` Font string `json:"font,omitempty"`
@@ -778,6 +780,15 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
} }
// sampleConfig.Battery.Enabled will be false if not set in config // 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 == "" { if sampleConfig.Battery.Color == "" {
sampleConfig.Battery.Color = sampleConfig.Color sampleConfig.Battery.Color = sampleConfig.Color
} }