文档文档

Modbus 输入插件

此插件使用例如 Modbus TCP 或串行接口(带 Modbus RTU 或 Modbus ASCII)从 Modbus 寄存器收集数据。

引入于: Telegraf v1.14.0 标签: iot 操作系统支持: all

全局配置选项

插件支持其他全局和插件配置设置,用于修改指标、标签和字段,创建别名以及配置插件顺序等任务。更多详情请参阅 CONFIGURATION.md

配置

# Retrieve data from MODBUS slave devices
[[inputs.modbus]]
  ## Connection Configuration
  ##
  ## The plugin supports connections to PLCs via MODBUS/TCP, RTU over TCP, ASCII over TCP or
  ## via serial line communication in binary (RTU) or readable (ASCII) encoding
  ##
  ## 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"

  ## Maximum number of retries and the time to wait between retries
  ## when a slave-device is busy.
  # busy_retries = 0
  # busy_retries_wait = "100ms"

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

  ## Serial (RS485; RS232)
  ## For RS485 specific setting check the end of the configuration.
  ## For unix-like operating systems use:
  # controller = "file:///dev/ttyUSB0"
  ## For Windows operating systems use:
  # controller = "COM1"
  # baud_rate = 9600
  # data_bits = 8
  # parity = "N"
  # stop_bits = 1

  ## 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".
  ## 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
  # log_level = "trace"

  ## Define the configuration schema
  ##  |---register -- define fields per register type in the original style (only supports one slave ID)
  ##  |---request  -- define fields on a requests base
  ##  |---metric   -- define fields on a metric base
  configuration_type = "register"

  ## Exclude the register type tag
  ## Please note, this will also influence the grouping of metrics as you won't
  ## see one metric per register type anymore!
  # exclude_register_type_tag = false

  ## --- "register" configuration style ---

  ## Measurements
  ##

  ## Digital Variables, Discrete Inputs and Coils
  ## measurement - the (optional) measurement name, defaults to "modbus"
  ## name        - the variable name
  ## data_type   - the (optional) output type, can be BOOL or UINT16 (default)
  ## address     - variable address

  discrete_inputs = [
    { name = "start",          address = [0]},
    { name = "stop",           address = [1]},
    { name = "reset",          address = [2]},
    { name = "emergency_stop", address = [3]},
  ]
  coils = [
    { 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
  ##  |---AB, ABCD   - Big Endian
  ##  |---BA, DCBA   - Little Endian
  ##  |---BADC       - Mid-Big Endian
  ##  |---CDAB       - Mid-Little Endian
  ## data_type   - BIT (single bit of a register)
  ##               INT8L, INT8H, UINT8L, UINT8H (low and high byte variants)
  ##               INT16, UINT16, INT32, UINT32, INT64, UINT64,
  ##               FLOAT16-IEEE, FLOAT32-IEEE, FLOAT64-IEEE (IEEE 754 binary representation)
  ##               FIXED, UFIXED (fixed-point representation on input)
  ##               STRING (byte-sequence converted to string)
  ## bit         - (optional) bit of the register, ONLY valid for BIT type
  ## scale       - the final numeric variable representation
  ## address     - variable address

  holding_registers = [
    { name = "power_factor", byte_order = "AB",   data_type = "FIXED", scale=0.01,  address = [8]},
    { name = "voltage",      byte_order = "AB",   data_type = "FIXED", scale=0.1,   address = [0]},
    { name = "energy",       byte_order = "ABCD", data_type = "FIXED", scale=0.001, address = [5,6]},
    { name = "current",      byte_order = "ABCD", data_type = "FIXED", scale=0.001, address = [1,2]},
    { name = "frequency",    byte_order = "AB",   data_type = "UFIXED", scale=0.1,  address = [7]},
    { name = "power",        byte_order = "ABCD", data_type = "UFIXED", scale=0.1,  address = [3,4]},
    { name = "firmware",     byte_order = "AB",   data_type = "STRING", address = [5, 6, 7, 8, 9, 10, 11, 12]},
  ]
  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]},
  ]

  ## --- "request" configuration style ---

  ## Per request definition
  ##

  ## Define a request sent to the device
  ## Multiple of those requests can be defined. Data will be collated into metrics at the end of data collection.
  [[inputs.modbus.request]]
    ## ID of the modbus slave device to query.
    ## If you need to query multiple slave-devices, create several "request" definitions.
    slave_id = 1

    ## Byte order of the data.
    ##  |---ABCD -- Big Endian (Motorola)
    ##  |---DCBA -- Little Endian (Intel)
    ##  |---BADC -- Big Endian with byte swap
    ##  |---CDAB -- Little Endian with byte swap
    byte_order = "ABCD"

    ## Type of the register for the request
    ## Can be "coil", "discrete", "holding" or "input"
    register = "coil"

    ## Name of the measurement.
    ## Can be overridden by the individual field definitions. Defaults to "modbus"
    # measurement = "modbus"

    ## Request optimization algorithm.
    ##  |---none       -- Do not perform any optimization and use the given layout(default)
    ##  |---shrink     -- Shrink requests to actually requested fields
    ##  |                 by stripping leading and trailing omits
    ##  |---rearrange  -- Rearrange request boundaries within consecutive address ranges
    ##  |                 to reduce the number of requested registers by keeping
    ##  |                 the number of requests.
    ##  |---max_insert -- Rearrange request keeping the number of extra fields below the value
    ##                    provided in "optimization_max_register_fill". It is not necessary to define 'omitted'
    ##                    fields as the optimisation will add such field only where needed.
    # optimization = "none"

    ## Maximum number register the optimizer is allowed to insert between two fields to
    ## save requests.
    ## This option is only used for the 'max_insert' optimization strategy.
    ## NOTE: All omitted fields are ignored, so this option denotes the effective hole
    ## size to fill.
    # optimization_max_register_fill = 50

    ## Field definitions
    ## Analog Variables, Input Registers and Holding Registers
    ## address        - address of the register to query. For coil and discrete inputs this is the bit address.
    ## name *1        - field name
    ## type *1,2      - type of the modbus field, can be
    ##                  BIT (single bit of a register)
    ##                  INT8L, INT8H, UINT8L, UINT8H (low and high byte variants)
    ##                  INT16, UINT16, INT32, UINT32, INT64, UINT64 and
    ##                  FLOAT16, FLOAT32, FLOAT64 (IEEE 754 binary representation)
    ##                  STRING (byte-sequence converted to string)
    ## length *1,2    - (optional) number of registers, ONLY valid for STRING type
    ## bit *1,2       - (optional) bit of the register, ONLY valid for BIT type
    ## scale *1,2,4   - (optional) factor to scale the variable with
    ## output *1,3,4  - (optional) type of resulting field, can be INT64, UINT64 or FLOAT64.
    ##                  Defaults to FLOAT64 for numeric fields if "scale" is provided.
    ##                  Otherwise the input "type" class is used (e.g. INT* -> INT64).
    ## measurement *1 - (optional) measurement name, defaults to the setting of the request
    ## omit           - (optional) omit this field. Useful to leave out single values when querying many registers
    ##                  with a single request. Defaults to "false".
    ##
    ## *1: These fields are ignored if field is omitted ("omit"=true)
    ## *2: These fields are ignored for both "coil" and "discrete"-input type of registers.
    ## *3: This field can only be "UINT16" or "BOOL" if specified for both "coil"
    ##     and "discrete"-input type of registers. By default the fields are
    ##     output as zero or one in UINT16 format unless "BOOL" is used.
    ## *4: These fields cannot be used with "STRING"-type fields.

    ## Coil / discrete input example
    fields = [
      { address=0, name="motor1_run" },
      { address=1, name="jog", measurement="motor" },
      { address=2, name="motor1_stop", omit=true },
      { address=3, name="motor1_overheating", output="BOOL" },
      { address=4, name="firmware", type="STRING", length=8 },
    ]

    [inputs.modbus.request.tags]
      machine = "impresser"
      location = "main building"

  [[inputs.modbus.request]]
    ## Holding example
    ## All of those examples will result in FLOAT64 field outputs
    slave_id = 1
    byte_order = "DCBA"
    register = "holding"
    fields = [
      { address=0, name="voltage",      type="INT16",   scale=0.1   },
      { address=1, name="current",      type="INT32",   scale=0.001 },
      { address=3, name="power",        type="UINT32",  omit=true   },
      { address=5, name="energy",       type="FLOAT32", scale=0.001, measurement="W" },
      { address=7, name="frequency",    type="UINT32",  scale=0.1   },
      { address=8, name="power_factor", type="INT64",   scale=0.01  },
    ]

    [inputs.modbus.request.tags]
      machine = "impresser"
      location = "main building"

  [[inputs.modbus.request]]
    ## Input example with type conversions
    slave_id = 1
    byte_order = "ABCD"
    register = "input"
    fields = [
      { address=0, name="rpm",         type="INT16"                   },  # will result in INT64 field
      { address=1, name="temperature", type="INT16", scale=0.1        },  # will result in FLOAT64 field
      { address=2, name="force",       type="INT32", output="FLOAT64" },  # will result in FLOAT64 field
      { address=4, name="hours",       type="UINT32"                  },  # will result in UIN64 field
    ]

    [inputs.modbus.request.tags]
      machine = "impresser"
      location = "main building"

  ## --- "metric" configuration style ---

  ## Per metric definition
  ##

  ## Request optimization algorithm across metrics
  ##  |---none       -- Do not perform any optimization and just group requests
  ##  |                 within metrics (default)
  ##  |---max_insert -- Collate registers across all defined metrics and fill in
  ##                    holes to optimize the number of requests.
  # optimization = "none"

  ## Maximum number of registers the optimizer is allowed to insert between
  ## non-consecutive registers to save requests.
  ## This option is only used for the 'max_insert' optimization strategy and
  ## effectively denotes the hole size between registers to fill.
  # optimization_max_register_fill = 50

  ## Define a metric produced by the requests to the device
  ## Multiple of those metrics can be defined. The referenced registers will
  ## be collated into requests send to the device
  [[inputs.modbus.metric]]
    ## ID of the modbus slave device to query
    ## If you need to query multiple slave-devices, create several "metric" definitions.
    slave_id = 1

    ## Byte order of the data
    ##  |---ABCD -- Big Endian (Motorola)
    ##  |---DCBA -- Little Endian (Intel)
    ##  |---BADC -- Big Endian with byte swap
    ##  |---CDAB -- Little Endian with byte swap
    # byte_order = "ABCD"

    ## Name of the measurement
    # measurement = "modbus"

    ## Field definitions
    ## register    - type of the modbus register, can be "coil", "discrete",
    ##               "holding" or "input". Defaults to "holding".
    ## address     - address of the register to query. For coil and discrete inputs this is the bit address.
    ## name        - field name
    ## type *1     - type of the modbus field, can be
    ##                 BIT (single bit of a register)
    ##                 INT8L, INT8H, UINT8L, UINT8H (low and high byte variants)
    ##                 INT16, UINT16, INT32, UINT32, INT64, UINT64 and
    ##                 FLOAT16, FLOAT32, FLOAT64 (IEEE 754 binary representation)
    ##                 STRING (byte-sequence converted to string)
    ## length *1   - (optional) number of registers, ONLY valid for STRING type
    ## bit *1,2    - (optional) bit of the register, ONLY valid for BIT type
    ## scale *1,3  - (optional) factor to scale the variable with
    ## output *2,3 - (optional) type of resulting field, can be INT64, UINT64 or FLOAT64. Defaults to FLOAT64 if
    ##               "scale" is provided and to the input "type" class otherwise (INT* -> INT64, etc).
    ##
    ## *1: These fields are ignored for both "coil" and "discrete"-input type of registers.
    ## *2: This field can only be "UINT16" or "BOOL" if specified for both "coil"
    ##     and "discrete"-input type of registers. By default the fields are
    ##     output as zero or one in UINT16 format unless "BOOL" is used.
    ## *3: These fields cannot be used with "STRING"-type fields.
    fields = [
      { register="coil",    address=0, name="door_open"},
      { register="coil",    address=1, name="status_ok"},
      { register="holding", address=0, name="voltage",      type="INT16"   },
      { address=1, name="current",      type="INT32",   scale=0.001 },
      { address=5, name="energy",       type="FLOAT32", scale=0.001 },
      { address=7, name="frequency",    type="UINT32",  scale=0.1   },
      { address=8, name="power_factor", type="INT64",   scale=0.01  },
      { address=9, name="firmware",     type="STRING",  length=8    },
    ]

    ## Tags assigned to the metric
    # [inputs.modbus.metric.tags]
    #   machine = "impresser"
    #   location = "main building"

  ## RS485 specific settings. Only take effect for serial controllers.
  ## Note: This has to be at the end of the modbus configuration due to
  ## TOML constraints.
  # [inputs.modbus.rs485]
    ## Delay RTS prior to sending
    # delay_rts_before_send = "0ms"
    ## Delay RTS after to sending
    # delay_rts_after_send = "0ms"
    ## Pull RTS line to high during sending
    # rts_high_during_send = false
    ## Pull RTS line to high after sending
    # rts_high_after_send = false
    ## Enabling receiving (Rx) during transmission (Tx)
    # rx_during_tx = false

  ## Enable workarounds required by some devices to work correctly
  # [inputs.modbus.workarounds]
    ## Pause after connect delays the first request by the specified time.
    ## This might be necessary for (slow) devices.
    # pause_after_connect = "0ms"

    ## Pause between read requests sent to the device.
    ## This might be necessary for (slow) serial devices.
    # pause_between_requests = "0ms"

    ## Close the connection after every gather cycle.
    ## Usually the plugin closes the connection after a certain idle-timeout,
    ## however, if you query a device with limited simultaneous connectivity
    ## (e.g. serial devices) from multiple instances you might want to only
    ## stay connected during gather and disconnect afterwards.
    # close_connection_after_gather = false

    ## Force the plugin to read each field in a separate request.
    ## This might be necessary for devices not conforming to the spec,
    ## see https://github.com/influxdata/telegraf/issues/12071.
    # one_request_per_field = false

    ## Enforce the starting address to be zero for the first request on
    ## coil registers. This is necessary for some devices see
    ## https://github.com/influxdata/telegraf/issues/8905
    # read_coils_starting_at_zero = false

    ## String byte-location in registers AFTER byte-order conversion
    ## Some device (e.g. EM340) place the string byte in only the upper or
    ## lower byte location of a register see
    ## https://github.com/influxdata/telegraf/issues/14748
    ## Available settings:
    ##   lower -- use only lower byte of the register (00XX 00XX 00XX 00XX)
    ##   upper -- use only upper byte of the register (XX00 XX00 XX00 XX00)
    ## By default both bytes of the register are used (XXXX XXXX).
    # string_register_location = ""

