PC 桌面富应用:WCS 硬件通信客户端
摘要
针对仓库自动化场景中 WCS(仓库控制系统)与硬件设备的通信需求,结合团队前端技术栈,选型 Electron 作为桌面客户端框架,实现串口、TCP 两种核心通信方式及自动化更新机制。本文简洁阐述方案选型、核心实现及注意事项,为工业场景 WCS 客户端开发提供可落地参考。
1. 需求背景与核心目标
1.1 业务与技术背景
WCS 是仓库自动化的核心,负责调度传送带、AGV 等硬件设备,实现业务系统与硬件的双向交互。现场硬件主要支持串口、TCP Server 通信,不兼容 HTTP 协议,因此需开发桌面客户端(exe 形式)。
1.2 核心目标
- 实现串口、TCP 与硬件的稳定通信;
- 提供简洁运维 UI 界面;
- 支持自动化版本更新,降低多站点运维成本;
- 适配多站点本地部署场景。
2. 核心概念与协议基础
2.1 串口通信核心协议
串口通信是工业硬件主流交互方式,常用协议对比如下:
| 协议 | 传输方式 | 最大传输距离 | 适用场景 |
|---|---|---|---|
| RS-232 | 全双工 | ~ 15 米 | 近距离外设连接 |
| RS-422 | 全双工 | ~ 1200 米 | 长距离点对点传输 |
| RS-485 | 半双工 | ~ 1800 米 | 工业多节点组网 |
2.2 核心通信方式
现场硬件核心依赖串口和 TCP Server 通信,是本次客户端开发的重点适配对象。
3. 技术选型与整体架构
3.1 客户端框架选型
结合前端技术栈、更新需求,对比主流框架后选型 Electron,核心优势:匹配前端技术、更新机制成熟、生态完善、性能适配本地部署场景。
3.2 整体架构
本架构自顶向下分为客户端层、业务服务层、本地服务层、硬件设备层四层结构,实现从业务操作到硬件控制的全链路打通:
- 客户端层:由 PDA 应用、FMS 门户、设备控制台组成,面向现场作业人员与运维人员提供操作入口。
- 业务服务层:以 ASM 服务与 SLDS 服务为核心,处理业务逻辑、站内管理、SCADA(监督控制与数据采集系统)工单流转与离线模式调度。
- 本地服务层:包含 WCS、ASM 离线系统、Kepware(工业自动化通信平台)工业数据采集服务及设备适配层,实现业务指令下发、硬件数据采集、离线缓存与协议转换。
- 硬件设备层:以 PLC 控制器为核心,对接 ASM 自动化设备,执行实际分拣、搬运、控制等物理动作。
整体流程为:上层业务系统下发指令 → WCS 接收并转换 → 通过适配层与 Kepware 分别实现指令控制与数据采集 → PLC 驱动硬件执行动作,同时支持离线模式保障现场作业连续性。
3.3 客户端通信架构
Electron 客户端一边通过 HTTP 对接后端,一边通过串口、TCP 连接硬件,架构如下:
4. 串口通信实现
4.1 技术选型:SerialPort
选用 SerialPort 库,支持多平台,适配工业串口设备,可快速实现数据收发与异常处理。该库广泛应用于物联网、工业传感器、医疗设备等场景,是 JavaScript 与硬件固件交互的成熟方案。
4.2 核心参数与代码
核心参数:波特率(常用 115200)、数据位(8 位)、奇偶校验(none)、停止位(1 位)、超时(1000 - 3000 ms)。
const { SerialPort } = require('serialport');
// 串口配置(工业标准参数)
const SERIAL_CONFIG = {
path: process.platform === 'win32' ? 'COM4' : '/dev/ttyUSB1',
baudRate: 115200,
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false,
timeout: 1500
};
// 初始化串口实例
const serialPort = new SerialPort(SERIAL_CONFIG);
/**
* 监听硬件上报数据
*/
serialPort.on('data', (buffer) => {
const data = buffer.toString('ascii');
console.log('串口数据:', data);
mainWindow.webContents.send('serial:data-received', data);
});
/**
* 发送指令到硬件(统一格式)
* @param {string} cmd 原始指令
*/
function sendSerialCmd(cmd) {
if (!serialPort.isOpen) {
console.error('串口未连接');
return;
}
const formatCmd = `CMD_V1.3.0:${cmd}`;
serialPort.write(formatCmd, (err) => {
if (err) console.error('指令发送失败:', err.message);
});
}
/**
* 统一异常捕获
*/
serialPort.on('error', (err) => {
console.error('串口异常:', err.message);
});
4.3 模拟测试方案
开发阶段用 SerialPortMock 离线调试,模拟硬件数据收发,提升开发效率:
const { SerialPortMock } = require('serialport');
// 创建虚拟设备
SerialPortMock.binding.createPort('/dev/MOCK_DEVICE', { echo: true });
// 初始化模拟串口
const mockPort = new SerialPortMock({
path: '/dev/MOCK_DEVICE',
baudRate: 115200
});
// 定时模拟硬件数据上报
setInterval(() => {
mockPort.port.emitData('DEVICE_STATUS:OK,VALUE:456,VERSION:1.3.0');
}, 2000);
5. TCP 通信实现
5.1 技术选型:Node.js net 模块
采用 Node.js 原生 net 模块,无需额外依赖,适配硬件 TCP Server 模式,保证长连接稳定性。
5.2 核心代码实现
const net = require('net');
const { mainWindow } = require('./electron');
// TCP 连接配置
const TCP_CONFIG = {
host: '192.168.1.101',
port: 8081,
reconnectInterval: 3000
};
let tcpClient = new net.Socket();
let reconnectTimer = null;
/**
* TCP 连接方法
*/
function connectTcpServer() {
tcpClient.connect(TCP_CONFIG.port, TCP_CONFIG.host, () => {
clearInterval(reconnectTimer);
console.log('TCP 连接成功');
tcpClient.write('INIT_CONNECTION_V1.3.0');
});
}
/**
* 接收硬件数据
*/
tcpClient.on('data', (buffer) => {
const data = buffer.toString('ascii');
mainWindow.webContents.send('tcp:data-received', data);
});
/**
* 断开自动重连机制
*/
tcpClient.on('close', () => {
console.log('TCP 连接断开,尝试重连...');
tcpClient.destroy();
tcpClient = new net.Socket();
reconnectTimer = setInterval(connectTcpServer, TCP_CONFIG.reconnectInterval);
});
/**
* TCP 异常捕获
*/
tcpClient.on('error', (err) => {
console.error('TCP 异常:', err.message);
});
// 启动连接
connectTcpServer();
6. 自动更新机制(electron-updater)
6.1 更新流程
6.2 核心实现
将安装包、version.json 上传至 CDN,客户端启动时比对版本,后台下载更新,完成后弹窗提示安装。
const { autoUpdater, dialog } = require('electron-updater');
// 启动版本检查
autoUpdater.checkForUpdatesAndNotify();
/**
* 新版本下载完成后提示
*/
autoUpdater.on('update-downloaded', (info) => {
dialog.showMessageBox({
title: '更新就绪',
message: `新版本 ${info.version} 已下载,是否立即安装?`,
buttons: ['立即安装', '稍后']
}).then(({ response }) => {
if (response === 0) autoUpdater.quitAndInstall();
});
});
/**
* 更新失败提示
*/
autoUpdater.on('error', (err) => {
dialog.showMessageBox({
type: 'error',
title: '更新失败',
message: `自动更新异常:${err.message}`
});
});
7. 方案总结与注意事项
7.1 技术栈概览
| 模块 | 技术选型 | 核心价值 |
|---|---|---|
| 桌面框架 | Electron | 匹配前端,快速开发 |
| 串口通信 | SerialPort | 工业级稳定适配 |
| TCP 通信 | Node.js net 模块 | 原生无依赖,适配长连接 |
| 自动更新 | electron-updater | 开箱即用,适配多站点 |
7.2 核心优势
开发效率高、硬件兼容性强、运维成本低、稳定性适配工业场景。
7.3 注意事项
- 精简 Electron 打包依赖,提升启动速度;
- 限制 Node.js 权限,避免安全风险;
- 适配不同系统串口权限(Windows 配置权限、Linux 加入 dialout 组);
- 开启日志记录,便于异常排查。
附录:参考资料
- SerialPort 官方文档:https://serialport.io/
- Electron 官方文档:https://www.electronjs.org/(支持跨平台,内置 Chromium 和 Node.js,被 VS Code、Discord 等广泛使用)
- electron-updater 官方文档:https://www.electron.build/auto-update(文档内容超限,可参考官方最新教程)
更多推荐
所有评论(0)