读取和写入首先要创建一个variant,将读写的值和节点绑定,指定节点需要节点id和作用域id
void* CXNOpc::GetOpcValueNumberic(UA_UInt16 nsIndex, UA_UInt32 identifier, int Type, int& length)
{
UA_Variant *val = UA_Variant_new();
if(!ReadOpcNumberic(nsIndex, identifier, val))
{
*m_qOutLog << OutLogTime() << ": Fail to Read NoteId " << identifier << endl;
return NULL;
}
if(val->type == &UA_TYPES[UA_TYPES_STRING])
{
UA_Byte* value = (*(UA_String*)val->data).data;
length = (*(UA_String*)val->data).length;
return (void*)value;
}
if(val->type == &UA_TYPES[Type])
return val->data;
else
return NULL;
}
bool CXNOpc::SetOpcValueNumberic(UA_UInt16 nsIndex, UA_UInt32 identifier, int Type, void* value)
{
UA_Variant *myVariant = UA_Variant_new();
UA_Variant_setScalarCopy(myVariant, value, &UA_TYPES[Type]);
bool bret = WriteOpcNumberic(nsIndex, identifier, myVariant);
if(!bret)
*m_qOutLog << OutLogTime() << ": Fail to Write NoteId " << identifier << endl;
UA_Variant_delete(myVariant);
return bret;
}
bool CXNOpc::ReadOpcNumberic(UA_UInt16 nsIndex, UA_UInt32 identifier, UA_Variant *val)
{
UA_NodeId nodeId = UA_NODEID_NUMERIC(nsIndex, identifier);
UA_StatusCode retval = UA_Client_readValueAttribute(m_pClient,nodeId,val);
if(retval == UA_STATUSCODE_GOOD && UA_Variant_isScalar(val))
return true;
else
return false;
}
bool CXNOpc::WriteOpcNumberic(UA_UInt16 nsIndex, UA_UInt32 identifier, UA_Variant *myVariant)
{
if(!m_bIsConnect)
return false;
UA_NodeId nodeId = UA_NODEID_NUMERIC(nsIndex, identifier);
UA_StatusCode code = UA_Client_writeValueAttribute(m_pClient, nodeId, myVariant);
if (code != UA_STATUSCODE_GOOD)
return false;
else
return true;
}
添加监控首先要创建订阅,然后将监控与订阅绑定,注意的是 无论多少个订阅,新建了几个客户端,同样只能监控500个节点
bool CXNOpc::AddSubscription()
{
if(!m_bIsConnect)
return false;
//UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();//创建默认订阅请求命令
UA_CreateSubscriptionRequest request;
UA_CreateSubscriptionRequest_init(&request);
request.requestedPublishingInterval = 200.0;
request.requestedLifetimeCount = 10000;
request.requestedMaxKeepAliveCount = 10;
request.maxNotificationsPerPublish = 0;
request.publishingEnabled = true;
request.priority = 0;
UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(m_pClient, request, NULL, NULL, NULL);//向服务器请求订阅
m_subId = response.subscriptionId;
if(response.responseHeader.serviceResult == UA_STATUSCODE_GOOD)
{
*m_qOutLog << OutLogTime() << ": Create subscription succeeded, id " << m_subId << endl;
return true;
}
else
{
UA_Client_Subscriptions_deleteSingle(m_pClient, m_subId);
m_subId = -1;
return false;
}
}
bool CXNOpc::AddNumbericMonitor(UA_UInt16 nsIndex, vector<UA_UInt32> identifier, UA_Client_DataChangeNotificationCallback callback)
{
if(!m_bIsConnect)
return false;
if(!AddSubscription())
return false;
for(vector<UA_UInt32>::iterator it = identifier.begin(); it != identifier.end(); it++)
{
UA_NodeId nodeId = UA_NODEID_NUMERIC(nsIndex, *it);
UA_MonitoredItemCreateRequest monRequest = UA_MonitoredItemCreateRequest_default(nodeId);//创建监控单个节点请求命令
UA_MonitoredItemCreateResult monResponse = UA_Client_MonitoredItems_createDataChange(m_pClient,
m_subId, UA_TIMESTAMPSTORETURN_BOTH,
monRequest, NULL, callback, NULL);//订阅与监控绑定
if(monResponse.statusCode == UA_STATUSCODE_GOOD)
*m_qOutLog << OutLogTime() << ": Monitoring: " << monResponse.monitoredItemId << " Noteid: " << *it << endl;
else
{
*m_qOutLog << OutLogTime() << ": Error! Fail to add numberic id: " << *it << endl;
return false;
}
}
return true;
}
bool CXNOpc::StartMonitorTask()
{
m_bStatus = true;
return true;
}
bool CXNOpc::StopMonitorTask()
{
m_bStatus = false;
return true;
}
void CXNOpc::run()
{
while(m_bStatus)
{
if(m_bIsConnect)
{
UA_Client_runAsync(m_pClient, m_time);
}
}
}