Linux/Windows下OPC ua -- 下

读取和写入首先要创建一个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);
        }
    }
}


猜你喜欢

转载自blog.csdn.net/qq_42956179/article/details/104763190