基于Open62541的OPCUA注册读写

基于Open62541库开发的OpcUa采集程序,找遍了全网都没有关于OpcUa注册读写方法的例子,在此分享关键代码如下,具体代码实例请按照自己开发需求进行完善:

UA_Client* client;
vector<UA_NodeId> nodeIdList;
vector<UA_NodeId> registerNodeIdList;
vector<UA_ReadValueId> readNodeIdList;

//UA_Client如何初始化及连接在此就不介绍了,网上有其他技术博客相关代码例子,请自己查找

//初始化
void Init()
{
    int nsIndex, char* addr;
    nsIndex = 1;
    addr = "test1";
    UA_NodeId nodeId1 = UA_NODEID_STRING(nsIndex, addr);
    UA_NodeId dstNodeId;
    /***重点1:如果用以上方法初始化NodeId,须用以下方法进行深拷贝后才能将NodeId放到集合里
    ,否则放进去后NodeId会失效***/
	UA_NodeId_copy(&nodeId1, &dstNodeId);  
	nodeIdList.push_back(dstNodeId);
    
    
    UA_NodeId nodeId2;
    addr = "test2";
    /***重点2:或者通过以下方法初始化NodeId放进集合里***/
    UA_NodeId nodeId2 = UA_NODEID_STRING_ALLOC(nsIndex, addr);
    nodeIdList.push_back(nodeId2);
}


//注册节点
void RegisterNodes()
{
	UA_RegisterNodesRequest request;
	UA_RegisterNodesRequest_init(&request);

	request.nodesToRegister = &nodeIdList[0];
	request.nodesToRegisterSize = nodeIdList.size();
	UA_Client_renewSecureChannel(client);
	UA_RegisterNodesResponse response = UA_Client_Service_registerNodes(client, request);
	UA_StatusCode retval = response.responseHeader.serviceResult;
	if (retval == UA_STATUSCODE_GOOD)
	{
		if (response.registeredNodeIdsSize != nodeIdList.size())
		{
			UA_RegisterNodesResponse_clear(&response);
			return;
		}
	}


	for (int i = 0; i < response.registeredNodeIdsSize; i++)
	{
		UA_ReadValueId readNode;
		UA_ReadValueId_init(&readNode);
		readNode.attributeId = UA_ATTRIBUTEID_VALUE;
		UA_NodeId nodeId = response.registeredNodeIds[i];
		UA_NodeId dstNodeId;
		UA_NodeId_copy(&nodeId, &dstNodeId);
		readNode.nodeId = dstNodeId;
		registerNodeIdList.push_back(dstNodeId);
        readNodeIdList.push_back(readNode);
		
	}

	UA_RegisterNodesResponse_clear(&response);
}

//读取节点数据
void ReadNodeValues()
{
   UA_ReadRequest request;
   UA_ReadRequest_init(&request);
   request.nodesToRead = &readNodeIdList[0];
   request.nodesToReadSize = readNodeIdList.size();
   
   /***重点3:必须通过以下方法更新通道,否则不能正确读取注册后的节点数据***/
   UA_Client_renewSecureChannel(client);
		
   UA_ReadResponse response = UA_Client_Service_read(client, request);
   UA_StatusCode retval = response.responseHeader.serviceResult;
   if (retval == UA_STATUSCODE_GOOD)
   {
	  if (response.resultsSize != readNodeIdList.size())
	  {
		 UA_ReadResponse_clear(&response);
		 return;
	  }
   }

   for (int i = 0; i < readNodeIdList.size(); ++i)
   {
	  UA_DataValue *p = response.results;
	  if (p != NULL)
	  {
		 if (response.results[i].status == UA_STATUSCODE_GOOD)
		 {
			UA_DataValue res = response.results[i];
			if (!res.hasValue) // no value
			{
				continue;
			}

            UA_Variant m_value;
			memcpy(&m_value, &res.value, sizeof(UA_Variant));
			UA_Variant_init(&res.value);

			double val = 0;
	        string dataType = m_value.type->typeName;
	        if (m_value.type == &UA_TYPES[UA_TYPES_FLOAT])
	        {
		        UA_Float *p = (UA_Float *)m_value.data;
		        val = *p;
	        }
	        else if (m_value.type == &UA_TYPES[UA_TYPES_BOOLEAN])
	        {
		        UA_Boolean *p = (UA_Boolean *)m_value.data;
		        if (*p == UA_FALSE)
		        {
			        val = 0;
		        }
		        else
                {
			        val = 1;
		        }
	        }
	        else if (m_value.type == &UA_TYPES[UA_TYPES_INT16])
	        {
		        UA_Int16 *p = (UA_Int16 *)m_value.data;
		        val = *p;
		    }
            else if...

           //将读取到的数值放到相应数据字典里后续用吧
           ...
	   }

	}

    UA_ReadResponse_clear(&response);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值