diff --git a/plugins/inputs/modbus/README.md b/plugins/inputs/modbus/README.md index 5112b8d28..1bc4ef086 100644 --- a/plugins/inputs/modbus/README.md +++ b/plugins/inputs/modbus/README.md @@ -50,10 +50,13 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. # parity = "N" # stop_bits = 1 - ## For Modbus over TCP you can choose between "TCP", "RTUoverTCP" and - ## "ASCIIoverTCP". The default behaviour is "TCP" for ModbusTCP controllers. + ## Transmission mode for Modbus packets depending on the controller type. + ## For Modbus over TCP you can choose between "TCP" , "RTUoverTCP" and + ## "ASCIIoverTCP". ## For Serial controllers you can choose between "RTU" and "ASCII". - # transmission_mode = "RTU" + ## By default this is set to "auto" selecting "TCP" for ModbusTCP connections + ## and "RTU" for serial connections. + # transmission_mode = "auto" ## Trace the connection to the modbus device as debug messages ## Note: You have to enable telegraf's debug mode to see those messages! diff --git a/plugins/inputs/modbus/modbus.go b/plugins/inputs/modbus/modbus.go index e1d64826e..61b4f4b38 100644 --- a/plugins/inputs/modbus/modbus.go +++ b/plugins/inputs/modbus/modbus.go @@ -235,6 +235,13 @@ func (m *Modbus) initClient() error { return err } switch m.TransmissionMode { + case "", "auto", "TCP": + handler := mb.NewTCPClientHandler(host + ":" + port) + handler.Timeout = time.Duration(m.Timeout) + if m.DebugConnection { + handler.Logger = m + } + m.handler = handler case "RTUoverTCP": handler := mb.NewRTUOverTCPClientHandler(host + ":" + port) handler.Timeout = time.Duration(m.Timeout) @@ -250,12 +257,7 @@ func (m *Modbus) initClient() error { } m.handler = handler default: - handler := mb.NewTCPClientHandler(host + ":" + port) - handler.Timeout = time.Duration(m.Timeout) - if m.DebugConnection { - handler.Logger = m - } - m.handler = handler + return fmt.Errorf("invalid transmission mode %q for %q", m.TransmissionMode, u.Scheme) } case "", "file": path := filepath.Join(u.Host, u.Path) @@ -263,7 +265,7 @@ func (m *Modbus) initClient() error { return fmt.Errorf("invalid path for controller %q", m.Controller) } switch m.TransmissionMode { - case "RTU": + case "", "auto", "RTU": handler := mb.NewRTUClientHandler(path) handler.Timeout = time.Duration(m.Timeout) handler.BaudRate = m.BaudRate @@ -286,7 +288,7 @@ func (m *Modbus) initClient() error { } m.handler = handler default: - return fmt.Errorf("invalid protocol '%s' - '%s' ", u.Scheme, m.TransmissionMode) + return fmt.Errorf("invalid transmission mode %q for %q", m.TransmissionMode, u.Scheme) } default: return fmt.Errorf("invalid controller %q", m.Controller) diff --git a/plugins/inputs/modbus/modbus_test.go b/plugins/inputs/modbus/modbus_test.go index 29e8bd45c..4fe5c6f96 100644 --- a/plugins/inputs/modbus/modbus_test.go +++ b/plugins/inputs/modbus/modbus_test.go @@ -25,6 +25,7 @@ func TestControllers(t *testing.T) { var tests = []struct { name string controller string + mode string errmsg string }{ { @@ -32,9 +33,41 @@ func TestControllers(t *testing.T) { controller: "tcp://localhost:502", }, { - name: "invalid TCP host", + name: "TCP mode auto", + controller: "tcp://localhost:502", + mode: "auto", + }, + { + name: "TCP mode TCP", + controller: "tcp://localhost:502", + mode: "TCP", + }, + { + name: "TCP mode RTUoverTCP", + controller: "tcp://localhost:502", + mode: "RTUoverTCP", + }, + { + name: "TCP mode ASCIIoverTCP", + controller: "tcp://localhost:502", + mode: "ASCIIoverTCP", + }, + { + name: "TCP invalid host", controller: "tcp://localhost", - errmsg: "initializing client failed: address localhost: missing port in address", + errmsg: "address localhost: missing port in address", + }, + { + name: "TCP invalid mode RTU", + controller: "tcp://localhost:502", + mode: "RTU", + errmsg: "invalid transmission mode", + }, + { + name: "TCP invalid mode ASCII", + controller: "tcp://localhost:502", + mode: "ASCII", + errmsg: "invalid transmission mode", }, { name: "absolute file path", @@ -56,20 +89,41 @@ func TestControllers(t *testing.T) { name: "Windows COM-port file path", controller: "file://com2", }, + { + name: "serial mode auto", + controller: "file:///dev/ttyUSB0", + mode: "auto", + }, + { + name: "serial mode RTU", + controller: "file:///dev/ttyUSB0", + mode: "RTU", + }, + { + name: "serial mode ASCII", + controller: "file:///dev/ttyUSB0", + mode: "ASCII", + }, { name: "empty file path", controller: "file://", - errmsg: "initializing client failed: invalid path for controller", + errmsg: "invalid path for controller", }, { name: "empty controller", controller: "", - errmsg: "initializing client failed: invalid path for controller", + errmsg: "invalid path for controller", }, { name: "invalid scheme", controller: "foo://bar", - errmsg: "initializing client failed: invalid controller", + errmsg: "invalid controller", + }, + { + name: "serial invalid mode TCP", + controller: "file:///dev/ttyUSB0", + mode: "TCP", + errmsg: "invalid transmission mode", }, } @@ -78,7 +132,7 @@ func TestControllers(t *testing.T) { plugin := Modbus{ Name: "dummy", Controller: tt.controller, - TransmissionMode: "RTU", + TransmissionMode: tt.mode, Log: testutil.Logger{}, } err := plugin.Init() diff --git a/plugins/inputs/modbus/sample_general_begin.conf b/plugins/inputs/modbus/sample_general_begin.conf index 54bc7e7d9..e88109f91 100644 --- a/plugins/inputs/modbus/sample_general_begin.conf +++ b/plugins/inputs/modbus/sample_general_begin.conf @@ -33,10 +33,13 @@ # parity = "N" # stop_bits = 1 - ## For Modbus over TCP you can choose between "TCP", "RTUoverTCP" and - ## "ASCIIoverTCP". The default behaviour is "TCP" for ModbusTCP controllers. + ## Transmission mode for Modbus packets depending on the controller type. + ## For Modbus over TCP you can choose between "TCP" , "RTUoverTCP" and + ## "ASCIIoverTCP". ## For Serial controllers you can choose between "RTU" and "ASCII". - # transmission_mode = "RTU" + ## By default this is set to "auto" selecting "TCP" for ModbusTCP connections + ## and "RTU" for serial connections. + # transmission_mode = "auto" ## Trace the connection to the modbus device as debug messages ## Note: You have to enable telegraf's debug mode to see those messages!