mirror of
https://github.com/henrygd/beszel.git
synced 2025-10-30 10:07:02 +00:00
fix: send battery stats even if some batteries are missing stats (#1287)
Implement battery error reporting mechanism Added error reporting for battery information retrieval. Handles cases like bluetooth devices where `battery` finds it but it has incomplete information about that battery, which would have otherwise caused a null pointer error. Related: #1254
This commit is contained in:
@@ -5,6 +5,8 @@ package battery
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/distatus/battery"
|
"github.com/distatus/battery"
|
||||||
@@ -19,33 +21,60 @@ func HasReadableBattery() bool {
|
|||||||
return systemHasBattery
|
return systemHasBattery
|
||||||
}
|
}
|
||||||
haveCheckedBattery = true
|
haveCheckedBattery = true
|
||||||
bat, err := battery.Get(0)
|
batteries,err := battery.GetAll()
|
||||||
systemHasBattery = err == nil && bat != nil && bat.Design != 0 && bat.Full != 0
|
if err != nil {
|
||||||
|
// even if there's errors getting some batteries, the system
|
||||||
|
// definitely has a battery if the list is not empty.
|
||||||
|
// This list will include everything `battery` can find,
|
||||||
|
// including things like bluetooth devices.
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
}
|
||||||
|
systemHasBattery = len(batteries) > 0
|
||||||
if !systemHasBattery {
|
if !systemHasBattery {
|
||||||
slog.Debug("No battery found", "err", err)
|
slog.Debug("No battery found", "err", err)
|
||||||
}
|
}
|
||||||
return systemHasBattery
|
return systemHasBattery
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBatteryStats returns the current battery percent and charge state
|
// GetBatteryStats returns the current battery percent and charge state
|
||||||
|
// percent = (current charge of all batteries) / (sum of designed/full capacity of all batteries)
|
||||||
func GetBatteryStats() (batteryPercent uint8, batteryState uint8, err error) {
|
func GetBatteryStats() (batteryPercent uint8, batteryState uint8, err error) {
|
||||||
if !systemHasBattery {
|
if !HasReadableBattery() {
|
||||||
return batteryPercent, batteryState, errors.ErrUnsupported
|
return batteryPercent, batteryState, errors.ErrUnsupported
|
||||||
}
|
}
|
||||||
batteries, err := battery.GetAll()
|
batteries, err := battery.GetAll()
|
||||||
if err != nil || len(batteries) == 0 {
|
// we'll handle errors later by skipping batteries with errors, rather
|
||||||
return batteryPercent, batteryState, err
|
// than skipping everything because of the presence of some errors.
|
||||||
|
if len(batteries) == 0 {
|
||||||
|
return batteryPercent, batteryState, errors.New("no batteries")
|
||||||
}
|
}
|
||||||
|
|
||||||
totalCapacity := float64(0)
|
totalCapacity := float64(0)
|
||||||
totalCharge := float64(0)
|
totalCharge := float64(0)
|
||||||
for _, bat := range batteries {
|
errs, partialErrs := err.(battery.Errors)
|
||||||
if bat.Design != 0 {
|
|
||||||
totalCapacity += bat.Design
|
for i, bat := range batteries {
|
||||||
} else {
|
if partialErrs && errs[i] != nil {
|
||||||
totalCapacity += bat.Full
|
// if there were some errors, like missing data, skip it
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
if bat.Full == 0 {
|
||||||
|
// skip batteries with no capacity. Charge is unlikely to ever be zero, but
|
||||||
|
// we can't guarantee that, so don't skip based on charge.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
totalCapacity += bat.Full
|
||||||
totalCharge += bat.Current
|
totalCharge += bat.Current
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if totalCapacity == 0 {
|
||||||
|
// for macs there's sometimes a ghost battery with 0 capacity
|
||||||
|
// https://github.com/distatus/battery/issues/34
|
||||||
|
// Instead of skipping over those batteries, we'll check for total 0 capacity
|
||||||
|
// and return an error. This also prevents a divide by zero.
|
||||||
|
return batteryPercent, batteryState, errors.New("no battery capacity")
|
||||||
|
}
|
||||||
|
|
||||||
batteryPercent = uint8(totalCharge / totalCapacity * 100)
|
batteryPercent = uint8(totalCharge / totalCapacity * 100)
|
||||||
batteryState = uint8(batteries[0].State.Raw)
|
batteryState = uint8(batteries[0].State.Raw)
|
||||||
return batteryPercent, batteryState, nil
|
return batteryPercent, batteryState, nil
|
||||||
|
|||||||
@@ -78,8 +78,9 @@ func (a *Agent) getSystemStats(cacheTimeMs uint16) system.Stats {
|
|||||||
var systemStats system.Stats
|
var systemStats system.Stats
|
||||||
|
|
||||||
// battery
|
// battery
|
||||||
if battery.HasReadableBattery() {
|
if batteryPercent, batteryState, err := battery.GetBatteryStats(); err == nil {
|
||||||
systemStats.Battery[0], systemStats.Battery[1], _ = battery.GetBatteryStats()
|
systemStats.Battery[0] = batteryPercent
|
||||||
|
systemStats.Battery[1] = batteryState
|
||||||
}
|
}
|
||||||
|
|
||||||
// cpu percent
|
// cpu percent
|
||||||
|
|||||||
14
go.sum
14
go.sum
@@ -169,20 +169,18 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
|
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
|
||||||
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||||
modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4=
|
modernc.org/cc/v4 v4.26.2 h1:991HMkLjJzYBIfha6ECZdjrIYz2/1ayr+FL8GN+CNzM=
|
||||||
modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
modernc.org/cc/v4 v4.26.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||||
modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A=
|
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
|
||||||
modernc.org/ccgo/v4 v4.28.1/go.mod h1:uD+4RnfrVgE6ec9NGguUNdhqzNIeeomeXf6CL0GTE5Q=
|
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
|
||||||
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
|
modernc.org/fileutil v1.3.8 h1:qtzNm7ED75pd1C7WgAGcK4edm4fvhtBsEiI/0NQ54YM=
|
||||||
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
modernc.org/fileutil v1.3.8/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
||||||
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||||
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||||
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
||||||
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||||
modernc.org/libc v1.66.3 h1:cfCbjTUcdsKyyZZfEUKfoHcP3S0Wkvz3jgSzByEWVCQ=
|
modernc.org/libc v1.66.3 h1:cfCbjTUcdsKyyZZfEUKfoHcP3S0Wkvz3jgSzByEWVCQ=
|
||||||
modernc.org/libc v1.66.3/go.mod h1:XD9zO8kt59cANKvHPXpx7yS2ELPheAey0vjIuZOhOU8=
|
modernc.org/libc v1.66.3/go.mod h1:XD9zO8kt59cANKvHPXpx7yS2ELPheAey0vjIuZOhOU8=
|
||||||
modernc.org/libc v1.66.10 h1:yZkb3YeLx4oynyR+iUsXsybsX4Ubx7MQlSYEw4yj59A=
|
|
||||||
modernc.org/libc v1.66.10/go.mod h1:8vGSEwvoUoltr4dlywvHqjtAqHBaw0j1jI7iFBTAr2I=
|
|
||||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||||
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||||
|
|||||||
Reference in New Issue
Block a user