Serverside: How to identify variables within method IOManager::beginStopMonitoring

Questions regarding the use of the C++ SDK for Server or Client development or integration into customer products ...

Moderator: uasdkcpp

Post Reply
rothfussthomas
Jr. Member
Jr. Member
Posts: 3
Joined: 11 Jan 2012, 11:24

Serverside: How to identify variables within method IOManager::beginStopMonitoring

Post by rothfussthomas »

Hi,

I implemented an own node manager derived from NodeManagerBase. The methods

IOManager::beginTransaction
IOManager::finishTransaction
IOManager::beginStartMonitoring
IOManager::beginStopMonitoring

are overwritten. When the client monitors a variable the method beginStartMonitoring is called. By casting the pVariableHandle parameter it is possible to get the UaNode of the variable:

VariableHandleUaNode* pVariableHandleUaNode = dynamic_cast (pVariableHandle);
UaNode* pUaNode = pVariableHandleUaNode->pUaNode ();

When the client stops the monitoring for a variable the method beginStopMonitoring is called. The hIOVariable is used to identify the variable. But I cannot find a way to get the UaNode for this variable.

beginStopMonitoring is called by UaSubscription::beginDeleteMonitoredItems:

retItem = pUaMonitoredItemData->pIOManager()->beginStopMonitoring(
pIOManagerSubset->m_hIOManagerTransactionContext,
i+1,
pUaMonitoredItemData->hIOVariable());

The pUaMonitoredItemData (class UaMonitoredItemData) has the link information: m_hIOVariable and m_pVariableHandle

In the documentation of beginStopMonitoring there is mentioned that
"hIOVariable - The handle of the variable in the IOManager created with beginStartMonitoring. The handle was passed to the SDK in the callback finishStartMonitoring."

Is it possible to create an own IOManagerCallback on serverside?

So, how to identify variables within the method IOManager::beginStopMonitoring?

Thanks in advance
Thomas

User avatar
Support Team
Hero Member
Hero Member
Posts: 3072
Joined: 18 Mar 2011, 15:09

Re:Serverside: How to identify variables within method IOManager::beginStopMonitoring

Post by Support Team »

Hi Thomas,

The solution depends on your use case.

(1) You want do your own implementation of the Value attribute monitoring
In this case you should implement your own IOManager just for the Value attribute. The other attributes are handled by the default implementation.
You can provide your own IOManager by overwriting NodeManager::getVariableHandle(). You must check for the requested attribute. If the Value attribute is requested, you are providing your own IOManager and if not, you call the method of the base class.
Sample code for implementing an IOManager is provided in the COM DA Migration Example.
In this case the hIOVariable is created by your IOManager in IOManager::beginStartMonitoring(). It is a handle to your internal management object. You can store the UaNode pointer in this internal management object. With the handle hIOVariable you can find your internal management object in IOManager::beginStopMonitoring() and therefore also the UaNode pointer.

(2) You want to know when a Variable value is monitored to update the cache if at least one monitored item is created
In this case there is a specialized event provided by the IOManagerUaNode to get informed about monitoring changes for Variable Values. The event is IOManagerUaNode::variableCacheMonitoringChanged(). You get the variable passed in to the event and you can get the count of monitored items for this variable.

You can set your variable to a mode that forces the SDK to
- Call readValues only for Client Read operations
- Call writeValues on Client Write operations
- Use cache updated by application for monitoring

See attached sample code for setting the variable and processing the event.

Best Regards,
Unified Automation Support Team

Code: Select all

// Setting variable to special mode
pVariable->setValueHandling(UaVariable_Value_CacheIsSource | UaVariable_Value_CacheIsUpdatedOnRequest);


// MyNodeManager.h
 
void variableCacheMonitoringChanged(UaVariableCache* pVariable, TransactionType transactionType);
 
// MyNodeManager.cpp

void MyNodeManager::variableCacheMonitoringChanged(UaVariableCache* pVariable, TransactionType transactionType)
{
    if ( (transactionType == IOManager::MONITOR_BEGIN) && (pVariable->signalCount() == 1) && (pVariable->getUserData() != NULL) )
    {
        // The variable is now used by one subscription -> start updating the value
        MyUserData* pUserData = (MyUserData*)pVariable->getUserData();
        if ( pUserData )
        {
            // Do something
        }
    }

    if ( (transactionType == IOManager::MONITOR_STOP) && (pVariable->signalCount() == 0) && (pVariable->getUserData() != NULL) )
    {
        // The variable is not longer used by a subscription -> stop updating the value
        MyUserData* pUserData = (MyUserData*)pVariable->getUserData();
        if ( pUserData )
        {
            // Do something
        }
    }
}
Best regards
Unified Automation Support Team

Post Reply