Kostal: add battery control (#10807)

This commit is contained in:
andig 2023-11-18 12:58:42 +01:00 • committed by GitHub
parent eb98e080a8
commit 8da3db2bab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 101 additions and 28 deletions

View file

@ -266,37 +266,88 @@ func (m *Modbus) BoolGetter() func() (bool, error) {
}
}
// IntSetter executes configured modbus write operation and implements SetIntProvider
func (m *Modbus) IntSetter(param string) func(int64) error {
return func(val int64) error {
var err error
// FloatSetter executes configured modbus write operation and implements SetFloatProvider
func (m *Modbus) FloatSetter(_ string) func(float64) error {
return func(val float64) error {
op := m.op.MBMD
if op.FuncCode == 0 {
return errors.New("modbus plugin does not support writing to sunspec")
}
// if funccode is configured, execute the read directly
if op := m.op.MBMD; op.FuncCode != 0 {
uval := uint16(m.scale * float64(val))
if op.FuncCode != gridx.FuncCodeWriteMultipleRegisters {
return fmt.Errorf("invalid write function code: %d", op.FuncCode)
}
switch op.FuncCode {
case gridx.FuncCodeWriteSingleRegister:
_, err = m.conn.WriteSingleRegister(op.OpCode, uval)
val = m.scale * val
case gridx.FuncCodeWriteMultipleRegisters:
var err error
switch op.ReadLen {
case 2:
var b [4]byte
binary.BigEndian.PutUint32(b[:], math.Float32bits(float32(val)))
_, err = m.conn.WriteMultipleRegisters(op.OpCode, 2, b[:])
case 4:
var b [8]byte
binary.BigEndian.PutUint64(b[:], math.Float64bits(val))
_, err = m.conn.WriteMultipleRegisters(op.OpCode, 4, b[:])
default:
err = fmt.Errorf("invalid write length: %d", op.ReadLen)
}
return err
}
}
// IntSetter executes configured modbus write operation and implements SetIntProvider
func (m *Modbus) IntSetter(_ string) func(int64) error {
return func(val int64) error {
op := m.op.MBMD
if op.FuncCode == 0 {
return errors.New("modbus plugin does not support writing to sunspec")
}
ival := int64(m.scale * float64(val))
// if funccode is configured, execute the read directly
var err error
switch op.FuncCode {
case gridx.FuncCodeWriteSingleRegister:
_, err = m.conn.WriteSingleRegister(op.OpCode, uint16(ival))
case gridx.FuncCodeWriteMultipleRegisters:
switch op.ReadLen {
case 1:
var b [2]byte
binary.BigEndian.PutUint16(b[:], uval)
binary.BigEndian.PutUint16(b[:], uint16(ival))
_, err = m.conn.WriteMultipleRegisters(op.OpCode, 1, b[:])
case gridx.FuncCodeWriteSingleCoil:
if uval != 0 {
// Modbus protocol requires 0xFF00 for ON
// and 0x0000 for OFF
uval = 0xFF00
}
_, err = m.conn.WriteSingleCoil(op.OpCode, uval)
case 2:
var b [4]byte
binary.BigEndian.PutUint32(b[:], uint32(ival))
_, err = m.conn.WriteMultipleRegisters(op.OpCode, 2, b[:])
case 4:
var b [8]byte
binary.BigEndian.PutUint64(b[:], uint64(ival))
_, err = m.conn.WriteMultipleRegisters(op.OpCode, 4, b[:])
default:
err = fmt.Errorf("invalid write function code: %d", op.FuncCode)
err = fmt.Errorf("invalid write length: %d", op.ReadLen)
}
} else {
err = errors.New("modbus plugin does not support writing to sunspec")
case gridx.FuncCodeWriteSingleCoil:
if ival != 0 {
// Modbus protocol requires 0xFF00 for ON
// and 0x0000 for OFF
ival = 0xFF00
}
_, err = m.conn.WriteSingleCoil(op.OpCode, uint16(ival))
default:
err = fmt.Errorf("invalid write function code: %d", op.FuncCode)
}
return err

View file

@ -19,6 +19,13 @@ params:
port: 1502
- name: capacity
advanced: true
# battery control
- name: minsoc
type: number
advanced: true
- name: maxsoc
type: number
advanced: true
render: |
{{- if eq .usage "pv" }}
type: custom
@ -39,12 +46,27 @@ render: |
value: 160:3:DCW # string 3
{{- end }}
{{- if eq .usage "battery" }}
type: modbus
{{- include "modbus" . }}
model: sunspec
power: 802:W # sunspec model 802 battery
soc: 802:SoC # sunspec model 802 battery
{{- if .capacity }}
type: custom
power:
source: modbus
{{- include "modbus" . | indent 2 }}
model: sunspec
value: 802:W # 802 battery control
soc:
source: modbus
{{- include "modbus" . | indent 2 }}
model: sunspec
value: 802:SoC # 802 battery control
limitsoc:
source: float2int
set:
source: modbus
{{- include "modbus" . | indent 4 }}
register:
address: 1042 # limit soc
type: writesingle
decode: uint16
capacity: {{ .capacity }} # kWh
{{- end }}
minsoc: {{ .minsoc }} # %
maxsoc: {{ .maxsoc }} # %
{{- end }}