注意

您可以通过启用 debug_connection 来调试 Modbus 连接问题。要查看这些调试消息,Telegraf 必须使用调试模式启动(使用 --debug 选项)。请注意,连接跟踪会产生大量消息,**不**应在生产环境中使用。

请谨慎使用 pause_after_connect / pause_between_requests。确保总采集时间(包括暂停时间)不超过配置的采集间隔。请注意,发送多个请求时,暂停时间会累加!

配置风格

modbus 插件支持多种配置风格,可以通过 configuration_type 设置进行配置。下面将详细介绍不同的风格。请注意,风格不能混用。只有属于已配置 configuration_type 的设置才用于构建 modbus 请求和创建指标。

直接跳转到风格

  • 原始 / register 插件风格
  • 每个请求风格
  • 每个指标风格

register 配置风格

这是此插件使用的原始风格。它允许为单个从设备进行每个寄存器的配置。

出于历史原因,这种配置风格与其他风格不完全一致。

data_type 的用法

data_type 字段定义了来自 modbus 寄存器的数据值的表示形式。然后,输入值将根据给定的 data_type 转换为发送给输出插件的合适类型。这些输出类型通常是整数或浮点数。假定输出类型的尺寸足够大,可以容纳所有支持的输入类型。从输入类型到输出类型的映射是固定的,无法配置。

布尔值:BOOL

此类型仅适用于 线圈离散输入 寄存器。如果寄存器的值为非零(ON),则值为 true,否则为 false

整数:INT8LINT8HUINT8LUINT8H

这些类型用于 8 位整数值。选择与您的 modbus 数据源匹配的类型。LH 后缀分别表示寄存器的低字节和高字节。

整数:INT16UINT16INT32UINT32INT64UINT64

这些类型用于整数输入值。选择与您的 modbus 数据源匹配的类型。对于 线圈离散输入 寄存器,只有 UINT16 有效。

浮点数:FLOAT16-IEEEFLOAT32-IEEEFLOAT64-IEEE

如果您的 modbus 寄存器包含以这种格式编码的值,请使用这些类型。这些类型始终包含符号,因此不存在变体。

定点数:FIXEDUFIXED

这些类型在输入时被视为整数类型,但会被转换为浮点表示形式以供进一步处理(例如,缩放)。当输入值是小数定点表示的非整数值时,请使用其中一种类型。

当输入类型声明为保存无符号整数值(不能为负数)时,请选择 UFIXED 类型。您的 modbus 设备文档应通过术语“uint16 包含具有 N 位小数的定点表示”等进行说明。

当输入类型声明为保存有符号整数值时,请选择 FIXED 类型。您的 modbus 设备文档应通过术语“int32 包含具有 N 位小数的定点表示”等进行说明。

