From b941f86ef0188a9f4fbfaa451d29c1fe8135b512 Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 12 Oct 2024 12:07:16 +0200 Subject: [PATCH] SofarSolar: ignore LSE3 modbus errors (#16618) --- provider/ignore.go | 92 +++++++++++++++++++ templates/definition/meter/sofarsolar-g3.yaml | 60 +++++++----- 2 files changed, 128 insertions(+), 24 deletions(-) create mode 100644 provider/ignore.go diff --git a/provider/ignore.go b/provider/ignore.go new file mode 100644 index 000000000..2f79618b9 --- /dev/null +++ b/provider/ignore.go @@ -0,0 +1,92 @@ +package provider + +import ( + "context" + "strings" + + "github.com/evcc-io/evcc/util" +) + +type ignoreProvider struct { + ctx context.Context + str string + set Config +} + +func init() { + registry.AddCtx("ignore", NewIgnoreFromConfig) +} + +// NewIgnoreFromConfig creates const provider +func NewIgnoreFromConfig(ctx context.Context, other map[string]interface{}) (Provider, error) { + var cc struct { + Error string + Set Config + } + + if err := util.DecodeOther(other, &cc); err != nil { + return nil, err + } + + o := &ignoreProvider{ + ctx: ctx, + str: cc.Error, + set: cc.Set, + } + + return o, nil +} + +var _ SetIntProvider = (*ignoreProvider)(nil) + +func ignoreError[T any](fun func(T) error, match string) func(T) error { + return func(val T) error { + err := fun(val) + if err != nil && strings.HasPrefix(err.Error(), match) { + err = nil + } + return err + } +} + +func (o *ignoreProvider) IntSetter(param string) (func(int64) error, error) { + set, err := NewIntSetterFromConfig(o.ctx, param, o.set) + if err != nil { + return nil, err + } + + return ignoreError(set, o.str), nil +} + +var _ SetFloatProvider = (*ignoreProvider)(nil) + +func (o *ignoreProvider) FloatSetter(param string) (func(float64) error, error) { + set, err := NewFloatSetterFromConfig(o.ctx, param, o.set) + if err != nil { + return nil, err + } + + return ignoreError(set, o.str), nil +} + +var _ SetBoolProvider = (*ignoreProvider)(nil) + +func (o *ignoreProvider) BoolSetter(param string) (func(bool) error, error) { + set, err := NewBoolSetterFromConfig(o.ctx, param, o.set) + if err != nil { + return nil, err + } + + return ignoreError(set, o.str), nil +} + +var _ SetBytesProvider = (*ignoreProvider)(nil) + +func (o *ignoreProvider) BytesSetter(param string) (func([]byte) error, error) { + set, err := NewBytesSetterFromConfig(o.ctx, param, o.set) + if err != nil { + return nil, err + } + + return ignoreError(set, o.str), nil +} diff --git a/templates/definition/meter/sofarsolar-g3.yaml b/templates/definition/meter/sofarsolar-g3.yaml index b11632e9d..570f31d66 100644 --- a/templates/definition/meter/sofarsolar-g3.yaml +++ b/templates/definition/meter/sofarsolar-g3.yaml @@ -152,18 +152,8 @@ render: | source: const value: 0 # self-use set: - source: modbus - {{- include "modbus" . | indent 8 }} - register: - address: 0x1110 - type: writemultiple - decode: int16 - - case: 2 # hold - set: - source: sequence - set: - - source: const - value: 3 # passive + source: ignore + error: "modbus: response data size '18' does not match count '4'" set: source: modbus {{- include "modbus" . | indent 10 }} @@ -171,18 +161,37 @@ render: | address: 0x1110 type: writemultiple decode: int16 + - case: 2 # hold + set: + source: sequence + set: + - source: const + value: 3 # passive + set: + source: ignore + error: "modbus: response data size '18' does not match count '4'" + set: + source: modbus + {{- include "modbus" . | indent 12 }} + register: + address: 0x1110 + type: writemultiple + decode: int16 - source: convert convert: int2bytes set: source: const value: '0x00000000_00000000_7FFFFFFF' set: - source: modbus - {{- include "modbus" . | indent 12 }} - register: - address: 0x1187 - type: writemultiple - decode: bytes + source: ignore + error: "modbus: response data size '18' does not match count '4'" + set: + source: modbus + {{- include "modbus" . | indent 14 }} + register: + address: 0x1187 + type: writemultiple + decode: bytes - case: 3 # charge (not implemented -> normal) set: source: const @@ -190,12 +199,15 @@ render: | set: source: sequence set: - - source: modbus - {{- include "modbus" . | indent 10 }} - register: - address: 0x1110 - type: writemultiple - decode: int16 + - source: ignore + error: "modbus: response data size '18' does not match count '4'" + set: + source: modbus + {{- include "modbus" . | indent 12 }} + register: + address: 0x1110 + type: writemultiple + decode: int16 - source: error error: ErrNotAvailable capacity: {{ .capacity }} # kWh