From 78b7bfd6c36ac20145f90d537eb1f2e41e16b1be Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 14 Sep 2024 21:00:00 +0200 Subject: [PATCH] SolarMax: add battery discharge control (#16110) --- provider/error.go | 45 ++++++++++++ provider/random.go | 46 ++++++++++++ .../definition/meter/solarmax-maxstorage.yaml | 72 +++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 provider/error.go create mode 100644 provider/random.go diff --git a/provider/error.go b/provider/error.go new file mode 100644 index 0000000000..96087ccb9d --- /dev/null +++ b/provider/error.go @@ -0,0 +1,45 @@ +package provider + +import ( + "fmt" + + "github.com/evcc-io/evcc/util" +) + +type errorProvider struct { + err error +} + +func init() { + registry.Add("error", NewErrorFromConfig) +} + +// NewErrorFromConfig creates error provider +func NewErrorFromConfig(other map[string]interface{}) (Provider, error) { + var cc struct { + Error string + } + + if err := util.DecodeOther(other, &cc); err != nil { + return nil, err + } + + err := knownErrors([]byte(cc.Error)) + if err == nil { + return nil, fmt.Errorf("unknown error: %s", cc.Error) + } + + o := &errorProvider{ + err: err, + } + + return o, nil +} + +var _ SetIntProvider = (*errorProvider)(nil) + +func (o *errorProvider) IntSetter(param string) (func(int64) error, error) { + return func(int64) error { + return o.err + }, nil +} diff --git a/provider/random.go b/provider/random.go new file mode 100644 index 0000000000..e749b582b9 --- /dev/null +++ b/provider/random.go @@ -0,0 +1,46 @@ +package provider + +import ( + "math" + "math/rand/v2" + + "github.com/evcc-io/evcc/util" +) + +type randomProvider struct { + set Config +} + +func init() { + registry.Add("random", NewRandomFromConfig) +} + +// NewRandomFromConfig creates random provider +func NewRandomFromConfig(other map[string]interface{}) (Provider, error) { + var cc struct { + Set Config + } + + if err := util.DecodeOther(other, &cc); err != nil { + return nil, err + } + + o := &randomProvider{ + set: cc.Set, + } + + return o, nil +} + +var _ SetIntProvider = (*randomProvider)(nil) + +func (o *randomProvider) IntSetter(param string) (func(int64) error, error) { + set, err := NewIntSetterFromConfig(param, o.set) + if err != nil { + return nil, err + } + + return func(int64) error { + return set(rand.Int64N(math.MaxInt64-1) + 1) + }, nil +} diff --git a/templates/definition/meter/solarmax-maxstorage.yaml b/templates/definition/meter/solarmax-maxstorage.yaml index eaf689517d..dccbbf679d 100644 --- a/templates/definition/meter/solarmax-maxstorage.yaml +++ b/templates/definition/meter/solarmax-maxstorage.yaml @@ -47,5 +47,77 @@ render: | address: 122 # Batterie Soc type: input decode: int16 + batterymode: + source: watchdog + timeout: {{ .watchdog }} + reset: 1 # reset watchdog on normal + set: + source: switch + switch: + - case: 1 # normal + set: + source: sequence + set: + - source: const + value: 7000 + set: + source: modbus + {{- include "modbus" . | indent 12 }} + register: + address: 140 + type: writemultiple + decode: int16 + - source: const + value: 7000 + set: + source: modbus + {{- include "modbus" . | indent 12 }} + register: + address: 141 + type: writemultiple + decode: int16 + - source: const + value: 0 + set: + source: modbus + {{- include "modbus" . | indent 12 }} + register: + address: 142 + type: writemultiple + decode: int16 + - case: 2 # hold + set: + source: sequence + set: + - source: const + value: 0 + set: + source: modbus + {{- include "modbus" . | indent 12 }} + register: + address: 140 + type: writemultiple + decode: int16 + - source: const + value: 0 + set: + source: modbus + {{- include "modbus" . | indent 12 }} + register: + address: 141 + type: writemultiple + decode: int16 + - source: random + set: + source: modbus + {{- include "modbus" . | indent 12 }} + register: + address: 142 + type: writemultiple + decode: int16 + - case: 3 # charge (not implemented) + set: + source: error + error: ErrNotImplemented capacity: {{ .capacity }} # kWh {{- end }}