Initial commit
This commit is contained in:
221
vendor/github.com/distatus/battery/battery_netbsd.go
generated
vendored
Normal file
221
vendor/github.com/distatus/battery/battery_netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
// battery
|
||||
// Copyright (C) 2016-2017,2023 Karol 'Kenji Takahashi' Woźniak
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
// a copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
package battery
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
plist "howett.net/plist"
|
||||
)
|
||||
|
||||
type plistref struct {
|
||||
pref_plist unsafe.Pointer
|
||||
pref_len uint64
|
||||
}
|
||||
|
||||
type values struct {
|
||||
Description string `plist:"description"`
|
||||
CurValue int `plist:"cur-value"`
|
||||
MaxValue int `plist:"max-value"`
|
||||
State string `plist:"state"`
|
||||
Type string `plist:"type"`
|
||||
}
|
||||
|
||||
type prop []values
|
||||
|
||||
type props map[string]prop
|
||||
|
||||
func readBytes(ptr unsafe.Pointer, length uint64) []byte {
|
||||
buf := make([]byte, length-1)
|
||||
var i uint64
|
||||
for ; i < length-1; i++ {
|
||||
buf[i] = *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(i)))
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
func readProps() (props, error) {
|
||||
fd, err := unix.Open("/dev/sysmon", unix.O_RDONLY, 0777)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer unix.Close(fd)
|
||||
|
||||
var retptr plistref
|
||||
|
||||
if err = ioctl(fd, 0, 'E', unsafe.Sizeof(retptr), unsafe.Pointer(&retptr)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bytes := readBytes(retptr.pref_plist, retptr.pref_len)
|
||||
|
||||
var props props
|
||||
if _, err = plist.Unmarshal(bytes, &props); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return props, nil
|
||||
}
|
||||
|
||||
func handleValue(val values, div float64, res *float64, amps *[]string) error {
|
||||
if val.State == "invalid" || val.State == "unknown" {
|
||||
return errors.New("Unknown value received")
|
||||
}
|
||||
|
||||
*res = float64(val.CurValue) / div
|
||||
|
||||
if amps != nil && strings.HasPrefix(val.Type, "Amp") {
|
||||
*amps = append(*amps, val.Description)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deriveState(cr1, cr2 error, current float64, max int) (AgnosticState, error) {
|
||||
if cr1 == nil && cr2 != nil {
|
||||
return Charging, nil
|
||||
}
|
||||
if cr1 != nil && cr2 == nil {
|
||||
return Discharging, nil
|
||||
}
|
||||
if cr1 != nil && cr2 != nil && current == float64(max)/1000 {
|
||||
return Full, nil
|
||||
}
|
||||
return Unknown, errors.New("Contradicting values received")
|
||||
}
|
||||
|
||||
func handleVoltage(amps []string, b *Battery, e *ErrPartial) {
|
||||
if e.DesignVoltage != nil && e.Voltage == nil {
|
||||
b.DesignVoltage, e.DesignVoltage = b.Voltage, nil
|
||||
}
|
||||
|
||||
for _, val := range amps {
|
||||
switch val {
|
||||
case "design cap":
|
||||
if e.DesignVoltage == nil {
|
||||
b.Design *= b.DesignVoltage
|
||||
} else {
|
||||
e.Design = e.DesignVoltage
|
||||
}
|
||||
case "last full cap":
|
||||
if e.Voltage == nil {
|
||||
b.Full *= b.Voltage
|
||||
} else {
|
||||
e.Full = e.Voltage
|
||||
}
|
||||
case "charge":
|
||||
if e.Voltage == nil {
|
||||
b.Current *= b.Voltage
|
||||
} else {
|
||||
e.Current = e.Voltage
|
||||
}
|
||||
case "charge rate", "discharge rate":
|
||||
if e.Voltage == nil {
|
||||
b.ChargeRate *= b.Voltage
|
||||
} else {
|
||||
e.ChargeRate = e.Voltage
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sortFilterProps(props props) []string {
|
||||
var keys []string
|
||||
for key := range props {
|
||||
if key[:7] != "acpibat" {
|
||||
continue
|
||||
}
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
func convertBattery(prop prop) (*Battery, error) {
|
||||
b := &Battery{}
|
||||
e := ErrPartial{}
|
||||
|
||||
amps := []string{}
|
||||
var cr1, cr2 error
|
||||
var maxCharge int
|
||||
|
||||
for _, val := range prop {
|
||||
switch val.Description {
|
||||
case "voltage":
|
||||
e.Voltage = handleValue(val, 1000000, &b.Voltage, nil)
|
||||
case "design voltage":
|
||||
e.DesignVoltage = handleValue(val, 1000000, &b.DesignVoltage, nil)
|
||||
case "design cap":
|
||||
e.Design = handleValue(val, 1000, &b.Design, &s)
|
||||
case "last full cap":
|
||||
e.Full = handleValue(val, 1000, &b.Full, &s)
|
||||
case "charge":
|
||||
e.Current = handleValue(val, 1000, &b.Current, &s)
|
||||
maxCharge = val.MaxValue
|
||||
case "charge rate":
|
||||
cr1 = handleValue(val, 1000, &b.ChargeRate, &s)
|
||||
case "discharge rate":
|
||||
cr2 = handleValue(val, 1000, &b.ChargeRate, &s)
|
||||
b.ChargeRate = math.Abs(b.ChargeRate)
|
||||
}
|
||||
}
|
||||
|
||||
b.State.Raw, e.State = deriveState(cr1, cr2, b.Current, maxCharge)
|
||||
b.State.specific = fmt.Sprintf("cr1: %v, cr2: %v")
|
||||
|
||||
handleVoltage(amps, b, &e)
|
||||
|
||||
return b, e
|
||||
}
|
||||
|
||||
func systemGet(idx int) (*Battery, error) {
|
||||
props, err := readProps()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keys := sortFilterProps(props)
|
||||
if idx >= len(keys) {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
return convertBattery(props[keys[idx]])
|
||||
}
|
||||
|
||||
func systemGetAll() ([]*Battery, error) {
|
||||
props, err := readProps()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keys := sortFilterProps(props)
|
||||
batteries := make([]*Battery, len(keys))
|
||||
errors := make(Errors, len(keys))
|
||||
for i, key := range keys {
|
||||
batteries[i], errors[i] = convertBattery(props[key])
|
||||
}
|
||||
|
||||
return batteries, errors
|
||||
}
|
||||
Reference in New Issue
Block a user