搞工控上位机和数据采集,最烦的一件事就是:手里没有真 PLC,代码写完只能干等。
买一台太贵,借一台排期太长。好不容易连上现场的 S7-1500 想看个 Tag,要么装笨重的商用软件,要么忍受界面万年不更、点一下卡半天的 UaExpert。
最近发现了一个开源工具 DruOPC,正好把这两件事一并解决了。
DruOPC 是带有 PLC 模拟器的 Web 端 OPC UA 工具。
它由两个独立模块组成,合在一起好用,拆开也能单独连外部设备。
- 服务端:假装成一台 PLC 持续向外吐数据。
- 客户端:纯 Web 界面,浏览器打开即用,免安装。

没设备时帮你造一台,有设备时帮你把每个 Tag 看明白。
下面看看具体做了哪些功能。
可以模拟出 PLC 服务端
启动后直接监听 opc.tcp://localhost:50000,像真机一样不断输出点位。
预置好了各类常用节点:正弦波、随机整数、跳变布尔量。快节点 1 秒刷新,慢节点 10 秒更替,Good、Bad、Uncertain 等数据质量也会交替轮换。
想模拟特定产线,改个 JSON 就行,不用重新编译。
{
"Folder": "MyTelemetry",
"NodeList": [
{ "NodeId": "ActualSpeed", "DataType": "Float", "Description": "Rotational speed" }
]
}
自定义节点可以读写,并且可以挂载到不同的 namespace 下来模拟多台设备。HeaterOn、ResetTrend 等方法在客户端上点击一下就可以直接触发。
报警与事件模拟
加上一个环境变量就可以把报警功能拉起来:
$env:OpcPlc__Simulation__AddAlarmSimulation="true"; dotnet run --project src
开启后,模拟器会按照一定节拍发送 Trip 跳闸和 Deviation 偏差。电机、储罐这些源都能配,报警确认、追加批注全流程都能测,相当于一个小假车间。
还可以通过 JSON 脚本定义确定性报警序列,专门测试上位机的列表刷新与异常重连。
浏览器打开就能连任何 OPC UA 服务端
这是日常最常用的模块,纯 Web 客户端,完全免安装。
在地址栏输入 Endpoint,点击 Connect,信任证书后就可以直接连接。

界面布局符合工业控制习惯:左边是节点树,右边是属性,中间是实时监控列表。
数值写进去就立即生效,就像在 HMI 上强制变量一样,测写点很方便。会话按浏览器标签隔离,URL 还支持深链接,把网址发给同事就能直接定位到同一个节点。
UDT 结构体不是一坨乱码
传统客户端里,复杂结构体常常显示为无法识别的 ExtensionObject。
DruOPC 会自动把它们展开成可以折叠的 JSON 树。电机参数块、配方数据等多层嵌套的对象,层层点开一清二楚。

报警确认和历史趋势在线测
Alarms 页面就相当于一个现成的 HMI 报警看板。
点击 Subscribe 就会自动刷新并拉回所有活动报警,点击 Ack 就可以确认并填写批注,流程和真机一样。
如果节点有历史数据,点时钟图标就能拉出时间曲线,并且可以一键导出为 CSV。

配置全在一个 JSON 里
所有模拟器设置都在 appsettings.json 中,也可以用环境变量覆盖。
参数写错或者端口冲突时,程序会直接报错退出,不会静默跑偏,排查问题很省心。
自带混沌模式,客户端也可以自己玩
开启 RunInChaosMode 后,模拟器会随机抽风:主动断开连接、终止订阅、返回错误码。
专门用来压测自己写的上位机,看断线重连和异常恢复是否足够健壮,省去手动拔网线的麻烦。
本地运行也很简单
Docker 一行命令就能把服务端与客户端全套跑起来:
git clone https://github.com/drusteeby/DruOPC.git
cd DruOPC
docker compose up
浏览器访问 http://localhost:5000,填入 opc.tcp://simulator:50000 即可连通。
不习惯 Docker 也可以装 .NET 10 SDK 本地运行。它同样能连真实 PLC,西门子、倍福、Kepware 等标准 OPC UA 服务端均完全兼容。
有兴趣的朋友可以试试看。
开源地址:https://github.com/drusteeby/DruOPC