From c31ba94bb859eb451e02f674eeaf5bfac722f9eb Mon Sep 17 00:00:00 2001 From: Steven Soroka Date: Tue, 10 Mar 2020 16:46:36 -0400 Subject: [PATCH] modbus to support scaling int32 and float32-ieee (#7148) --- plugins/inputs/modbus/modbus.go | 25 ++++++++++++++++--------- plugins/inputs/modbus/modbus_test.go | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/plugins/inputs/modbus/modbus.go b/plugins/inputs/modbus/modbus.go index d2e913039..e96b2f117 100644 --- a/plugins/inputs/modbus/modbus.go +++ b/plugins/inputs/modbus/modbus.go @@ -468,27 +468,26 @@ func convertDataType(t fieldContainer, bytes []byte) interface{} { switch t.DataType { case "UINT16": e16 := convertEndianness16(t.ByteOrder, bytes) - f16 := format16(t.DataType, e16).(uint16) - return scaleUint16(t.Scale, f16) + return scaleUint16(t.Scale, e16) case "INT16": e16 := convertEndianness16(t.ByteOrder, bytes) - f16 := format16(t.DataType, e16).(int16) + f16 := int16(e16) return scaleInt16(t.Scale, f16) case "UINT32": e32 := convertEndianness32(t.ByteOrder, bytes) - f32 := format32(t.DataType, e32).(uint32) - return scaleUint32(t.Scale, f32) + return scaleUint32(t.Scale, e32) case "INT32": e32 := convertEndianness32(t.ByteOrder, bytes) - return format32(t.DataType, e32) + f32 := int32(e32) + return scaleInt32(t.Scale, f32) case "FLOAT32-IEEE": e32 := convertEndianness32(t.ByteOrder, bytes) - return format32(t.DataType, e32) + f32 := math.Float32frombits(e32) + return scaleFloat32(t.Scale, f32) case "FLOAT32": if len(bytes) == 2 { e16 := convertEndianness16(t.ByteOrder, bytes) - f16 := format16(t.DataType, e16).(uint16) - return scale16toFloat32(t.Scale, f16) + return scale16toFloat32(t.Scale, e16) } else { e32 := convertEndianness32(t.ByteOrder, bytes) return scale32toFloat32(t.Scale, e32) @@ -568,6 +567,14 @@ func scaleUint32(s float64, v uint32) uint32 { return uint32(float64(v) * float64(s)) } +func scaleInt32(s float64, v int32) int32 { + return int32(float64(v) * float64(s)) +} + +func scaleFloat32(s float64, v float32) float32 { + return float32(float64(v) * s) +} + // Gather implements the telegraf plugin interface method for data accumulation func (m *Modbus) Gather(acc telegraf.Accumulator) error { if !m.isConnected { diff --git a/plugins/inputs/modbus/modbus_test.go b/plugins/inputs/modbus/modbus_test.go index 3317067a8..e346ece17 100644 --- a/plugins/inputs/modbus/modbus_test.go +++ b/plugins/inputs/modbus/modbus_test.go @@ -239,6 +239,16 @@ func TestHoldingRegisters(t *testing.T) { write: []byte{0xAB, 0xCD}, read: int16(-12885), }, + { + name: "register50_register51_abcd_int32_scaled", + address: []uint16{50, 51}, + quantity: 2, + byteOrder: "ABCD", + dataType: "INT32", + scale: 10, + write: []byte{0x00, 0x00, 0xAB, 0xCD}, + read: int32(439810), + }, { name: "register50_register51_abcd_int32", address: []uint16{50, 51}, @@ -329,6 +339,16 @@ func TestHoldingRegisters(t *testing.T) { write: []byte{0xAA, 0xBB, 0xCC, 0xDD}, read: float32(-3.3360025e-13), }, + { + name: "register130_register131_abcd_float32_ieee_scaled", + address: []uint16{130, 131}, + quantity: 2, + byteOrder: "ABCD", + dataType: "FLOAT32-IEEE", + scale: 10, + write: []byte{0xAA, 0xBB, 0xCC, 0xDD}, + read: float32(-3.3360025e-12), + }, } serv := mbserver.NewServer()