字符串:STRING

此类型用于查询 address 设置中指定的寄存器数量,并将字节序列转换为字符串。请注意,如果字节序列包含 null 字节,则字符串在此位置截断。您不能对字符串字段使用 scale 设置。

位:BIT

此类型用于查询 address 设置中指定的寄存器的单个位,并将该值转换为无符号整数。此类型 **要求** 指定 bit 设置。


request 配置风格

此风格可用于直接指定 modbus 请求。它允许指定多个 [[inputs.modbus.request]] 部分,包括多个从设备。这样,可以查询 modbus 网关设备。请注意,对于非连续地址,请求 可能会被拆分。如果您想避免此行为,请添加具有 omit 标志的 字段 来填充地址之间的空隙。

从设备

您可以使用 slave_id 设置来指定要查询的从设备 ID。每个请求都应指定它,否则默认为零。请注意,每个请求只能指定一个 slave_id

寄存器的字节顺序

byte_order 设置指定寄存器的字节和字顺序。它可以设置为 ABCD(用于 大端(Motorola))或 DCBA(用于 小端(Intel))格式,以及 BADCCDAB(用于 大端小端 并进行 字节交换)。

寄存器类型

register 设置指定要查询的 modbus 寄存器集,可以设置为 coildiscreteholdinginput

