SMA: add battery params (BC) (#26899)
This commit is contained in:
parent
37bee0cde5
commit
7f812f8b71
5 changed files with 31 additions and 78 deletions
46
meter/sma.go
46
meter/sma.go
|
|
@ -24,13 +24,14 @@ func init() {
|
|||
registry.Add("sma", NewSMAFromConfig)
|
||||
}
|
||||
|
||||
//go:generate go tool decorate -f decorateSMA -b *SMA -r api.Meter -t "api.Battery,Soc,func() (float64, error)" -t "api.BatteryCapacity,Capacity,func() float64"
|
||||
|
||||
// NewSMAFromConfig creates an SMA meter from generic config
|
||||
func NewSMAFromConfig(other map[string]any) (api.Meter, error) {
|
||||
cc := struct {
|
||||
batteryCapacity `mapstructure:",squash"`
|
||||
batteryPowerLimits `mapstructure:",squash"`
|
||||
batterySocLimits `mapstructure:",squash"`
|
||||
URI, Password, Interface string
|
||||
Usage string
|
||||
Serial uint32
|
||||
Scale float64 // power only
|
||||
}{
|
||||
|
|
@ -42,11 +43,24 @@ func NewSMAFromConfig(other map[string]any) (api.Meter, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return NewSMA(cc.URI, cc.Password, cc.Interface, cc.Serial, cc.Scale, cc.batteryCapacity.Decorator())
|
||||
sm, err := NewSMA(cc.URI, cc.Password, cc.Interface, cc.Serial, cc.Scale)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cc.Usage == "battery" {
|
||||
return decorateMeterBattery(
|
||||
sm, sm.TotalEnergy,
|
||||
sm.soc, cc.batteryCapacity.Decorator(),
|
||||
cc.batterySocLimits.Decorator(), cc.batteryPowerLimits.Decorator(), nil,
|
||||
), nil
|
||||
}
|
||||
|
||||
return sm, nil
|
||||
}
|
||||
|
||||
// NewSMA creates an SMA meter
|
||||
func NewSMA(uri, password, iface string, serial uint32, scale float64, capacity func() float64) (api.Meter, error) {
|
||||
func NewSMA(uri, password, iface string, serial uint32, scale float64) (*SMA, error) {
|
||||
sm := &SMA{
|
||||
uri: uri,
|
||||
scale: scale,
|
||||
|
|
@ -82,20 +96,7 @@ func NewSMA(uri, password, iface string, serial uint32, scale float64, capacity
|
|||
// start update loop manually to get values as fast as possible
|
||||
go sm.device.Run()
|
||||
|
||||
// decorate api.Battery in case of inverter
|
||||
var soc func() (float64, error)
|
||||
if !sm.device.IsEnergyMeter() {
|
||||
vals, err := sm.device.Values()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, ok := vals[sunny.BatteryCharge]; ok {
|
||||
soc = sm.soc
|
||||
}
|
||||
}
|
||||
|
||||
return decorateSMA(sm, soc, capacity), nil
|
||||
return sm, nil
|
||||
}
|
||||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
|
|
@ -170,7 +171,14 @@ func (sm *SMA) Powers() (float64, float64, float64, error) {
|
|||
// soc implements the api.Battery interface
|
||||
func (sm *SMA) soc() (float64, error) {
|
||||
values, err := sm.device.Values()
|
||||
return sma.AsFloat(values[sunny.BatteryCharge]), err
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
soc, ok := values[sunny.BatteryCharge]
|
||||
if !ok {
|
||||
return 0, api.ErrNotAvailable
|
||||
}
|
||||
return sma.AsFloat(soc), nil
|
||||
}
|
||||
|
||||
var _ api.Diagnosis = (*SMA)(nil)
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
package meter
|
||||
|
||||
// Code generated by github.com/evcc-io/evcc/cmd/tools/decorate.go. DO NOT EDIT.
|
||||
|
||||
import (
|
||||
"github.com/evcc-io/evcc/api"
|
||||
)
|
||||
|
||||
func decorateSMA(base *SMA, battery func() (float64, error), batteryCapacity func() float64) api.Meter {
|
||||
switch {
|
||||
case battery == nil:
|
||||
return base
|
||||
|
||||
case battery != nil && batteryCapacity == nil:
|
||||
return &struct {
|
||||
*SMA
|
||||
api.Battery
|
||||
}{
|
||||
SMA: base,
|
||||
Battery: &decorateSMABatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
}
|
||||
|
||||
case battery != nil && batteryCapacity != nil:
|
||||
return &struct {
|
||||
*SMA
|
||||
api.Battery
|
||||
api.BatteryCapacity
|
||||
}{
|
||||
SMA: base,
|
||||
Battery: &decorateSMABatteryImpl{
|
||||
battery: battery,
|
||||
},
|
||||
BatteryCapacity: &decorateSMABatteryCapacityImpl{
|
||||
batteryCapacity: batteryCapacity,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type decorateSMABatteryImpl struct {
|
||||
battery func() (float64, error)
|
||||
}
|
||||
|
||||
func (impl *decorateSMABatteryImpl) Soc() (float64, error) {
|
||||
return impl.battery()
|
||||
}
|
||||
|
||||
type decorateSMABatteryCapacityImpl struct {
|
||||
batteryCapacity func() float64
|
||||
}
|
||||
|
||||
func (impl *decorateSMABatteryCapacityImpl) Capacity() float64 {
|
||||
return impl.batteryCapacity()
|
||||
}
|
||||
|
|
@ -39,6 +39,8 @@ type batterySocLimits struct {
|
|||
MinSoc, MaxSoc float64
|
||||
}
|
||||
|
||||
// var _ api.BatterySocLimiter = (*batterySocLimits)(nil)
|
||||
|
||||
// Decorator returns an api.BatterySocLimiter decorator
|
||||
func (m *batterySocLimits) Decorator() func() (float64, float64) {
|
||||
if m.MinSoc == 0 && m.MaxSoc == 0 {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ render: |
|
|||
id: {{ .id }}
|
||||
register:
|
||||
address: 2201 # SUR Überschussleistung Auflösung 1 W
|
||||
type: writeholding
|
||||
type: writesingle
|
||||
decode: int16
|
||||
power:
|
||||
source: modbus
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ params:
|
|||
- preset: battery-params
|
||||
render: |
|
||||
type: sma
|
||||
usage: {{ .usage }}
|
||||
uri: {{ .host }} # IP address or hostname
|
||||
password: {{ .password }} # optional
|
||||
{{- if eq .usage "battery" }}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue