Python通过DCOM调用实现OPC DA访问

写在最前面

Python、工业4.0、大数据等如此火热,难得闲下来数小时,用Python实现下OPC DA Client玩儿玩儿吧。

工具

1.kepserver 作为OPC DA 服务端

2.Python 3.7 

3.OPC DA COM组件即opcdaauto.dll

开始

1.创建keyserver测试工程,这里就不多讲了直接上图。测试而已,所以只加了一个变量。

 2.如果机器没注册opcdaauto.dll Com组件,注册COM。方法为:

1)以管理员方式打开命令行

2)输入regsvr32 + 路径+opcdaauto.dll

3.上面工作准备完成后开始测试喽,很简单的。

1)首先引入必要包

2)拿到OPC DA组件

3)获取OPCServer实例

opcserver = dll.OPCServer()

4)测试一下枚举检测到的OPC DA Server

for svr in opcserver.GetOPCServers():
    print (svr)

因为我电脑只装了一个kepserver 6,所以结果如下图

5)连接

opcserver.Connect('KEPware.KEPServerEx.V6')

6)拿到组实例

groups=opcserver.OPCGroups
groups.DefaultGroupIsActive = True
groups.DefaultGroupDeadband = 0
groups.DefaultGroupUpdateRate = 200

7)添加组,并订阅回调事件

group = DispatchWithEvents(groups.Add('Group1'),GroupEvent)
group.IsActive = True
group.IsSubscribed = True
group.UpdateRate = 100

8)添加需要操作的条目

item1 = "T1.T1.Tag1"
item=items.AddItem(item1,1)
item.IsActive = True
myItems[1]=item

9)测试读写

a=0
b=0
c=0
d=0
item.Read(win32com.client.constants.OPCDevice,b,c,d)

# write a new value
item.Write(100)

item.Write(111)

item.Write(120)

#read item value
item.Read(win32com.client.constants.OPCDevice,b,c,d)

10)搞一个消息循环,不然订阅无法正常触发。这个问题卡了我挺长时间

root = Tk()

#root.withdraw()   # 隐藏窗口
root.mainloop()  # 消息循环

11)断开连接

opcserver.Disconnect()

12)别忘记回调函数注册

                def OnDataChange(unknow,TransactionID,NumItems,ClientHandles,ItemValues,Qualities,TimeStamps):               
                    i=0
                    print("callback")
                    while(i<NumItems):                       
                        handle = ClientHandles[i]
                        value = ItemValues[i]
                        quality = Qualities[i]
                        time = TimeStamps[i]
                        print("item:%s , value:%s , quality:%s , time:%s ",myItems[handle],value,quality,time)
                        i=i+1

结果:

经测试,读、写、订阅均没问题。

简单封装下就可以项目中使用了呦。

虽然现在UA是趋势,但是DA也得会用哒。

看看测试截图吧

  • 5
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 43
    评论
Utgard 是一个Java库,用于连接 OPC DA 服务器,如果你想在Linux环境下使用C++调用Utgard库访问OPC DA服务器,你需要使用Java Native Interface(JNI)。 以下是一些步骤: 1.首先,在Linux系统上安装Java Development Kit(JDK)。 2.然后创建一个Java类来连接OPC DA服务器并实现所需的功能。 3.编译Java类并生成一个Java动态链接库(.so文件)。 4.在C++代码中使用JNI调用Java动态链接库。 下面是一个简单的示例: Java类: ```java import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.core.JIVariant; import org.jinterop.dcom.core.JIString; import org.openscada.opc.lib.common.ConnectionInformation; import org.openscada.opc.lib.da.Item; import org.openscada.opc.lib.da.ItemState; import org.openscada.opc.lib.da.Server; import org.openscada.opc.lib.da.SyncAccess; public class OPCClient { public static void main(String[] args) throws Exception { // connect to an OPC DA server ConnectionInformation ci = new ConnectionInformation(); ci.setHost("localhost"); ci.setUser("user"); ci.setPassword("password"); ci.setClsid("B3AF0BF6-4C0C-4804-A122-6F3B160F4397"); Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor()); // create an item and read its value Item item = server.getItemManager().getItem("Random.Int1"); SyncAccess syncAccess = new SyncAccess(server, 1000); syncAccess.addItem(item); syncAccess.bind(); ItemState itemState = item.read(syncAccess.getTransactionId()).get(); JIVariant jiVariant = itemState.getValue(); int value = jiVariant.getObjectAsInt(); System.out.println(value); // write a value to the item item.write(new JIVariant(new JIString("new value"))); // disconnect from the server server.dispose(); } } ``` 编译Java类并生成一个Java动态链接库: ```bash javac -cp .:utgard.jar OPCClient.java javah -classpath .:utgard.jar -jni OPCClient gcc -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -o libOPCClient.so OPCClient.c -L. -lutgard ``` C++代码: ```c++ #include <jni.h> int main() { JavaVM *jvm; JNIEnv *env; JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_8; vm_args.nOptions = 0; vm_args.ignoreUnrecognized = JNI_FALSE; JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args); jclass cls = env->FindClass("OPCClient"); jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); jobjectArray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), NULL); env->CallStaticVoidMethod(cls, mid, args); jvm->DestroyJavaVM(); } ``` 在编译C++代码时需要链接utgard库和jni库,如下所示: ```bash g++ -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -L. -lutgard -ljvm -o main main.cpp ``` 注意:以上示例仅演示了如何使用JNI调用Java动态链接库,具体的OPC DA连接实现需要根据自己的需求进行编写。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值