diff --git a/battery.go b/battery.go index 54fc59b..d175f20 100644 --- a/battery.go +++ b/battery.go @@ -36,6 +36,7 @@ package battery import ( "fmt" + "math" "strings" ) @@ -154,3 +155,32 @@ func getAll(sg func() ([]*Battery, error)) ([]*Battery, error) { func GetAll() ([]*Battery, error) { return getAll(systemGetAll) } + +func summarize(sg func() ([]*Battery, error)) (*Battery, error) { + bs, err := sg() + if err != nil { + return nil, err + } + if len(bs) == 1 { + return bs[0], nil + } + res := new(Battery) + for _, battery := range bs { + res.Current += battery.Current + res.Full += battery.Full + res.ChargeRate += battery.ChargeRate + res.Design += battery.Design + res.Voltage = math.Max(res.Voltage, battery.Voltage) + res.DesignVoltage = math.Max(res.DesignVoltage, battery.DesignVoltage) + res.State = State(math.Max(float64(res.State), float64(battery.State))) + } + return res, nil +} + +// Summarize returns aggregated information about all batteries in the system. +// +// If error != nil, it will be either ErrFatal or Errors. +// If error is of type Errors, it is guaranteed that length of both returned slices is the same and that i-th error coresponds with i-th battery structure. +func Summarize() (*Battery, error) { + return summarize(systemGetAll) +} diff --git a/battery_test.go b/battery_test.go index 901618a..576557d 100644 --- a/battery_test.go +++ b/battery_test.go @@ -206,3 +206,44 @@ func ExampleGet_errors() { fmt.Println("Got current battery capacity") } } + +func TestSummarize(t *testing.T) { + cases := []struct { + batteriesIn []*Battery + batterieOut *Battery + }{{ + []*Battery{{Full: 1}, {Full: 3}}, + &Battery{Full: 4}, + }, { + []*Battery{{Current: 3}, {Current: 2}}, + &Battery{Current: 5}, + }, { + []*Battery{{Design: 3}, {Design: 1}}, + &Battery{Design: 4}, + }, { + []*Battery{{ChargeRate: 3}, {ChargeRate: 1}}, + &Battery{ChargeRate: 4}, + }, { + []*Battery{{Voltage: 220}, {Voltage: 110}}, + &Battery{Voltage: 220}, + }, { + []*Battery{{DesignVoltage: 220}, {DesignVoltage: 110}}, + &Battery{DesignVoltage: 220}, + }, { + []*Battery{{State: Empty}, {State: Charging}}, + &Battery{State: Charging}, + }, + } + + for i, c := range cases { + f := func() ([]*Battery, error) { + return c.batteriesIn, nil + } + batterie, _ := summarize(f) + + if !reflect.DeepEqual(batterie, c.batterieOut) { + t.Errorf("%d: %v != %v", i, batterie, c.batterieOut) + } + + } +}