每个请求的测量设置

您可以使用 measurement 设置为以下字段定义指定度量名称。如果省略此设置,则使用 modbus。此外,度量值可以被每个字段单独覆盖。

优化设置

**仅当您理解其含义时才使用请求优化!** optimization 设置可用于优化发送到设备的实际请求。以下算法可用:

none (默认)

不执行任何优化。请注意,请求仍然遵守最大请求大小。此外,完全空的请求(其中所有字段都指定 omit=true)将被删除。否则,请求将按照用户指定的方式发送,包括对已省略字段的请求。如果需要完全控制请求(例如,以适应设备限制),则应使用此设置。

shrink

此优化允许从请求中删除前导和尾随字段(如果这些字段被省略)。在指定大量省略字段(例如,用于文档目的)的情况下,这可以减小请求的数量和大小。

rearrange

请求的处理方式类似于 shrink,但会重新排列请求边界,通常读取的寄存器数量会减少,同时保持请求数量不变。此优化算法仅适用于连续地址范围,并尊重用户定义的字段地址之间的间隙。

**请注意:** 如果有许多不连续、未省略的字段,此优化可能会花费很长时间!

max_insert

字段被分配到同一个请求,只要字段之间的间隔不超过 optimization_max_register_fill 中给出的最大填充大小。用户定义的省略字段将被忽略并解释为间隔,因此最佳实践是不为此优化器手动插入省略字段。这允许仅指定实际使用的字段,让优化器自行组织请求,从而大大提高查询时间。权衡在于读取的额外寄存器之后被丢弃的成本与许多请求的成本。

