SolarEdge: add battery control (#10808)
This commit is contained in:
parent
ae33590e6b
commit
d01e9a85d9
4 changed files with 96 additions and 9 deletions
|
|
@ -8,8 +8,8 @@ type battery struct {
|
|||
MinSoc, MaxSoc float64
|
||||
}
|
||||
|
||||
// Decorator returns an api.BatteryController decorator
|
||||
func (m *battery) BatteryController(socG func() (float64, error), limitSocS func(float64) error) func(api.BatteryMode) error {
|
||||
// LimitController returns an api.BatteryController decorator
|
||||
func (m *battery) LimitController(socG func() (float64, error), limitSocS func(float64) error) func(api.BatteryMode) error {
|
||||
return func(mode api.BatteryMode) error {
|
||||
switch mode {
|
||||
case api.BatteryNormal:
|
||||
|
|
@ -30,3 +30,10 @@ func (m *battery) BatteryController(socG func() (float64, error), limitSocS func
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ModeController returns an api.BatteryController decorator
|
||||
func (m *battery) ModeController(modeS func(int64) error) func(api.BatteryMode) error {
|
||||
return func(mode api.BatteryMode) error {
|
||||
return modeS(int64(mode))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,10 +25,11 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
Powers []provider.Config // optional
|
||||
|
||||
// battery
|
||||
capacity `mapstructure:",squash"`
|
||||
battery `mapstructure:",squash"`
|
||||
Soc *provider.Config // optional
|
||||
LimitSoc *provider.Config // optional
|
||||
capacity `mapstructure:",squash"`
|
||||
battery `mapstructure:",squash"`
|
||||
Soc *provider.Config // optional
|
||||
LimitSoc *provider.Config // optional
|
||||
BatteryMode *provider.Config // optional
|
||||
}{
|
||||
battery: battery{
|
||||
MinSoc: 20,
|
||||
|
|
@ -84,13 +85,23 @@ func NewConfigurableFromConfig(other map[string]interface{}) (api.Meter, error)
|
|||
}
|
||||
|
||||
var batModeS func(api.BatteryMode) error
|
||||
if cc.Soc != nil && cc.LimitSoc != nil {
|
||||
|
||||
switch {
|
||||
case cc.Soc != nil && cc.LimitSoc != nil:
|
||||
limitSocS, err := provider.NewFloatSetterFromConfig("limitSoc", *cc.LimitSoc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("battery limit soc: %w", err)
|
||||
}
|
||||
|
||||
batModeS = cc.battery.BatteryController(socG, limitSocS)
|
||||
batModeS = cc.battery.LimitController(socG, limitSocS)
|
||||
|
||||
case cc.BatteryMode != nil:
|
||||
modeS, err := provider.NewIntSetterFromConfig("mode", *cc.BatteryMode)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("battery mode: %w", err)
|
||||
}
|
||||
|
||||
batModeS = cc.battery.ModeController(modeS)
|
||||
}
|
||||
|
||||
res := m.Decorate(totalEnergyG, currentsG, voltagesG, powersG, socG, cc.capacity.Decorator(), batModeS)
|
||||
|
|
|
|||
53
provider/map.go
Normal file
53
provider/map.go
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/evcc-io/evcc/util"
|
||||
)
|
||||
|
||||
type mapProvider struct {
|
||||
values map[int64]int64
|
||||
set Config
|
||||
}
|
||||
|
||||
func init() {
|
||||
registry.Add("map", NewMapFromConfig)
|
||||
}
|
||||
|
||||
// NewMapFromConfig creates type conversion provider
|
||||
func NewMapFromConfig(other map[string]interface{}) (Provider, error) {
|
||||
var cc struct {
|
||||
Values map[int64]int64
|
||||
Set Config
|
||||
}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(cc.Values) == 0 {
|
||||
return nil, fmt.Errorf("missing values")
|
||||
}
|
||||
|
||||
o := &mapProvider{
|
||||
set: cc.Set,
|
||||
values: cc.Values,
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
var _ SetIntProvider = (*mapProvider)(nil)
|
||||
|
||||
func (o *mapProvider) IntSetter(param string) (func(int64) error, error) {
|
||||
set, err := NewIntSetterFromConfig(param, o.set)
|
||||
|
||||
return func(val int64) error {
|
||||
m, ok := o.values[val]
|
||||
if !ok {
|
||||
return fmt.Errorf("value %d not found", val)
|
||||
}
|
||||
return set(m)
|
||||
}, err
|
||||
}
|
||||
|
|
@ -20,8 +20,8 @@ params:
|
|||
advanced: true
|
||||
render: |
|
||||
type: custom
|
||||
power:
|
||||
{{- if eq .usage "grid" }}
|
||||
power:
|
||||
source: modbus
|
||||
{{- include "modbus" . | indent 2 }}
|
||||
timeout: {{ .timeout }}
|
||||
|
|
@ -31,6 +31,7 @@ render: |
|
|||
scale: -1
|
||||
{{- end }}
|
||||
{{- if eq .usage "pv" }}
|
||||
power:
|
||||
source: calc
|
||||
add:
|
||||
- source: modbus
|
||||
|
|
@ -47,6 +48,7 @@ render: |
|
|||
decode: float32s
|
||||
{{- end }}
|
||||
{{- if eq .usage "battery" }}
|
||||
power:
|
||||
source: modbus
|
||||
{{- include "modbus" . | indent 2 }}
|
||||
timeout: {{ .timeout }}
|
||||
|
|
@ -63,6 +65,20 @@ render: |
|
|||
address: 62852 # Battery 1 State of Energy (SOE)
|
||||
type: holding
|
||||
decode: float32s
|
||||
batterymode:
|
||||
source: map
|
||||
values:
|
||||
1: 7 # normal
|
||||
2: 1 # hold
|
||||
3: 3 # charge
|
||||
set:
|
||||
source: modbus
|
||||
{{- include "modbus" . | indent 4 }}
|
||||
timeout: {{ .timeout }}
|
||||
register:
|
||||
address: 0xE00A # Battery mode
|
||||
type: writesingle
|
||||
decode: uint16
|
||||
{{- if .capacity }}
|
||||
capacity: {{ .capacity }} # kWh
|
||||
{{- end }}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue