# modbus.parse_tcp

## 功能

解析 Modbus TCP 响应帧，校验 MBAP length 并提取常见响应字段。

## 语法

```bt
modbus.parse_tcp(data)
```

## 参数

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

## 返回值

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

## 返回对象字段

| 字段 | 类型 | 必定存在 | 说明 |
|------|------|------|------|
| protocol | String | 是 | 协议类型，固定为 `tcp`。 |
| transaction_id | Int | 是 | MBAP 事务编号。 |
| protocol_id | Int | 是 | MBAP 协议编号，标准 Modbus TCP 通常为 `0`。 |
| length | Int | 是 | MBAP length 字段，表示 `unit_id + pdu` 的字节数。 |
| valid_length | Bool | 是 | 输入字节长度是否和 MBAP length 精确一致。输入更长时仍按 MBAP length 解析当前帧。 |
| unit_id | Int | 是 | MBAP 单元标识。 |
| 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([0, 1, 0, 0, 0, 7, 1, 3, 4, 0, 10, 0, 20])
result = modbus.parse_tcp(frame)

// 输出：20
print result.registers[1]
```

## 注意事项

- `valid_length` 表示输入长度是否和 MBAP length 精确一致；输入更长时仍按 MBAP length 解析当前帧。
