97 lines
1.8 KiB
Go
97 lines
1.8 KiB
Go
package plugin
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/evcc-io/evcc/plugin/sma"
|
|
"github.com/evcc-io/evcc/util"
|
|
"gitlab.com/bboehmke/sunny"
|
|
)
|
|
|
|
// SMA provider
|
|
type SMA struct {
|
|
device *sma.Device
|
|
value sunny.ValueID
|
|
scale float64
|
|
}
|
|
|
|
func init() {
|
|
registry.Add("sma", NewSMAFromConfig)
|
|
}
|
|
|
|
// NewSMAFromConfig creates SMA provider
|
|
func NewSMAFromConfig(other map[string]any) (Plugin, error) {
|
|
cc := struct {
|
|
URI, Password, Interface string
|
|
Serial uint32
|
|
Value string
|
|
Scale float64
|
|
}{
|
|
Password: "0000",
|
|
Scale: 1,
|
|
}
|
|
|
|
if err := util.DecodeOther(other, &cc); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
discoverer, err := sma.GetDiscoverer(cc.Interface)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get discoverer failed: %w", err)
|
|
}
|
|
|
|
o := &SMA{
|
|
scale: cc.Scale,
|
|
}
|
|
switch {
|
|
case cc.URI != "":
|
|
o.device, err = discoverer.DeviceByIP(cc.URI, cc.Password)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
case cc.Serial > 0:
|
|
o.device = discoverer.DeviceBySerial(cc.Serial, cc.Password)
|
|
if o.device == nil {
|
|
return nil, fmt.Errorf("device not found: %d", cc.Serial)
|
|
}
|
|
|
|
default:
|
|
return nil, errors.New("missing uri or serial")
|
|
}
|
|
|
|
o.value, err = sunny.ValueIDString(cc.Value)
|
|
|
|
return o, err
|
|
}
|
|
|
|
var _ FloatGetter = (*SMA)(nil)
|
|
|
|
// FloatGetter creates handler for float64
|
|
func (p *SMA) FloatGetter() (func() (float64, error), error) {
|
|
return func() (float64, error) {
|
|
values, err := p.device.Values()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return sma.AsFloat(values[p.value]) * p.scale, nil
|
|
}, nil
|
|
}
|
|
|
|
var _ IntGetter = (*SMA)(nil)
|
|
|
|
// IntGetter creates handler for int64
|
|
func (p *SMA) IntGetter() (func() (int64, error), error) {
|
|
g, err := p.FloatGetter()
|
|
|
|
return func() (int64, error) {
|
|
f, err := g()
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return int64(f), nil
|
|
}, err
|
|
}
|