Modbus: add bytes setter (#16510)

This commit is contained in:
andig 2024-10-12 11:09:12 +02:00 • committed by GitHub
parent 5e482972e0
commit 11d2b8b85d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 97 additions and 40 deletions

View file

@ -36,6 +36,9 @@ type (
SetBoolProvider interface {
BoolSetter(param string) (func(bool) error, error)
}
SetBytesProvider interface {
BytesSetter(param string) (func([]byte) error, error)
}
)
// Config is the general provider config
@ -144,3 +147,13 @@ func NewBoolSetterFromConfig(ctx context.Context, param string, config Config) (
return prov.BoolSetter(param)
}
// NewBytesSetterFromConfig creates a BytesSetter from config
func NewBytesSetterFromConfig(param string, config Config) (func([]byte) error, error) {
prov, err := provider[SetBytesProvider]("bytes", config)
if err != nil {
return nil, err
}
return prov.BytesSetter(param)
}

View file

@ -2,7 +2,9 @@ package provider
import (
"context"
"encoding/hex"
"strconv"
"strings"
"github.com/evcc-io/evcc/provider/pipeline"
"github.com/evcc-io/evcc/util"
@ -149,3 +151,23 @@ func (o *constProvider) BoolSetter(param string) (func(bool) error, error) {
return set(val)
}, err
}
var _ SetBytesProvider = (*constProvider)(nil)
func (o *constProvider) BytesSetter(param string) (func([]byte) error, error) {
set, err := NewBytesSetterFromConfig(param, o.set)
if err != nil {
return nil, err
}
str := strings.ReplaceAll(strings.TrimPrefix(o.str, "0x"), "_", "")
val, err := hex.DecodeString(str)
if err != nil {
err = nil
}
return func(_ []byte) error {
return set(val)
}, err
}

View file

@ -2,6 +2,7 @@ package provider
import (
"context"
"encoding/binary"
"fmt"
"github.com/evcc-io/evcc/util"
@ -33,27 +34,40 @@ func NewConvertFromConfig(ctx context.Context, other map[string]interface{}) (Pr
var _ SetFloatProvider = (*convertProvider)(nil)
func (o *convertProvider) FloatSetter(param string) (func(float64) error, error) {
if o.Convert != "float2int" {
switch o.Convert {
case "float2int":
set, err := NewIntSetterFromConfig(o.ctx, param, o.Set)
return func(val float64) error {
return set(int64(val))
}, err
default:
return nil, fmt.Errorf("convert: invalid conversion: %s", o.Convert)
}
set, err := NewIntSetterFromConfig(o.ctx, param, o.Set)
return func(val float64) error {
return set(int64(val))
}, err
}
var _ SetIntProvider = (*convertProvider)(nil)
func (o *convertProvider) IntSetter(param string) (func(int64) error, error) {
if o.Convert != "int2float" {
switch o.Convert {
case "int2float":
set, err := NewFloatSetterFromConfig(o.ctx, param, o.Set)
return func(val int64) error {
return set(float64(val))
}, err
case "int2bytes":
set, err := NewBytesSetterFromConfig(o.ctx, param, o.Set)
return func(val int64) error {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(val))
return set(b)
}, err
default:
return nil, fmt.Errorf("convert: invalid conversion: %s", o.Convert)
}
set, err := NewFloatSetterFromConfig(o.ctx, param, o.Set)
return func(val int64) error {
return set(float64(val))
}, err
}

View file

@ -234,3 +234,24 @@ func (m *Modbus) BoolSetter(param string) (func(bool) error, error) {
return set(ival)
}, err
}
var _ SetBytesProvider = (*Modbus)(nil)
// BytesSetter implements SetBytesProvider
func (m *Modbus) BytesSetter(_ string) (func([]byte) error, error) {
op, err := m.reg.Operation()
if err != nil {
return nil, err
}
return func(val []byte) error {
switch op.FuncCode {
case gridx.FuncCodeWriteMultipleRegisters:
_, err = m.conn.WriteMultipleRegisters(op.Addr, uint16(len(val)/2), val)
return err
default:
return fmt.Errorf("invalid func code: %d", op.FuncCode)
}
}, nil
}

View file

@ -171,33 +171,18 @@ render: |
address: 0x1110
type: writemultiple
decode: int16
- source: const
value: 0
- source: convert
convert: int2bytes
set:
source: modbus
{{- include "modbus" . | indent 10 }}
register:
address: 0x1187
type: writemultiple
decode: int32
- source: const
value: 0
set:
source: modbus
{{- include "modbus" . | indent 10 }}
register:
address: 0x1189
type: writemultiple
decode: int32
- source: const
value: 0x7FFFFFFF
set:
source: modbus
{{- include "modbus" . | indent 10 }}
register:
address: 0x118B
type: writemultiple
decode: int32
source: const
value: '0x00000000_00000000_7FFFFFFF'
set:
source: modbus
{{- include "modbus" . | indent 12 }}
register:
address: 0x1187
type: writemultiple
decode: bytes
- case: 3 # charge (not implemented -> normal)
set:
source: const

View file

@ -50,6 +50,8 @@ func (r Register) Length() (uint16, error) {
return 2, nil
case strings.Contains(enc, "64"):
return 4, nil
case strings.EqualFold(enc, "bytes"):
return 0, nil
default:
return 0, fmt.Errorf("invalid register length: %s", enc)
}