EM24: fix decoding (#3348)
This commit is contained in:
parent
6832b5f364
commit
6ee4b7e436
7 changed files with 41 additions and 68 deletions
|
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/modbus"
|
||||
"github.com/evcc-io/evcc/util/sponsor"
|
||||
"github.com/volkszaehler/mbmd/encoding"
|
||||
"github.com/volkszaehler/mbmd/meters/rs485"
|
||||
)
|
||||
|
||||
|
|
@ -177,7 +178,7 @@ var _ api.Diagnosis = (*Amtron)(nil)
|
|||
// Diagnose implements the api.Diagnosis interface
|
||||
func (wb *Amtron) Diagnose() {
|
||||
if b, err := wb.conn.ReadInputRegisters(amtronRegName, 11); err == nil {
|
||||
fmt.Printf("Name: %s\n", modbus.RTUStringSwapped(b))
|
||||
fmt.Printf("Name: %s\n", encoding.StringLsbFirst(b))
|
||||
}
|
||||
|
||||
if b, err := wb.conn.ReadInputRegisters(amtronRegPhases, 1); err == nil {
|
||||
|
|
|
|||
|
|
@ -228,6 +228,6 @@ var _ api.Diagnosis = (*Wallbe)(nil)
|
|||
// Diagnose implements the Diagnosis interface
|
||||
func (wb *Wallbe) Diagnose() {
|
||||
if b, err := wb.conn.ReadInputRegisters(wbRegFirmware, 6); err == nil {
|
||||
fmt.Printf("Firmware:\t%s\n", encoding.StringSwapped(b))
|
||||
fmt.Printf("Firmware:\t%s\n", encoding.StringLsbFirst(b))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -73,7 +73,7 @@ require (
|
|||
github.com/spf13/viper v1.11.0
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c
|
||||
github.com/volkszaehler/mbmd v0.0.0-20220429083530-4218d966b2dc
|
||||
github.com/volkszaehler/mbmd v0.0.0-20220509062004-21ece8c27e5e
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
gitlab.com/bboehmke/sunny v0.15.1-0.20211022160056-2fba1c86ade6
|
||||
golang.org/x/exp v0.0.0-20220428152302-39d4317da171
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -902,8 +902,8 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9
|
|||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
github.com/volkszaehler/mbmd v0.0.0-20220429083530-4218d966b2dc h1:ErvZcShn2BDQoeU/RQw9z/Y33yqu1ECe1ko6zza/MF0=
|
||||
github.com/volkszaehler/mbmd v0.0.0-20220429083530-4218d966b2dc/go.mod h1:JP4R5rxFO4QlDo/DoNp8YrPD2YV0+imTfRTL5xBCUjs=
|
||||
github.com/volkszaehler/mbmd v0.0.0-20220509062004-21ece8c27e5e h1:2dGaYpWS+pW4L6cvBQndHvkvhpUt5ZEHErWUADbd0ug=
|
||||
github.com/volkszaehler/mbmd v0.0.0-20220509062004-21ece8c27e5e/go.mod h1:JP4R5rxFO4QlDo/DoNp8YrPD2YV0+imTfRTL5xBCUjs=
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible h1:IIqxTM5Jr7RzhigcL6FkrCNfXkvbR+Nbu1ls48pXYcw=
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible/go.mod h1:Rsyu10ZhbEK9pXdk8V6MVnZmTzRG0alMNLMwa0J01fE=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ template: cg-em24
|
|||
products:
|
||||
- brand: Carlo Gavazzi
|
||||
description:
|
||||
generic: EM 24
|
||||
generic: EM24 E1
|
||||
params:
|
||||
- name: usage
|
||||
choice: ["grid", "pv", "battery", "charge"]
|
||||
- name: modbus
|
||||
choice: ["rs485"]
|
||||
choice: ["tcpip"]
|
||||
render: |
|
||||
type: modbus
|
||||
model: cgem24
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
product:
|
||||
brand: Carlo Gavazzi
|
||||
description: EM 24
|
||||
description: EM24 E1
|
||||
render:
|
||||
- usage: grid
|
||||
default: |
|
||||
|
|
@ -8,15 +8,8 @@ render:
|
|||
template: cg-em24
|
||||
usage: grid
|
||||
|
||||
# RS485 via adapter (Modbus RTU)
|
||||
modbus: rs485serial
|
||||
id: 1
|
||||
device: /dev/ttyUSB0 # USB-RS485 Adapter Adresse
|
||||
baudrate: 9600 # Prüfe die Geräteeinstellungen, typische Werte sind 9600, 19200, 38400, 57600, 115200
|
||||
comset: "8N1" # Kommunikationsparameter für den Adapter
|
||||
|
||||
# RS485 via TCP/IP (Modbus RTU)
|
||||
modbus: rs485tcpip
|
||||
# Modbus TCP
|
||||
modbus: tcpip
|
||||
id: 1
|
||||
host: 192.0.2.2 # Hostname
|
||||
port: 502 # Port
|
||||
|
|
@ -26,15 +19,8 @@ render:
|
|||
template: cg-em24
|
||||
usage: pv
|
||||
|
||||
# RS485 via adapter (Modbus RTU)
|
||||
modbus: rs485serial
|
||||
id: 1
|
||||
device: /dev/ttyUSB0 # USB-RS485 Adapter Adresse
|
||||
baudrate: 9600 # Prüfe die Geräteeinstellungen, typische Werte sind 9600, 19200, 38400, 57600, 115200
|
||||
comset: "8N1" # Kommunikationsparameter für den Adapter
|
||||
|
||||
# RS485 via TCP/IP (Modbus RTU)
|
||||
modbus: rs485tcpip
|
||||
# Modbus TCP
|
||||
modbus: tcpip
|
||||
id: 1
|
||||
host: 192.0.2.2 # Hostname
|
||||
port: 502 # Port
|
||||
|
|
@ -44,15 +30,8 @@ render:
|
|||
template: cg-em24
|
||||
usage: battery
|
||||
|
||||
# RS485 via adapter (Modbus RTU)
|
||||
modbus: rs485serial
|
||||
id: 1
|
||||
device: /dev/ttyUSB0 # USB-RS485 Adapter Adresse
|
||||
baudrate: 9600 # Prüfe die Geräteeinstellungen, typische Werte sind 9600, 19200, 38400, 57600, 115200
|
||||
comset: "8N1" # Kommunikationsparameter für den Adapter
|
||||
|
||||
# RS485 via TCP/IP (Modbus RTU)
|
||||
modbus: rs485tcpip
|
||||
# Modbus TCP
|
||||
modbus: tcpip
|
||||
id: 1
|
||||
host: 192.0.2.2 # Hostname
|
||||
port: 502 # Port
|
||||
|
|
@ -62,15 +41,8 @@ render:
|
|||
template: cg-em24
|
||||
usage: charge
|
||||
|
||||
# RS485 via adapter (Modbus RTU)
|
||||
modbus: rs485serial
|
||||
id: 1
|
||||
device: /dev/ttyUSB0 # USB-RS485 Adapter Adresse
|
||||
baudrate: 9600 # Prüfe die Geräteeinstellungen, typische Werte sind 9600, 19200, 38400, 57600, 115200
|
||||
comset: "8N1" # Kommunikationsparameter für den Adapter
|
||||
|
||||
# RS485 via TCP/IP (Modbus RTU)
|
||||
modbus: rs485tcpip
|
||||
# Modbus TCP
|
||||
modbus: tcpip
|
||||
id: 1
|
||||
host: 192.0.2.2 # Hostname
|
||||
port: 502 # Port
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ import (
|
|||
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/grid-x/modbus"
|
||||
"github.com/volkszaehler/mbmd/encoding"
|
||||
"github.com/volkszaehler/mbmd/meters"
|
||||
"github.com/volkszaehler/mbmd/meters/rs485"
|
||||
"github.com/volkszaehler/mbmd/meters/sunspec"
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
type Protocol int
|
||||
|
|
@ -272,6 +274,13 @@ type Register struct {
|
|||
BitMask string
|
||||
}
|
||||
|
||||
// asFloat64 creates a function that returns numerics vales as float64
|
||||
func asFloat64[T constraints.Signed | constraints.Unsigned | constraints.Float](f func([]byte) T) func([]byte) float64 {
|
||||
return func(v []byte) float64 {
|
||||
return float64(f(v))
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterOperation creates a read operation from a register definition
|
||||
func RegisterOperation(r Register) (rs485.Operation, error) {
|
||||
op := rs485.Operation{
|
||||
|
|
@ -294,16 +303,16 @@ func RegisterOperation(r Register) (rs485.Operation, error) {
|
|||
|
||||
// 16 bit
|
||||
case "int16":
|
||||
op.Transform = rs485.RTUInt16ToFloat64
|
||||
op.Transform = asFloat64(encoding.Int16)
|
||||
op.ReadLen = 1
|
||||
case "int16nan":
|
||||
op.Transform = decodeNaN16(1<<15, rs485.RTUInt16ToFloat64)
|
||||
op.Transform = decodeNaN16(1<<15, asFloat64(encoding.Int16))
|
||||
op.ReadLen = 1
|
||||
case "uint16":
|
||||
op.Transform = rs485.RTUUint16ToFloat64
|
||||
op.Transform = asFloat64(encoding.Uint16)
|
||||
op.ReadLen = 1
|
||||
case "uint16nan":
|
||||
op.Transform = decodeNaN16(0xFFFF, rs485.RTUUint16ToFloat64)
|
||||
op.Transform = decodeNaN16(0xFFFF, asFloat64(encoding.Uint16))
|
||||
op.ReadLen = 1
|
||||
case "bool16":
|
||||
mask, err := decodeMask(r.BitMask)
|
||||
|
|
@ -315,31 +324,31 @@ func RegisterOperation(r Register) (rs485.Operation, error) {
|
|||
|
||||
// 32 bit
|
||||
case "int32":
|
||||
op.Transform = rs485.RTUInt32ToFloat64
|
||||
op.Transform = asFloat64(encoding.Int32)
|
||||
case "int32nan":
|
||||
op.Transform = decodeNaN32(1<<31, rs485.RTUInt32ToFloat64)
|
||||
op.Transform = decodeNaN32(1<<31, asFloat64(encoding.Int32))
|
||||
case "int32s":
|
||||
op.Transform = rs485.RTUInt32ToFloat64Swapped
|
||||
op.Transform = asFloat64(encoding.Int32LswFirst)
|
||||
case "uint32":
|
||||
op.Transform = rs485.RTUUint32ToFloat64
|
||||
op.Transform = asFloat64(encoding.Uint32)
|
||||
case "uint32s":
|
||||
op.Transform = rs485.RTUUint32ToFloat64Swapped
|
||||
op.Transform = asFloat64(encoding.Uint32LswFirst)
|
||||
case "uint32nan":
|
||||
op.Transform = decodeNaN32(0xFFFFFFFF, rs485.RTUUint32ToFloat64)
|
||||
op.Transform = decodeNaN32(0xFFFFFFFF, asFloat64(encoding.Uint32))
|
||||
case "float32", "ieee754":
|
||||
op.Transform = rs485.RTUIeee754ToFloat64
|
||||
op.Transform = asFloat64(encoding.Float32)
|
||||
case "float32s", "ieee754s":
|
||||
op.Transform = rs485.RTUIeee754ToFloat64Swapped
|
||||
op.Transform = asFloat64(encoding.Float32LswFirst)
|
||||
|
||||
// 64 bit
|
||||
case "uint64":
|
||||
op.Transform = rs485.RTUUint64ToFloat64
|
||||
op.Transform = asFloat64(encoding.Uint64)
|
||||
op.ReadLen = 4
|
||||
case "uint64nan":
|
||||
op.Transform = decodeNaN64(0xFFFFFFFFFFFFFFFF, rs485.RTUUint64ToFloat64)
|
||||
op.Transform = decodeNaN64(0xFFFFFFFFFFFFFFFF, asFloat64(encoding.Uint64))
|
||||
op.ReadLen = 4
|
||||
case "float64":
|
||||
op.Transform = rs485.RTUFloat64ToFloat64
|
||||
op.Transform = encoding.Float64
|
||||
op.ReadLen = 4
|
||||
|
||||
default:
|
||||
|
|
@ -349,15 +358,6 @@ func RegisterOperation(r Register) (rs485.Operation, error) {
|
|||
return op, nil
|
||||
}
|
||||
|
||||
func RTUStringSwapped(b []byte) string {
|
||||
s := new(strings.Builder)
|
||||
for i := 0; i < len(b); i += 2 {
|
||||
s.WriteByte(b[i+1])
|
||||
s.WriteByte(b[i])
|
||||
}
|
||||
return s.String()
|
||||
}
|
||||
|
||||
// SunSpecOperation is a sunspec modbus operation
|
||||
type SunSpecOperation struct {
|
||||
Model, Block int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue