编辑 | blame | 历史 | 原始文档

data-acquisition

亨旺特导 MES 数据采集器(Spring Boot 2.6.3 / Java 8)

  • 采集方式:串口(手动监听)、Access 数据库、PostgreSQL
  • 服务端口:9527(server.port
  • 日志目录:logging.file-location(默认 D:\mes-acquistion\logs
  • 统一返回格式:{ "code": 0, "msg": null, "data": ... }code=0 成功,code=1 失败(原因在 msg 里)

一、串口采集(手动监听)

串口不随项目启动自动监听:调用开启接口打开串口并取数,采集结束后调用关闭接口释放串口。

接口 说明
GET /collection/openSerialPort 开启串口监听并返回当前接收到的数据列表(没有数据时返回空集合,由前端轮询取数)。幂等:参数一致时复用已打开的串口,参数变化时按新参数重新打开,多线程并发调用也只会打开一次
GET /collection/closeSerialPort 关闭串口监听(幂等,未开启时调用也返回成功)
GET /collection/serialPortStatus 查询监听状态,返回 listenName / listening / portOpen / dataSize

串口参数(全部由接口传入,不传的字段用默认值)

参数 默认值 说明
serialPortName 必传 串口名称,如 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 1 数据缓存队列长度:队列满时插入最新一条、移除最旧一条;默认 1 即只返回设备最新的一条
frameIdleMillis 200 帧空闲补帧时间(毫秒):超过该时间没有新数据,就把缓冲区剩余数据当成一帧取出;0 表示关闭

调用示例:

# 开启监听并取数(9600 8N1、结束标志 *,默认只取最新一条)
http://127.0.0.1:9527/collection/openSerialPort?serialPortName=COM12

# 19200 偶校验、以换行结尾、最多取 6 条
http://127.0.0.1:9527/collection/openSerialPort?serialPortName=COM12&baudRate=19200&parity=EVEN&endMark=%0A&maxCount=6

# 查看监听状态 / 关闭串口
http://127.0.0.1:9527/collection/serialPortStatus
http://127.0.0.1:9527/collection/closeSerialPort

取数与切帧规则

  • 数据按 endMark 切成一帧一帧;
  • 切出来的数据放进队列缓存:插入最新的一条,超过 maxCount 条时移除最旧的一条,
    因此接口每次最多返回 maxCount 条最新的数据(按接收先后顺序);数据被取走后队列清空,重新开始缓存;
  • 设备最后一帧如果不带结束标志(例如每帧以 * 开头、靠下一个 * 分隔前后两帧),只靠结束标志会漏掉最后一条,
    此时由 frameIdleMillis 兜底:串口空闲超过该时间就把接收缓冲区里剩下的数据当作一帧取出;
    如果设备每帧都以结束标志结尾,缓冲区每次切分后都是空的,空闲补帧不会做任何事;
  • 参数与当前生效参数一致时复用已经打开的串口(不会重复打开);参数变化时按新参数重新打开;
  • 再次开启监听时会清掉上一轮残留的半包数据和未取走的数据,保证每次采集的数据只属于本轮;
  • 参数非法时接口直接返回具体原因(如 串口参数 dataBits 非法:9,取值范围 5~8)。

并发说明

  • 开启 / 关闭串口由同一把锁保护,重复调用只会真正打开一次串口,不会重复注册监听器;
  • 采集结果存放在同步集合中,多线程同时取数时同一条数据只会被一个线程取走,不会重复也不会丢失;
  • 监听状态使用 volatile 标记,关闭串口后回调线程不再处理数据。

二、数据库采集

接口 说明
GET /collection/getAccessData 采集 Access 数据库(.mdb/.accdb)表数据,返回 List<Map<String,Object>>
GET /collection/getPostgreSqlData 采集 PostgreSQL 表数据,返回 List<Map<String,Object>>

参数(DatabaseDTO):

参数 说明
filePath Access 数据库文件路径(仅 getAccessData
ipAddress / serverPort / databaseName PostgreSQL 连接信息(仅 getPostgreSqlData
userName / password 数据库用户名、密码;Access 的文件打开密码放在 passworduserName 对 Access 文件加密无作用)
tableName 数据表名
pointColumns 要采集的字段,多个用逗号分隔
mainColumn + batchCode 按批次过滤:mainColumn = batchCode
orderColumn / orderRule 排序字段与规则(ASC/DESC,不传默认 ASC

Access 读取方式(mes.access.read-mode

  • jackcess(默认):jackcess 只读直读(DatabaseBuilder.setReadOnly(true).setAutoSync(false)),打开文件后顺序扫描单表、只取需要的列,不构建 HSQLDB 镜像,只取某张表几列时最快;
  • ucanaccess:走 UCanAccess 的 SQL 路径,需要 Access SQL、链接表 remap 等场景时使用。

jackcess 模式的差异:

  • mainColumn 过滤是整表扫描:本库文本索引的排序规则是中文 2052,jackcess 不支持(索引只读、索引游标直接抛异常),没有可用的索引查询路径;orderColumn 排序在 Java 侧完成;
  • OLE 字段与原来一样返回 null,且不会读取它的长值;
  • 时间字段统一返回 java.sql.Timestamp(JSON 里仍是 yyyy-MM-dd HH:mm:ss.SSS);
  • 设置了打开密码的库会自动用 jackcess-encrypt 打开(密码取 password 参数;Access 的文件加密只有“打开密码”一个概念,userName 不参与,.mdw 工作组级安全性 jackcess 不支持);ucanaccess 模式下有 jackcess-encrypt 在 classpath 上,password 参数同样对加密库生效;
  • 链接表的行为与 UCanAccess 的 remap 不同,遇到问题切回 ucanaccess 模式即可。

三、托盘图标

程序启动后任务栏右下角会出现托盘图标(SystemTrayInitializer),右键菜单:

菜单项 说明
查看串口状态 弹出状态窗口:串口名称 / 监听状态 / 串口连接 / 缓存条数,每秒自动刷新
关闭串口 只关闭串口监听(不退出程序),方便现场把串口释放给别的程序用;结果用托盘气泡提示
打开日志目录 打开 logging.file-location 配置的日志目录
退出 先关闭 Spring 容器(触发 @PreDestroy:关闭串口、停止补帧线程),再结束进程
  • 双击托盘图标 = 查看串口状态;
  • 菜单弹出在光标上方、右边缘对齐,点菜单外面 / 按 ESC / 再右键一次都会收起;
  • 图标优先用 src/main/resources/tray.png(放一张 32x32 的 png 即可换成自己的图标),没有就用代码画的默认图标;
  • 托盘依赖 AWT,启动类里已经 setHeadless(false);以 Windows 服务方式运行(没有桌面会话)时托盘不显示,接口不受影响。

四、构建与运行

# 打包(产物 target/data-acquisition.jar,可直接 java -jar 运行)
mvn clean package -DskipTests

# 运行(需要 Java 8)
java -jar target/data-acquisition.jar
  • 双击 jar 运行:需要把 .jar 的默认打开方式指向 Java 8 的 javaw.exe
    (右键 jar → 打开方式 → 选择其他应用 → 更多应用 → 在这台电脑上查找其他应用 → <jdk8>\bin\javaw.exe → 勾选“始终使用此应用打开 .jar 文件”)。
    注意不要指向高版本 JDK(本项目是 Spring Boot 2.6.3,只支持 Java 8~17),也不要用压缩软件打开;
  • 用 javaw 启动没有控制台,**启动失败会弹窗提示**(例如端口被占用、日志目录不可写),详细错误看 logging.file-location 目录下的日志;
  • 退出请用托盘菜单的「退出」(会正常关闭串口);直接结束进程不会走这套清理流程。

五、配置(application.yml)

server:
  port: 9527                              # 服务端口

logging:
  file-location: D:\mes-acquistion\logs   # 日志目录(托盘“打开日志目录”也用它)

#mes:
#  access:
#    read-mode: jackcess                   # Access 读取方式:jackcess(默认,直读单表)/ ucanaccess(SQL 模式)

串口参数(串口名、波特率、数据位、校验位、结束标志等)全部由接口传入,配置文件里不需要串口相关配置。