**请注意:** optimization_max_register_fill 的最佳值取决于网络和被查询的设备。因此,建议测试几个值并评估性能以找到最佳值。使用 --test --debug 标志来监视发送了多少请求以及触及的寄存器数量。

字段定义

每个 request 可以包含一个要从 modbus 设备收集的字段列表。

address

字段由 address 标识,该地址反映了 modbus 寄存器地址。您通常可以在 modbus 设备的数据表中找到不同数据点的地址值。这是一个强制性设置。

对于 线圈离散输入 寄存器,此设置指定了包含字段值的 **位**。

name

使用 name 设置,您可以指定插件输出的度量中的字段名称。如果字段的 omit 设置为 true,则此设置将被忽略,在此情况下可以省略。

**请注意:** 在由 measurementslave_idregister 标识的单个度量中,不能有多个具有相同 name 的字段。

寄存器数据类型

type 设置指定 modbus 寄存器的数据类型,可以设置为 INT8LINT8HUINT8LUINT8H,其中 L 是寄存器的低字节,H 是高字节。此外,还有用于整数类型的 INT16UINT16INT32UINT32INT64UINT64,或用于 IEEE 754 二进制浮点表示的 FLOAT16FLOAT32FLOAT64FLOAT16 表示半精度浮点数,具有 16 位表示。通常,寄存器的数据类型与上述 address 相关联,并在 modbus 设备的数据表中列出。

STRING 数据类型比较特殊,它需要指定 length 设置,该设置包含字符串所在的寄存器数量。返回的字节序列被解释为字符串,并截断到找到的第一个 null 字节(如果存在)。对于此 type,不能使用 scaleoutput 设置。

如果字段的 omit 设置为 true,或者 register 类型是位类型(coildiscrete),则忽略此设置,并且在这种情况下可以省略。

缩放

您可以使用 scale 设置来缩放寄存器值,例如,如果寄存器包含 UINT32 格式的定点值,小数点后有两位。要将读取的寄存器值转换为实际值,可以将 scale=0.01 设置为 0.01。缩放因子用于计算,例如 field_value * scale

如果字段的 omit 设置为 true,或者 register 类型是位类型(coildiscrete),则忽略此设置,并且在这种情况下可以省略。

**请注意:** 如果未指定输出格式,则生成的字段类型将设置为 FLOAT64

输出数据类型

使用 output 设置,您可以显式指定输出字段数据类型。output 类型可以是 INT64UINT64FLOAT64。如果未显式设置,则输出类型猜测如下:如果 scale 设置为非零值,则输出类型为 FLOAT64。否则,输出类型对应于寄存器数据类型类别INT* 将导致 INT64UINT* 将导致 UINT64FLOAT* 将导致 FLOAT64)。

如果字段的 omit 设置为 true,则忽略此设置,可以省略。如果 register 类型是位类型(coildiscrete),则只有 UINT16BOOL 有效,前者是默认值(如果省略)。对于 coildiscrete 寄存器,字段值以 UINT16 格式输出为零或一,或以 BOOL 格式输出为 truefalse

每个字段的测量设置

measurement 设置可用于在每个字段的基础上覆盖度量名称。如果您想将一个请求中的字段拆分到多个度量中,这可能很有用。如果未指定,则使用在 request 部分指定的,或者(如果该部分也省略)modbus 的值。

如果字段的 omit 设置为 true,则忽略此设置,可以省略。

省略字段

当指定 omit=true 时,将在收集度量时忽略相应字段,但在构建 modbus 请求时会将其考虑在内。这样,您可以填充地址中的“空隙”以构建连续地址范围,从而生成单个请求。使用单个 modbus 请求可能很有益,因为所有值都在同一时间点收集。

标签定义

每个 request 都可以附带适用于该请求的标签。

**请注意:** 这些标签的优先级高于预定义的标签,如 nametypeslave_id


metric 配置风格

此风格可用于直接指定所需的指标,而不是侧重于 modbus 视图。可以指定多个 [[inputs.modbus.metric]] 部分,包括多个从设备。这样,可以查询 modbus 网关设备。该插件会自动收集指定指标的寄存器,按从设备和寄存器类型分组,并(可选地)优化生成的请求以处理非连续地址。

