Fix float conversion and startup connection issue in modbus input (#7002)

This commit is contained in:
Antonio Garcia 2020-02-10 18:54:33 -06:00 committed by GitHub
parent c681eb3524
commit 9d97ed22e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 40 deletions

View File

@ -40,7 +40,6 @@ type Modbus struct {
type register struct { type register struct {
Type string Type string
RegistersRange []registerRange RegistersRange []registerRange
ReadValue func(uint16, uint16) ([]byte, error)
Fields []fieldContainer Fields []fieldContainer
} }
@ -48,7 +47,7 @@ type fieldContainer struct {
Name string `toml:"name"` Name string `toml:"name"`
ByteOrder string `toml:"byte_order"` ByteOrder string `toml:"byte_order"`
DataType string `toml:"data_type"` DataType string `toml:"data_type"`
Scale float32 `toml:"scale"` Scale float64 `toml:"scale"`
Address []uint16 `toml:"address"` Address []uint16 `toml:"address"`
value interface{} value interface{}
} }
@ -155,13 +154,7 @@ func (m *Modbus) Init() error {
return fmt.Errorf("device name is empty") return fmt.Errorf("device name is empty")
} }
err := connect(m) err := m.InitRegister(m.DiscreteInputs, cDiscreteInputs)
if err != nil {
m.isConnected = false
return err
}
err = m.InitRegister(m.DiscreteInputs, cDiscreteInputs)
if err != nil { if err != nil {
return err return err
} }
@ -224,21 +217,7 @@ func (m *Modbus) InitRegister(fields []fieldContainer, name string) error {
} }
} }
var fn func(uint16, uint16) ([]byte, error) m.registers = append(m.registers, register{name, registersRange, fields})
if name == cDiscreteInputs {
fn = m.client.ReadDiscreteInputs
} else if name == cCoils {
fn = m.client.ReadCoils
} else if name == cInputRegisters {
fn = m.client.ReadInputRegisters
} else if name == cHoldingRegisters {
fn = m.client.ReadHoldingRegisters
} else {
return fmt.Errorf("not Valid function")
}
m.registers = append(m.registers, register{name, registersRange, fn, fields})
return nil return nil
} }
@ -306,6 +285,31 @@ func connect(m *Modbus) error {
} }
} }
func disconnect(m *Modbus) error {
u, err := url.Parse(m.Controller)
if err != nil {
return err
}
switch u.Scheme {
case "tcp":
m.tcpHandler.Close()
return nil
case "file":
if m.TransmissionMode == "RTU" {
m.rtuHandler.Close()
return nil
} else if m.TransmissionMode == "ASCII" {
m.asciiHandler.Close()
return nil
} else {
return fmt.Errorf("invalid protocol '%s' - '%s' ", u.Scheme, m.TransmissionMode)
}
default:
return fmt.Errorf("invalid controller")
}
}
func validateFieldContainers(t []fieldContainer, n string) error { func validateFieldContainers(t []fieldContainer, n string) error {
nameEncountered := map[string]bool{} nameEncountered := map[string]bool{}
for _, item := range t { for _, item := range t {
@ -379,13 +383,27 @@ func removeDuplicates(elements []uint16) []uint16 {
return result return result
} }
func readRegisterValues(m *Modbus, rt string, rr registerRange) ([]byte, error) {
if rt == cDiscreteInputs {
return m.client.ReadDiscreteInputs(uint16(rr.address), uint16(rr.length))
} else if rt == cCoils {
return m.client.ReadCoils(uint16(rr.address), uint16(rr.length))
} else if rt == cInputRegisters {
return m.client.ReadInputRegisters(uint16(rr.address), uint16(rr.length))
} else if rt == cHoldingRegisters {
return m.client.ReadHoldingRegisters(uint16(rr.address), uint16(rr.length))
} else {
return []byte{}, fmt.Errorf("not Valid function")
}
}
func (m *Modbus) getFields() error { func (m *Modbus) getFields() error {
for _, register := range m.registers { for _, register := range m.registers {
rawValues := make(map[uint16][]byte) rawValues := make(map[uint16][]byte)
bitRawValues := make(map[uint16]uint16) bitRawValues := make(map[uint16]uint16)
for _, rr := range register.RegistersRange { for _, rr := range register.RegistersRange {
address := rr.address address := rr.address
readValues, err := register.ReadValue(uint16(rr.address), uint16(rr.length)) readValues, err := readRegisterValues(m, register.Type, rr)
if err != nil { if err != nil {
return err return err
} }
@ -530,23 +548,23 @@ func format32(f string, r uint32) interface{} {
} }
} }
func scale16toFloat32(s float32, v uint16) float32 { func scale16toFloat32(s float64, v uint16) float64 {
return float32(v) * s return float64(v) * s
} }
func scale32toFloat32(s float32, v uint32) float32 { func scale32toFloat32(s float64, v uint32) float64 {
return float32(v) * s return float64(float64(v) * float64(s))
} }
func scaleInt16(s float32, v int16) int16 { func scaleInt16(s float64, v int16) int16 {
return int16(float32(v) * s) return int16(float64(v) * s)
} }
func scaleUint16(s float32, v uint16) uint16 { func scaleUint16(s float64, v uint16) uint16 {
return uint16(float32(v) * s) return uint16(float64(v) * s)
} }
func scaleUint32(s float32, v uint32) uint32 { func scaleUint32(s float64, v uint32) uint32 {
return uint32(float64(v) * float64(s)) return uint32(float64(v) * float64(s))
} }
@ -562,6 +580,7 @@ func (m *Modbus) Gather(acc telegraf.Accumulator) error {
err := m.getFields() err := m.getFields()
if err != nil { if err != nil {
disconnect(m)
m.isConnected = false m.isConnected = false
return err return err
} }

View File

@ -125,7 +125,7 @@ func TestHoldingRegisters(t *testing.T) {
quantity uint16 quantity uint16
byteOrder string byteOrder string
dataType string dataType string
scale float32 scale float64
write []byte write []byte
read interface{} read interface{}
}{ }{
@ -137,7 +137,7 @@ func TestHoldingRegisters(t *testing.T) {
dataType: "FLOAT32", dataType: "FLOAT32",
scale: 0.1, scale: 0.1,
write: []byte{0x08, 0x98}, write: []byte{0x08, 0x98},
read: float32(220), read: float64(220),
}, },
{ {
name: "register0_register1_ab_float32", name: "register0_register1_ab_float32",
@ -147,7 +147,7 @@ func TestHoldingRegisters(t *testing.T) {
dataType: "FLOAT32", dataType: "FLOAT32",
scale: 0.001, scale: 0.001,
write: []byte{0x00, 0x00, 0x03, 0xE8}, write: []byte{0x00, 0x00, 0x03, 0xE8},
read: float32(1), read: float64(1),
}, },
{ {
name: "register1_register2_abcd_float32", name: "register1_register2_abcd_float32",
@ -157,7 +157,7 @@ func TestHoldingRegisters(t *testing.T) {
dataType: "FLOAT32", dataType: "FLOAT32",
scale: 0.1, scale: 0.1,
write: []byte{0x00, 0x00, 0x08, 0x98}, write: []byte{0x00, 0x00, 0x08, 0x98},
read: float32(220), read: float64(220),
}, },
{ {
name: "register3_register4_abcd_float32", name: "register3_register4_abcd_float32",
@ -167,7 +167,7 @@ func TestHoldingRegisters(t *testing.T) {
dataType: "FLOAT32", dataType: "FLOAT32",
scale: 0.1, scale: 0.1,
write: []byte{0x00, 0x00, 0x08, 0x98}, write: []byte{0x00, 0x00, 0x08, 0x98},
read: float32(220), read: float64(220),
}, },
{ {
name: "register7_ab_float32", name: "register7_ab_float32",
@ -177,7 +177,7 @@ func TestHoldingRegisters(t *testing.T) {
dataType: "FLOAT32", dataType: "FLOAT32",
scale: 0.1, scale: 0.1,
write: []byte{0x01, 0xF4}, write: []byte{0x01, 0xF4},
read: float32(50), read: float64(50),
}, },
{ {
name: "register10_ab_uint16", name: "register10_ab_uint16",