如何使用 InfluxDB 监控您的 Modbus 设备

导航至

我们在 Telegraf 1.14 中发布了一个新的 Modbus 输入插件,在本博客中,我想告诉您更多关于该插件的信息以及如何使用它。

Modbus InfluxData

什么是 Modbus?

Modbus 是一种用于工业设备的消息协议,由 Modicon(现在的施耐德电气)开发,用于这些智能设备之间的主从通信。它已成为远程终端单元 (RTU) 的理想协议,在这些单元中,无线通信是必要的。Modbus 是开放且免费的,制造商可以将其构建到他们的设备中,而无需支付任何版税。Modbus 协议现在由美国非营利行业协会 Modbus.org 控制。

Modbus 在哪里使用?

由于 Modbus 是一种免版税的开放协议,它已成为工业制造环境中应用最广泛的网络协议之一。Modbus 已被 数百家供应商在数千种不同的设备上实施,以在控制设备之间传输离散/模拟 I/O 和寄存器数据。行业分析师报告称,仅在北美和欧洲就有超过 700 万个 Modbus 节点

如何从使用 Modbus 的物联网设备中检索数据?

来自 Simply Modbus 关于数据如何在标准 Modbus 中存储的一些背景知识。从设备将信息存储在 4 个不同的表中:两个表存储开/关离散值(线圈),两个表存储数值(寄存器)。线圈和寄存器各有只读表和读写表,最多可存储 9999 个值。线圈/寄存器号可以被认为是位置名称,因为它们不会出现在实际消息中;它们的数据地址在消息中使用。

对象类型 访问权限 大小 地址空间
线圈 (Coil) 读写 1 位 00001 - 09999
离散输入 (Discrete input) 只读 1 位 10001 - 19999
输入寄存器 (Input register) 只读 16 位 30001 - 39999
保持寄存器 (Holding register) 读写 16 位 40001 - 49999

您可能想知道:Modbus 线圈和离散输入之间有什么区别?线圈可以读取或写入,而离散输入是只读的。线圈通常与继电器输出相关联。

您也可能会问:Modbus 输入寄存器和保持寄存器之间有什么区别?输入寄存器是只读的,而保持寄存器可以读取或写入。

您可以使用 Telegraf Modbus 输入插件通过 Modbus TCP 或 Modbus RTU/ASCII 从离散输入、线圈、输入寄存器和保持寄存器收集数据。与大多数 Telegraf 插件一样,Modbus 输入插件不需要详尽的配置。

要利用 Modbus 插件,您需要通过配置来自 discrete_inputscoils 的数字变量来确定您希望从设备收集的指标。这可以通过配置它们的变量名称 (name) 和变量地址 (address) 来完成。至于模拟变量,需要为从 holding_registersinput_registers 收集的每个指标配置 namebyte_orderdata_typescaleaddress

以下是 Modbus 输入插件的示例配置,可在 Telegraf 中用于检索 Modbus 指标。

[[inputs.modbus]]
  ## Connection Configuration
  ##
  ## The module supports connections to PLCs via MODBUS/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://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]},
    { name = "Reset",          address = [2]},
    { name = "EmergencyStop",  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  - 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]},
    { name = "Energy",      byte_order = "ABCD", data_type = "FLOAT32", scale=0.001, address = [5,6]},
    { name = "Current",     byte_order = "ABCD", data_type = "FLOAT32", scale=0.001, address = [1,2]},
    { name = "Frequency",   byte_order = "AB",   data_type = "FLOAT32", scale=0.1,   address = [7]},
    { name = "Power",       byte_order = "ABCD", data_type = "FLOAT32", scale=0.1,   address = [3,4]},
  ]
  input_registers = [
    { name = "TankLevel",   byte_order = "AB",   data_type = "INT16",   scale=1.0,     address = [0]},
    { name = "TankPH",      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]},
  ]

*注意:我们已联系 Modbus 组织以重命名主/从术语,以便可以在 Telegraf 配置中更新它。

通过 Telegraf Modbus 插件收集哪些指标?

从 Modbus 输入插件收集的指标是自定义的,并使用上面示例中的 discrete_inputscoilsholding_registerinput_registers 选项进行配置。

标签

Modbus 插件中的标签将返回标记为 host 的设备名称。

字段

在上面的示例配置中,收集的字段如下,并取决于在 holding_registersinput_registers 选项中设置的内容。

来自 holding_registers 配置

  • 功率因数 (PowerFactor)
  • 电压 (Voltage)
  • 能量 (Energy)
  • 电流 (Current)
  • 频率 (Frequency)
  • 功率 (Power)

来自 input_registers 配置

  • 液位 (TankLevel)
  • 罐体 pH 值 (TankPH)
  • 泵 1 速度 (Pump1-Speed)

使用 InfluxDB 轻松启动和运行 Modbus 监控的简单方法是什么?

InfluxDB 2.0 最近推出了 InfluxDB 模板——预先打包的 InfluxDB 配置,其中包含从仪表板和 Telegraf 配置到通知和警报的所有内容,都在一个清单文件中。InfluxDB 模板允许您快速设置 InfluxDB 的全新实例,并为常见设置创建可重用的模板。

Ray Farias 贡献了一个用于 Island Pulse Monitoring 的 Modbus 模板。此 InfluxDB 模板可用于从 Modbus 设备收集数据。

Monitoring dashboard - InfluxDB Template<figcaption> InfluxDB 模板中包含的 Island Pulse Monitoring 仪表板</figcaption>

该模板包含一个 Island Pulse Demo Modbus Device 仓库,用于您可以使用的工作演示设备,以探索 InfluxDB 模板和/或 Modbus Telegraf 输入插件。

开始使用 InfluxDB 和 Modbus!

最后,非常感谢贡献了 Modbus 输入插件的 Antonio Garcia 和为第一个利用它的 InfluxDB 模板的 Ray Farias!没有像 Antonio 和 Ray 这样的贡献者,InfluxData 就不会有今天的成就。

如果您或您的公司正在寻找一种方法来监控您的 Modbus 设备,请试用您在这篇 Telegraf 插件中读到的所有内容。我们很乐意听取您如何使用此插件或任何其他 InfluxData 产品监控 Modbus。加入我们的 社区 Slack 频道,您可以在其中提问并与其他使用 InfluxDB 的人互动。