从设备

您可以使用 slave_id 设置来指定要查询的从设备 ID。每个指标部分都应指定它,否则默认为零。请注意,每个指标部分只能指定一个 slave_id

寄存器的字节顺序

byte_order 设置指定寄存器的字节和字顺序。它可以设置为 ABCD(用于 大端(Motorola))或 DCBA(用于 小端(Intel))格式,以及 BADCCDAB(用于 大端小端 并进行 字节交换)。

度量名称

您可以使用 measurement 设置来指定给定部分中定义的字段的度量名称。如果省略此设置,则使用 modbus

优化设置

**请仅在您理解其含义时才使用请求优化!** optimization 设置可以全局指定(**不** 按指标部分指定),并用于优化发送到设备的实际请求。在这里,优化应用于所有指标部分!以下算法可用:

none (默认)

不执行任何优化。请注意,连续寄存器仍会分组到一个请求中,同时遵守最大请求大小。如果您希望触及的寄存器数量最少,但代价是发送到设备的请求数量更多,则应使用此设置。

max_insert

字段被分配到同一个请求,只要触及的寄存器之间的间隔不超过通过 optimization_max_register_fill 设置的最大填充大小。此优化可能会导致请求数量大大减少,从而提高查询时间。权衡在于读取的额外寄存器之后被丢弃的成本与许多请求的成本。

**请注意:** optimization_max_register_fill 的最佳值取决于网络和被查询的设备。因此,建议测试几个值并评估性能以找到最佳值。使用 --test --debug 标志来监视发送了多少请求以及触及的寄存器数量。

字段定义

每个 metric 都可以包含一个要从 modbus 设备收集的字段列表。指定的字段直接对应于结果指标的字段。

register

register 设置指定要查询的 modbus 寄存器集,可以设置为 coildiscreteholdinginput

address

字段由 address 标识,该地址反映了 modbus 寄存器地址。您通常可以在 modbus 设备的数据表中找到不同数据点的地址值。这是一个强制性设置。

对于 线圈离散输入 寄存器,此设置指定了包含字段值的 **位**。

name

使用 name 设置,您可以指定插件输出的度量中的字段名称。

**请注意:** 在由 measurementslave_idregister 和标签集标识的单个度量中,不能有多个具有相同 name 的字段。

寄存器数据类型

type 设置指定 modbus 寄存器的数据类型,可以设置为 INT8LINT8HUINT8LUINT8H,其中 L 是寄存器的低字节,H 是高字节。此外,还有用于整数类型的 INT16UINT16INT32UINT32INT64UINT64,或用于 IEEE 754 二进制浮点表示的 FLOAT16FLOAT32FLOAT64FLOAT16 表示半精度浮点数,具有 16 位表示。通常,寄存器的数据类型与上述 address 相关联,并在 modbus 设备的数据表中列出。

STRING 数据类型比较特殊,它需要指定 length 设置,该设置包含字符串所在的寄存器数量。返回的字节序列被解释为字符串,并截断到找到的第一个 null 字节(如果存在)。对于此 type,不能使用 scaleoutput 设置。

如果 register 是位类型(coildiscrete),则忽略此设置,并且在这种情况下可以省略。

缩放

您可以使用 scale 设置来缩放寄存器值,例如,如果寄存器包含 UINT32 格式的定点值,小数点后有两位。要将读取的寄存器值转换为实际值,可以将 scale=0.01 设置为 0.01。缩放因子用于计算,例如 field_value * scale

如果 register 是位类型(coildiscrete),则忽略此设置,并且在这种情况下可以省略。

**请注意:** 如果未指定输出格式,则生成的字段类型将设置为 FLOAT64

输出数据类型

使用 output 设置,您可以显式指定输出字段数据类型。output 类型可以是 INT64UINT64FLOAT64。如果未显式设置,则输出类型猜测如下:如果 scale 设置为非零值,则输出类型为 FLOAT64。否则,输出类型对应于寄存器数据类型类别INT* 将导致 INT64UINT* 将导致 UINT64FLOAT* 将导致 FLOAT64)。

