Add sysfs method to get battery charge for linux
This commit is contained in:
@@ -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",
|
||||||
|
|
||||||
|
|||||||
@@ -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 (
|
||||||
// In theory, this module should give for each entry its separate err, but in practice it gives
|
batteries []*battery.Battery = []*battery.Battery{}
|
||||||
// one single err for all entries, so we cannot detemine whist exatly entry errored.
|
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 (
|
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.
|
||||||
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 {
|
switch {
|
||||||
case ch <= 500 && ch >= 84:
|
case ch <= 500 && ch >= 84:
|
||||||
|
|||||||
@@ -134,14 +134,16 @@ type MyConfig struct {
|
|||||||
} `json:"clock,omitempty"`
|
} `json:"clock,omitempty"`
|
||||||
|
|
||||||
Battery struct {
|
Battery struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
Color string `json:"color,omitempty"`
|
UseSysfs bool `json:"use_sysfs,omitempty"`
|
||||||
Background string `json:"background,omitempty"`
|
SysfsFiles []string `json:"sysfs_files,omitempty"`
|
||||||
Font string `json:"font,omitempty"`
|
Color string `json:"color,omitempty"`
|
||||||
FontSize string `json:"font_size,omitempty"`
|
Background string `json:"background,omitempty"`
|
||||||
Symbol string `json:"symbol,omitempty"`
|
Font string `json:"font,omitempty"`
|
||||||
SymbolFont string `json:"symbol_font,omitempty"`
|
FontSize string `json:"font_size,omitempty"`
|
||||||
SymbolFontSize string `json:"symbol_font_size,omitempty"`
|
Symbol string `json:"symbol,omitempty"`
|
||||||
|
SymbolFont string `json:"symbol_font,omitempty"`
|
||||||
|
SymbolFontSize string `json:"symbol_font_size,omitempty"`
|
||||||
|
|
||||||
ChargeColor struct {
|
ChargeColor struct {
|
||||||
Full string `json:"full,omitempty"`
|
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.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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user