Skip to content

Commit

Permalink
Add possibility to specify measurement per register (influxdata#7231)
Browse files Browse the repository at this point in the history
  • Loading branch information
srebhan authored and Mathieu Lecarme committed Apr 17, 2020
1 parent 2b60f02 commit f64118e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 30 deletions.
25 changes: 13 additions & 12 deletions plugins/inputs/modbus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,33 @@ The Modbus plugin collects Discrete Inputs, Coils, Input Registers and Holding R
##
## Device name
name = "Device"

## Slave ID - addresses a MODBUS device on the bus
## Range: 0 - 255 [0 = broadcast; 248 - 255 = reserved]
slave_id = 1

## Timeout for each request
timeout = "1s"

# TCP - connect via Modbus/TCP
controller = "tcp://localhost:502"

# Serial (RS485; RS232)
#controller = "file:///dev/ttyUSB0"
#baud_rate = 9600
#data_bits = 8
#parity = "N"
#stop_bits = 1
#transmission_mode = "RTU"


## Measurements
##

## Digital Variables, Discrete Inputs and Coils
## name - the variable name
## address - variable address

discrete_inputs = [
{ name = "Start", address = [0]},
{ name = "Stop", address = [1]},
Expand All @@ -49,19 +49,20 @@ The Modbus plugin collects Discrete Inputs, Coils, Input Registers and Holding R
{ name = "Motor1-Run", address = [0]},
{ name = "Motor1-Jog", address = [1]},
{ name = "Motor1-Stop", address = [2]},
]
]

## Analog Variables, Input Registers and Holding Registers
## measurement - the (optional) measurement name, defaults to "modbus"
## name - the variable name
## byte_order - the ordering of bytes
## byte_order - the ordering of bytes
## |---AB, ABCD - Big Endian
## |---BA, DCBA - Little Endian
## |---BADC - Mid-Big Endian
## |---CDAB - Mid-Little Endian
## data_type - INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT32, FLOAT32-IEEE (the IEEE 754 binary representation)
## scale - the final numeric variable representation
## address - variable address

holding_registers = [
{ name = "PowerFactor", byte_order = "AB", data_type = "FLOAT32", scale=0.01, address = [8]},
{ name = "Voltage", byte_order = "AB", data_type = "FLOAT32", scale=0.1, address = [0]},
Expand Down
53 changes: 35 additions & 18 deletions plugins/inputs/modbus/modbus.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import (
"net"
"net/url"
"sort"
"time"

mb "github.com/goburrow/modbus"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/metric"
"github.com/influxdata/telegraf/plugins/inputs"
)

Expand Down Expand Up @@ -44,12 +46,13 @@ type register struct {
}

type fieldContainer struct {
Name string `toml:"name"`
ByteOrder string `toml:"byte_order"`
DataType string `toml:"data_type"`
Scale float64 `toml:"scale"`
Address []uint16 `toml:"address"`
value interface{}
Measurement string `toml:"measurement"`
Name string `toml:"name"`
ByteOrder string `toml:"byte_order"`
DataType string `toml:"data_type"`
Scale float64 `toml:"scale"`
Address []uint16 `toml:"address"`
value interface{}
}

type registerRange struct {
Expand Down Expand Up @@ -97,14 +100,15 @@ const sampleConfig = `
##
## Digital Variables, Discrete Inputs and Coils
## name - the variable name
## address - variable address
## measurement - the (optional) measurement name, defaults to "modbus"
## name - the variable name
## address - variable address
discrete_inputs = [
{ name = "start", address = [0]},
{ name = "stop", address = [1]},
{ name = "reset", address = [2]},
{ name = "emergency_stop", address = [3]},
{ name = "emergency_stop", address = [3]},
]
coils = [
{ name = "motor1_run", address = [0]},
Expand All @@ -113,8 +117,9 @@ const sampleConfig = `
]
## Analog Variables, Input Registers and Holding Registers
## name - the variable name
## byte_order - the ordering of bytes
## measurement - the (optional) measurement name, defaults to "modbus"
## name - the variable name
## byte_order - the ordering of bytes
## |---AB, ABCD - Big Endian
## |---BA, DCBA - Little Endian
## |---BADC - Mid-Big Endian
Expand All @@ -134,7 +139,7 @@ const sampleConfig = `
input_registers = [
{ name = "tank_level", byte_order = "AB", data_type = "INT16", scale=1.0, address = [0]},
{ name = "tank_ph", byte_order = "AB", data_type = "INT16", scale=1.0, address = [1]},
{ name = "pump1_speed", byte_order = "ABCD", data_type = "INT32", scale=1.0, address = [3,4]},
{ name = "pump1_speed", byte_order = "ABCD", data_type = "INT32", scale=1.0, address = [3,4]},
]
`

Expand Down Expand Up @@ -319,10 +324,11 @@ func validateFieldContainers(t []fieldContainer, n string) error {
}

//search name duplicate
if nameEncountered[item.Name] {
return fmt.Errorf("name '%s' is duplicated in '%s' - '%s'", item.Name, n, item.Name)
canonical_name := item.Measurement + "." + item.Name
if nameEncountered[canonical_name] {
return fmt.Errorf("name '%s' is duplicated in measurement '%s' '%s' - '%s'", item.Name, item.Measurement, n, item.Name)
} else {
nameEncountered[item.Name] = true
nameEncountered[canonical_name] = true
}

if n == cInputRegisters || n == cHoldingRegisters {
Expand Down Expand Up @@ -635,25 +641,36 @@ func (m *Modbus) Gather(acc telegraf.Accumulator) error {
}
}

timestamp := time.Now()
err := m.getFields()
if err != nil {
disconnect(m)
m.isConnected = false
return err
}

grouper := metric.NewSeriesGrouper()
for _, reg := range m.registers {
fields := make(map[string]interface{})
tags := map[string]string{
"name": m.Name,
"type": reg.Type,
}

for _, field := range reg.Fields {
fields[field.Name] = field.value
// In case no measurement was specified we use "modbus" as default
measurement := "modbus"
if field.Measurement != "" {
measurement = field.Measurement
}

// Group the data by series
grouper.Add(measurement, tags, timestamp, field.Name, field.value)
}

acc.AddFields("modbus", fields, tags)
// Add the metrics grouped by series to the accumulator
for _, metric := range grouper.Metrics() {
acc.AddMetric(metric)
}
}

return nil
Expand Down

0 comments on commit f64118e

Please sign in to comment.