上海郢昱
12 小时以前 0d9956362ef415d0b49318746e9a2ef955dcfebd
README.md
@@ -1,4 +1,47 @@
## data-acquisition
设备数据采集器
亨旺特导MES数据采集器
### 串口采集(手动监听)
串口不再随项目启动自动监听,改为手动监听:调用采集接口时开启监听,采集结束后调用关闭接口。
| 接口 | 说明 |
| --- | --- |
| `GET /lims/getFile?fileExtension=.serialPort` | 采集接口:调用时自动开启监听,并返回本次采集到的数据;没有数据时返回空集合,由前端轮询取数 |
| `GET /lims/openSerialPort` | 手动开启监听,并返回当前接收到的数据列表(幂等,参数一致时复用已打开的串口) |
| `GET /lims/closeSerialPort` | 手动关闭监听(幂等,采集结束后调用,避免串口一直被占用) |
| `GET /lims/serialPortStatus` | 查询监听状态:`listenName` / `listening` / `portOpen` / `dataSize` |
串口参数全部由接口传入,`/lims/getFile`(`fileExtension=.serialPort` 时)和 `/lims/openSerialPort` 都支持,
不传的字段使用默认值(`listenName` 必传)。application.yml 中的 `serialPort` 配置已不再生效,可以删除。
| 参数 | 默认值 | 说明 |
| --- | --- | --- |
| `listenName` | 必传 | 串口名称,如 `COM12`;不传会返回“串口名称不能为空” |
| `baudRate` | `9600` | 波特率 |
| `dataBits` | `8` | 数据位,5~8 |
| `stopBits` | `1` | 停止位,1、2、3(1.5 位) |
| `parity` | `NONE` | 校验位:`NONE`/`ODD`/`EVEN`/`MARK`/`SPACE`,也兼容 0~4 |
| `flowControl` | `NONE` | 流控:`NONE`/`RTS_CTS`/`XON_XOFF`,也兼容数字常量 |
| `readTimeout` | `1000` | 读取超时(毫秒) |
| `endMark` | `*` | 一帧数据的结束标志,特殊字符用 URL 编码,如换行 `%0A` |
| `maxCount` | `6` | 数据缓存队列长度:队列满时插入最新一条、移除最旧一条 |
| `frameIdleMillis` | `200` | 帧空闲补帧时间(毫秒):超过该时间没有新数据,就把缓冲区剩余数据当成一帧取出;`0` 表示关闭 |
示例:`/lims/getFile?fileExtension=.serialPort&listenName=COM12&baudRate=19200&parity=EVEN&endMark=%0A&maxCount=6`
参数与当前生效参数一致时复用已经打开的串口(不会重复打开);参数变化时会自动按新参数重新打开串口;
参数非法时接口直接返回具体原因(如 `串口参数 dataBits 非法:9,取值范围 5~8`)。
采集到的数据按队列缓存:插入最新的一条,超过 `maxCount` 条(默认 6 条)时移除最旧的一条,
因此接口每次最多返回 `maxCount` 条最新的数据(按接收先后顺序);数据被取走后队列清空,重新开始缓存。
数据帧按 `endMark` 切分。如果设备是「每帧以某个字符开头」而不是结尾(例如发 `*0 1 0`、`*0 2 0`,
`*` 用于分隔前后两帧),那么最后一帧后面没有新的 `*` 来触发切分,只靠结束标志会漏掉最后一条;
此时由 `frameIdleMillis`(默认 200ms)兜底:串口空闲超过该时间后,把接收缓冲区里剩下的数据当作一帧取出。
如果设备每帧都以结束标志结尾,缓冲区每次切分后都是空的,空闲补帧不会做任何事。
并发说明:开启 / 关闭串口由同一把锁保护,多线程并发调用采集接口也只会打开一次串口,不会重复注册监听器;
采集结果存放在同步集合中,多线程同时取数时同一条数据只会被一个线程取走,不会重复也不会丢失。
调用关闭接口后再次调用采集接口会重新开启监听,并清掉上一轮残留的半包数据和未取走的数据,保证每次采集的数据只属于本轮。