一. 前言
OPC UA是一种基于
以太网的开放
通讯协议,亦可谓是工业4.0中的当红通讯协议
CONTROL ENGINEERING China版权所有,意在打通OT和IT网络,以一种统一的数据架构和方法,为不同网络中的设备相互访问和操作提供可能性,同时为不同行业不断变化的通讯需求提供充分的扩展性和安全性支持。
OPC UA的定义完全是在TCP/IP五层模型的应用层,也就是说,实现该协议并不需要专用芯片,也不需要任何物理层面的改动。
那么,我们如何才能让现有的设备支持上OPC UA协议呢?本文就以虹科
工业树莓派为例进行实践,为大家分享其实现OPC UA协议支持的方法。
虹科工业树莓派
RevPi本身出厂时,并没有内置OPC UA协议,但是我们可以利用相关的SDK搭建一个简单的server,然后把工业协议(如Modbus)中的数据,以OPC UA方式输出。
二. 准备工作
三. 操作步骤
1、工业树莓派上电,连上网线,PC使用Advanced IP Scanner或类似软件扫描树莓派的IP地址,或在路由器后台中直接查看DHCP客户端列表,从而确定树莓派所在IP地址。
2、使用SSH软件与工业树莓派建立连接,登录账号为pi,默认密码会印在机身侧面的贴纸上,每台机子默认密码各不相同。出现类似如下画面,即表示登录成功,本文后面的终端界面,如无特殊说明,均来自与工业树莓派的SSH会话。
3、简单起见,本文以python的开源OPC UA SDK为例,本文默认读者已有python基础,若无请先学习python基本语法。该SDK的GitHub仓库链接如下:
https://github.com/FreeOpcUa/python-opcua
python3环境在工业树莓派中已预装好控制工程网版权所有,我们只需要安装SDK库即可,安装命令如下:
pip3 install opcua
安装速度取决于网络环境,如果实在太慢,或者网络下载出错,可以考虑先给pip3换国内源,再安装该库,此处不展开说明,安装完成效果如下:
4、接下来,浏览器打开树莓派所在IP地址,登录,这次用户名改为adminwww.cechina.cn,密码和SSH密码是同一个,写在机身贴纸上。
5、登录后,进行Modbus配置(本文仍以ModbusTCP协议为例),配置方法请参考以往文章,或联系广州虹科获取相关指引文档,此处不再重复。整个连接配置如下表所示:
6、配置保存生效后,回到SSH界面,使用如下指令验证Modbus的连接是否成功建立:
piTest -r Input_Word_1
若配置正确,该指令应该会一直读取Input_Word_1变量存储的值,也就是Modbus从站变量地址为1的Holding Registers的值,直到按下Ctrl+C,如下图所示。
Input_Word_1亦可换成其它RevPi变量名进行读数测试,输入输出变量都可以使用该命令进行读取;我们也可以通过以下指令尝试写入变量:
piTest -w Output_Word_2,666
Output_Word_2也可以换成其它RevPi变量名,但仅当变量是个可写变量时,该指令才有意义。变量名和待写入值之间的逗号注意是英文的,不要输成中文的。
7、至此控制工程网版权所有,Modbus的连接部分已测试完成,我们准备开始python编程。首先,我们需要先确认刚才我们设置的变量的相关信息,分别执行以下终端命令。
piTest -v Input_Word_1
piTest -v Input_Word_2
piTest -v Input_Word_3
piTest -v Output_Word_1
piTest -v Output_Word_2
这些返回信息非常重要,以第一个为例,我们从一行一行分析。首先第一行,很显然,只是把我们的变量名返回来了;第二行,offset:11,意思是变量的偏移量是11,我们知道,Linux中万物皆文件,我们的这些RevPi变量也是存在文件中(具体来说,映像文件完整的路径为 /dev/piControl0 ),而变量的首字节所在地址,或者说,距离文件首字节的偏移量,就是这里的offset——11(字节)了;第三行,length: 16,此处长度单位是bit,由于Modbus的Holding Registers是16位寄存器,因此对应的存储变量也用的是16位长度;第四行,bit: 0,这其实是位偏移量,部分变量(比如DIO每通道的变量),length只有1位,那么此时就需要知道该比特是第几位,对于长度不为1的变量,位偏移量始终是0。
8、有了文件偏移量,也有文件路径,我们就可以通过标准的python文件IO来取出数据。同样以变量Input_Word_1为例,刚才我们知道了它的偏移量是11,长度是16位,因此我们需要做的是打开文件后,光标定位到11的位置,读取2个字节的长度(16位),然后把这两个字节按小端模式解析即可(所有变量值超过1字节的都是以小端模式存储)。读取完成后记得把文件关了,python代码如下:
f = open("/dev/piControl0","rb",0)
f.seek(11)
tempVar = int.from_bytes(f.read(2),byteorder='little',signed=False)
f.close()
print(tempVar)
9、我们已经成功用python取到RevPi变量的值,接下来,我们写OPC UA服务器的代码。其实整个代码,主要参考的是GitHub项目中,最小服务器的示例代码,源码链接:
https://github.com/FreeOpcUa/python-opcua/blob/master/examples/server-minimal.py
主要改动就是,我们需要多用几次add_variable,创建几个变量节点来放我们RevPi变量的值,然后在主循环中,定期进行文件IO,采样各个RevPi变量的当前值,然后把他赋值给对应的变量节点。完整源码如下,set_endpoint中的URL请改成自己RevPi所在的IP和想要使用的端口号,addrList中的变量偏移量,也请按实际情况修改:
......
剩余代码由于篇幅问题此处不放置,有需要者请联系虹科
工业物联网团队获取。
10、将以上代码复制到终端文件编辑器(比方说nano或者vi),命名保存成py脚本,比方说modbus2opcua.py,然后给该脚本加上执行权限,命令如下。
chmod +x modbus2opcua.py
而后即可执行该脚本,效果如图:
11、此时打开OPC UA客户端,本文以Matrikon OPC UA Explorer为例(该软件免费,可以联系广州虹科获取安装包),连接到树莓派创建的OPC UA server,并把变量添加进监视列表,此时即可访问到从Modbus读取来的数据。
12、此时,我们修改Modbus中的值,OPC UA客户端这边也能同步获取到变化后的值
13、var4和var5读取的是树莓派上次写入该变量的值,因此我们尝试在终端给var4写入一个新值,进行写入验证。
验证成功!
四. 总结
工业树莓派能帮助我们把不同的工业数据,以及IO点位的值,变成统一的工业树莓派变量。而我们要做的,实际上就是在创建OPC UA server之前,在地址空间内添加相应的变量节点,然后把工业树莓派变量的值和变量节点的值进行绑定即可。
Python的简便性,使得我们用五十行左右的源码,即可从零创建一个简单的OPC UA server,但是功能在很大程度上是受限的,各种节点的属性设置也不完整,而且python本身的运行效率和性能就较低,仅适用于少量点位、低速刷新的原理验证、个人学习等应用场合。
如果是在追求稳定和效率的实际工业生产环境中,笔者建议使用商业版的C/C++语言SDK,目前我们广州虹科有这样的商业版SDK在售,如有需要可与我们联系,该商业版SDK已成功通过交叉编译控制工程网版权所有,并通过了在虹科工业树莓派环境上的运行验证测试。