77 lines
1.3 KiB
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
|
|
}
|
|
}
|