跳转到内容

Modbus 控制器传感器

modbus_controller 传感器平台从 modbus_controller 组件创建传感器, 需要配置 Modbus 控制器

  • register_type (必需): modbus 寄存器的类型。

    • coil: 线圈是 1 位寄存器(开/关值),用于控制离散输出。它们可以被读取和/或写入。将使用 Modbus 功能码 1(读线圈状态)
    • discrete_input: 离散输入寄存器(只读线圈)类似于线圈,但只能被读取。将使用 Modbus 功能码 2(读输入状态)
    • holding: 保持寄存器 - 保持寄存器是最通用的 16 位寄存器。它们可以被读取和/或写入。将使用 Modbus 功能码 3(读保持寄存器)
    • read: 读输入寄存器 - 寄存器是用于输入的 16 位寄存器,只能被读取。将使用 Modbus 功能码 4(读输入寄存器)
  • address (必需, int): 范围内第一个寄存器的起始地址(可以是十进制或十六进制)。

  • value_type (必需): modbus 寄存器数据的数据类型。modbus 的默认数据类型是大端格式的 16 位整数(MSB 优先)。

    • U_WORD: 来自 1 个寄存器的无符号 16 位整数 = 16 位
    • S_WORD: 来自 1 个寄存器的有符号 16 位整数 = 16 位
    • U_DWORD: 来自 2 个寄存器的无符号 32 位整数 = 32 位
    • S_DWORD: 来自 2 个寄存器的有符号 32 位整数 = 32 位
    • U_DWORD_R: 来自 2 个寄存器的无符号 32 位整数,低字在前
    • S_DWORD_R: 来自 2 个寄存器的有符号 32 位整数,低字在前
    • U_QWORD: 来自 4 个寄存器的无符号 64 位整数 = 64 位
    • S_QWORD: 来自 4 个寄存器的有符号 64 位整数 = 64 位
    • U_QWORD_R: 来自 4 个寄存器的无符号 64 位整数,低字在前
    • S_QWORD_R: 来自 4 个寄存器的有符号 64 位整数,低字在前
    • FP32: 来自 2 个寄存器的 32 位 IEEE 754 浮点数
    • FP32_R: 32 位 IEEE 754 浮点数 - 与 FP32 相同但低字在前
  • bitmask (可选, int): 有时多个值被打包在单个寄存器的响应中。可以使用位掩码从响应中提取值。请参阅 位掩码

  • skip_updates (可选, int): 默认情况下,modbus_controller 的所有传感器会一起更新。对于不经常变化的数据点,可以跳过更新。值为 5 表示仅在每第 6 个更新周期更新此传感器范围。注意:modbus_controller 按地址范围对组件进行分组以减少事务数量。所有具有相同起始地址的组件将在一个请求中更新。skip_updates 适用于同一范围内的 所有 组件。

  • register_count (可选, int): 此读取请求应在单个命令中跨越或跳过的连续寄存器数量。默认值为 1。有关更多详细信息,请参阅 优化 modbus 通信

  • response_size (可选, int): 寄存器响应的大小(以字节为单位)。默认为 register_count*2。

  • force_new_range (可选, boolean): 如果可能,具有顺序地址的传感器会被分组在一起并在一个范围内请求。设置 force_new_range: true 会强制在该地址开始新范围。

  • lambda (可选, lambda): 每个更新间隔评估一次的 lambda,用于获取传感器的新值。

    传递给 lambda 的参数

    • x (float): modbus 数据的解析浮点值

    • data (std::vector<uint8_t>): 包含此传感器完整原始 modbus 响应字节的向量 注意: 由于响应包含同一范围内所有寄存器的数据,您必须使用 data[item->offset] 来获取传感器的第一个响应字节。

    • item (指向 SensorItem 派生对象的 const 指针): 传感器对象本身。

    lambda 的可能返回值:

    • return <浮点数>; 传感器的新值。
    • return NAN; 如果状态应被视为无效以指示错误(高级用法)。
  • custom_command (可选, 字节列表): modbus 命令的原始字节。这允许使用非标准命令。如果使用 custom_command,则不能使用 addressregister_type。 自定义数据必须包含所有必需的字节,包括 modbus 设备地址。CRC 会自动计算并附加到命令后面。 请参阅 使用 custom_command 了解如何使用 custom_command

  • offset (可选, int): 从起始地址的字节偏移量(仅用于不常见的响应编码)。如果在命令中写入多个寄存器,此值用于查找此数据点相对于起始地址的开始位置。组件根据偏移量和值类型的大小计算范围的大小。对于 coildiscrete_input 寄存器,偏移量是线圈/寄存器的位置,因为这些寄存器在一个字节中编码 8 个线圈。

  • 来自 传感器 的所有其他选项。

下面的示例将发送 2 个 modbus 命令(假设设备地址为 1):

0x1 0x4 0x31 0x0 0x0 0x02 x7f 0x37(从 0x3100 开始读取 2 个寄存器)

0x1 0x3 0x90 0x1 0x0 0x1 0xf8 0xca(从 0x9001 读取 1 个保持寄存器)

- platform: modbus_controller
modbus_controller_id: modbus1
id: pv_input_voltage
name: "PV array input voltage"
address: 0x3100
unit_of_measurement: "V" ## 对于任何其他单位,值以分钟为单位返回
register_type: read
value_type: U_WORD
accuracy_decimals: 1
filters:
- multiply: 0.01
- platform: modbus_controller
modbus_controller_id: modbus1
name: "Battery Capacity"
id: battery_capacity
register_type: holding
address: 0x9001
unit_of_measurement: "AH"
value_type: U_WORD

modbus 传感器平台允许您使用 lambda 在数据发布之前调用。

下面的示例记录解析的值和为此寄存器范围接收的原始 modbus 字节:

# 示例配置条目
sensor:
- platform: modbus_controller
modbus_controller_id: modbus1
id: battery_capacity
address: 0x9001
name: "Battery Capacity"
register_type: holding
value_type: U_WORD
lambda: |-
ESP_LOGI("","Lambda incoming value=%f - data array size is %d",x,data.size());
ESP_LOGI("","Sensor properties: adress = 0x%X, offset = 0x%X value type=%d",item->start_address,item->offset,item->sensor_value_type);
int i=0 ;
for (auto val : data) {
ESP_LOGI("","data[%d]=0x%02X (%d)",i,data[i],data[i]);
i++;
}
return x ;