如果 register 是位类型(coildiscrete),则只有 UINT16BOOL 有效,前者是默认值(如果省略)。对于 coildiscrete 寄存器,字段值以 UINT16 格式输出为零或一,或以 BOOL 格式输出为 truefalse

标签定义

每个 metric 都可以附带一组标签。这些标签直接对应于结果指标的标签。

**请注意:** 这些标签的优先级高于预定义的标签,如 nametypeslave_id


故障排除

奇怪的数据

Modbus 文档通常很混乱。人们混淆内存地址(从一开始)和寄存器地址(从零开始),或者不确定使用的字顺序。此外,还有一些非标准实现会交换寄存器字(16 位)内的字节。

如果您遇到错误或未从设备获得预期值,您可以尝试以下步骤(假设是 32 位值)。

如果您使用的是串行设备并收到 permission denied 错误,请检查串行设备的权限并相应地更改它们。

如果您收到 exception '2' (illegal data address) 错误,您可以尝试将 address 条目偏移减一,因为很可能存在内存地址和寄存器地址之间的混淆。

如果您看到奇怪的值,则 byte_order 可能不正确。您可以尝试探测所有组合(ABCDCDBABADCDCBA),或者设置 byte_order="ABCD" data_type="UINT32" 并使用在线转换器(如)中的结果值。如果您不想更改设备,处理 64 位值,以及/或不知道寄存器的 data_type(例如,定点浮点值与 IEEE 浮点数),这尤其有用。

如果您的数据仍然看起来损坏,请将您的配置、错误消息和/或 byte_order="ABCD" data_type="UINT32" 的输出发布到 telegraf 的一个支持渠道(论坛、slack 或作为 issue)。如果都没有帮助,请将您的配置、错误消息和/或 byte_order="ABCD" data_type="UINT32" 的输出发布到 telegraf 的一个支持渠道(论坛、slack 或作为 issue)。

解决方法

某些 Modbus 设备在读取数据时需要特殊的读取特性,否则会失败。例如,某些串行设备需要在寄存器读取请求之间暂停。其他设备可能只支持有限数量的同时连接设备,例如串行设备或某些 ModbusTCP 设备。如果您需要并行访问这些设备,您可能希望在插件完成读取后立即断开连接。

为了使此插件也能处理这些“特殊”设备,提供了 workarounds 配置选项。如果您的文档说明了某些读取要求,或者您收到读取超时或其他读取错误,您可能需要尝试一种或多种解决方法。如果您发现您的设备需要其他/更多的解决方法,请告知我们。

如果您的设备需要尚未实现的解决方法,请打开一个 issue 或提交一个 pull request。

Metrics

插件读取配置的寄存器,并根据指定的配置构建指标。没有预定义的度量格式。

示例输出

modbus,name=device,slave_id=1,type=holding_register energy=3254.5,power=23.5,frequency=49,97 1701777274026591864

此页面是否有帮助?

感谢您的反馈!


InfluxDB 3.8 新特性

InfluxDB 3.8 和 InfluxDB 3 Explorer 1.6 的主要增强功能。

查看博客文章

InfluxDB 3.8 现已适用于 Core 和 Enterprise 版本,同时发布了 InfluxDB 3 Explorer UI 的 1.6 版本。本次发布着重于操作成熟度,以及如何更轻松地部署、管理和可靠地运行 InfluxDB。

更多信息,请查看

InfluxDB Docker 的 latest 标签将指向 InfluxDB 3 Core

在 **2026 年 2 月 3 日**,InfluxDB Docker 镜像的 latest 标签将指向 InfluxDB 3 Core。为避免意外升级,请在您的 Docker 部署中使用特定的版本标签。

如果使用 Docker 来安装和运行 InfluxDB,latest 标签将指向 InfluxDB 3 Core。为避免意外升级,请在您的 Docker 部署中使用特定的版本标签。例如,如果使用 Docker 运行 InfluxDB v2,请将 latest 版本标签替换为 Docker pull 命令中的特定版本标签 — 例如

docker pull influxdb:2