# modbus.parse_rtu

## 功能

解析 Modbus RTU 响应帧，校验 CRC 并提取常见响应字段。

## 语法

```bt
modbus.parse_rtu(data)
```

## 参数

| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|------|------|------|
| data | Bytes/Array/String | 是 | 无 | RTU 响应帧。 |

## 返回值

| 类型 | 说明 |
|------|------|
| Object | 返回 RTU 响应解析对象。字段见下方“返回对象字段”。 |

## 返回对象字段

| 字段 | 类型 | 必定存在 | 说明 |
|------|------|------|------|
| protocol | String | 是 | 协议类型，固定为 `rtu`。 |
| unit_id | Int | 是 | RTU 从站地址。 |
| crc | Int | 是 | 响应帧尾部携带的 CRC16 值，按低字节在前解析。 |
| crc_expected | Int | 是 | 根据响应负载重新计算得到的 CRC16 值。 |
| valid_crc | Bool | 是 | `crc` 是否等于 `crc_expected`。CRC 不匹配时仍会继续解析 PDU。 |
| function_code | Int | 是 | 响应功能码。异常响应会带最高位，例如 `0x83`。 |
| exception | Bool | 是 | 是否为 Modbus 异常响应。 |
| exception_code | Int/Empty | 否 | 异常响应的异常码；仅 `exception` 为 `true` 时写入，响应中缺失异常码时为 `empty`。 |
| data | Bytes | 是 | PDU 中去掉功能码后的原始数据。异常响应时包含异常码字节。 |
| byte_count | Int | 否 | 读线圈、读离散输入、读保持寄存器、读输入寄存器响应中的数据字节数。其它响应不写入该字段。 |
| coils | Array | 否 | 读线圈或读离散输入响应解析出的布尔数组。其它响应不写入该字段。 |
| registers | Array | 否 | 读保持寄存器或读输入寄存器响应解析出的 16 位无符号寄存器整数数组。其它响应不写入该字段。 |
| address | Int | 否 | 写单个线圈、写单个寄存器、写多个线圈、写多个寄存器确认响应中的起始地址。其它响应不写入该字段。 |
| value | Int | 否 | 写入确认响应中的数量或写入值。功能码 5/6 表示写入值，功能码 15/16 表示写入数量。 |

## 代码示例

```bt
frame = bytes('010304000a0014da3e', 'hex')
result = modbus.parse_rtu(frame)

// 输出：10
print result.registers[0]
```

## 注意事项

- CRC 不匹配时不会丢弃数据，`valid_crc` 返回 false，脚本可自行决定是否丢弃。
- 异常响应会返回 `exception: true` 和 `exception_code`。
