evcc-io/provider/sma/device.go

77 lines
1.3 KiB
Go

package sma
import (
"maps"
"sync"
"time"
"github.com/evcc-io/evcc/util"
"gitlab.com/bboehmke/sunny"
)
// Device holds information for a Device and provides interface to get values
type Device struct {
*sunny.Device
log *util.Logger
values *util.Monitor[map[sunny.ValueID]any]
once sync.Once
}
// Run starts the receive loop once per device
func (d *Device) Run() {
d.once.Do(d.run)
}
func (d *Device) run() {
for range time.Tick(5 * time.Second) {
if err := d.UpdateValues(); err != nil {
d.log.ERROR.Println(err)
}
}
}
func (d *Device) UpdateValues() error {
res, err := d.Device.GetValues()
if err == nil {
d.values.SetFunc(func(state map[sunny.ValueID]any) map[sunny.ValueID]any {
if state == nil {
return res
}
maps.Copy(state, res)
return state
})
}
return err
}
func (d *Device) Values() (map[sunny.ValueID]any, error) {
var res map[sunny.ValueID]any
err := d.values.GetFunc(func(state map[sunny.ValueID]any) {
res = maps.Clone(state)
})
return res, err
}
func AsFloat(value any) float64 {
switch v := value.(type) {
case float64:
return v
case int32:
return float64(v)
case int64:
return float64(v)
case uint32:
return float64(v)
case uint64:
return float64(v)
case nil:
return 0
default:
util.NewLogger("sma").WARN.Printf("unknown value type: %T", value)
return 0
}
}