Files
macos-battery-exporter/battery/battery.go

131 lines
3.5 KiB
Go

//go:build darwin
package battery
import (
"math"
"time"
)
type Battery struct {
// BatteryCellDisconnectCount is the number of times the battery cells have
// been disconnected.
BatteryCellDisconnectCount int
// BuiltIn indicates if the battery is built-in or not.
BuiltIn bool
// ChargeRateAmps is the current charge rate in mAh. Negative values indicate
// discharge, positive values indicate charging.
ChargeRateAmps int64
// ChargeRateWatts is the current charge rate in mWh. Negative values indicate
// discharge, positive values indicate charging.
ChargeRateWatts float64
// CurrentCapacityAmps is the current battery capacity in mAh.
CurrentCapacityAmps int
// CurrentCapacityWatts is the current battery capacity in mWh.
CurrentCapacityWatts float64
// CurrentPercentage is the current battery capacity as a percentage.
CurrentPercentage int
// CycleCount is the current cycle count.
CycleCount int
// DesignCapacityAmps is the design capacity in mAh.
DesignCapacityAmps int
// DesignCapacityWatts is the design capacity in mWh.
DesignCapacityWatts float64
// DeviceName is the battery device name.
DeviceName string
// FullyCharged indicates if the battery is fully charged.
FullyCharged bool
// Health is the battery health as a percentage (0-100%).
Health int
// IsCharging indicates if the battery is currently charging.
IsCharging bool
// MaxCapacityAmps is the maximum capacity in mAh.
MaxCapacityAmps int
// MaxCapacityWatts is the maximum capacity in mWh.
MaxCapacityWatts float64
// Serial is the battery serial number.
Serial string
// Temperature is the current temperature in °C.
Temperature float64
// TimeRemaining is the estimated time remaining until the battery is
// fully charged or discharged.
TimeRemaining time.Duration
// Voltage is the current voltage in mV.
Voltage int64
}
func newBattery(b *batteryRaw) *Battery {
volts := float64(b.Voltage) / 1000
return &Battery{
BatteryCellDisconnectCount: b.BatteryCellDisconnectCount,
BuiltIn: b.BuiltIn,
ChargeRateAmps: b.Amperage,
ChargeRateWatts: roundTo(float64(b.Amperage)*volts, 3),
CurrentCapacityAmps: b.CurrentCapacity,
CurrentCapacityWatts: roundTo(float64(b.CurrentCapacity)*volts, 3),
CurrentPercentage: b.CurrentPercentage,
CycleCount: b.CycleCount,
DesignCapacityAmps: b.DesignCapacity,
DesignCapacityWatts: roundTo(float64(b.DesignCapacity)*volts, 3),
DeviceName: b.DeviceName,
FullyCharged: b.FullyCharged,
Health: b.Health,
IsCharging: b.IsCharging,
MaxCapacityAmps: b.MaxCapacity,
MaxCapacityWatts: roundTo(float64(b.MaxCapacity)*volts, 3),
Serial: b.Serial,
Temperature: float64(b.Temperature) / 100,
TimeRemaining: time.Duration(b.TimeRemaining) * time.Minute,
Voltage: b.Voltage,
}
}
func Get() (*Battery, error) {
batteriesRaw, err := getAllRaw()
if err != nil {
return nil, err
}
return newBattery(batteriesRaw[0]), nil
}
func GetAll() ([]*Battery, error) {
batteriesRaw, err := getAllRaw()
if err != nil {
return nil, err
}
batteries := []*Battery{}
for _, b := range batteriesRaw {
batteries = append(batteries, newBattery(b))
}
return batteries, nil
}
// roundTo rounds a float64 to 'places' decimal places
func roundTo(value float64, places int) float64 {
shift := math.Pow(10, float64(places))
return math.Round(value*shift) / shift
}