OPC Studio User's Guide and Reference
Examples - OPC Unified Architecture - Call multiple methods
View with Navigation Tools

.NET

// This example shows how to call multiple methods, and pass arguments to and
// from them.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// OPC client and subscriber examples in C# on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using System.Diagnostics;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    class CallMultipleMethods
    {
        public static void Main1()
        {

            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"
            UANodeDescriptor nodeDescriptor = "nsu=http://test.org/UA/Data/ ;i=10755";

            object[] inputs1 =
            {
                false, 
                1, 
                2, 
                3, 
                4, 
                5, 
                6, 
                7, 
                8, 
                9, 
                10
            };

            TypeCode[] typeCodes1 =
            {
                TypeCode.Boolean,
                TypeCode.SByte,
                TypeCode.Byte,
                TypeCode.Int16,
                TypeCode.UInt16,
                TypeCode.Int32,
                TypeCode.UInt32,
                TypeCode.Int64,
                TypeCode.UInt64,
                TypeCode.Single,
                TypeCode.Double
            };

            object[] inputs2 =
            {
                false, 
                1, 
                2, 
                3, 
                4, 
                5, 
                6, 
                7, 
                8, 
                9, 
                10,
                "eleven"
            };

            TypeCode[] typeCodes2 =
            {
                TypeCode.Boolean,
                TypeCode.SByte,
                TypeCode.Byte,
                TypeCode.Int16,
                TypeCode.UInt16,
                TypeCode.Int32,
                TypeCode.UInt32,
                TypeCode.Int64,
                TypeCode.UInt64,
                TypeCode.Single,
                TypeCode.Double,
                TypeCode.String
            };

            // Instantiate the client object
            var client = new EasyUAClient();

            // Perform the operation.
            ValueArrayResult[] results = client.CallMultipleMethods(new[]
            {
                new UACallArguments(endpointDescriptor, nodeDescriptor, 
                    "nsu=http://test.org/UA/Data/ ;i=10756", inputs1, typeCodes1),
                new UACallArguments(endpointDescriptor, nodeDescriptor, 
                    "nsu=http://test.org/UA/Data/ ;i=10774", inputs2, typeCodes2)
            });

            // Display results
            for (int i = 0; i < results.Length; i++)
            {
                Console.WriteLine();
                Console.WriteLine($"results[{i}]:");

                ValueArrayResult result = results[i];
                if (result.Succeeded)
                {
                    object[] outputs = result.ValueArray;
                    Debug.Assert(outputs != null);

                    for (int j = 0; j < outputs.Length; j++)
                        Console.WriteLine($"    outputs[{j}]: {outputs[j]}");
                }
                else
                    Console.WriteLine($"*** Failure: {result.ErrorMessageBrief}");
            }

            // Example output:
            //results[0]:
            //    outputs[0]: False
            //    outputs[1]: 1
            //    outputs[2]: 2
            //    outputs[3]: 3
            //    outputs[4]: 4
            //    outputs[5]: 5
            //    outputs[6]: 6
            //    outputs[7]: 7
            //    outputs[8]: 8
            //    outputs[9]: 9
            //    outputs[10]: 10

            //results[1]:
            //    outputs[0]: False
            //    outputs[1]: 1
            //    outputs[2]: 2
            //    outputs[3]: 3
            //    outputs[4]: 4
            //    outputs[5]: 5
            //    outputs[6]: 6
            //    outputs[7]: 7
            //    outputs[8]: 8
            //    outputs[9]: 9
            //    outputs[10]: 10
            //    outputs[11]: eleven
        }
    }
}

COM

// This example shows how to call multiple methods, and pass arguments to and from them.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

#include "stdafx.h"    // Includes "QuickOpc.h", and other commonly used files
#include <atlsafe.h>
#include "CallMultipleMethods.h"

namespace _EasyUAClient
{
    void CallMultipleMethods::Main()
    {
        // Initialize the COM library
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
        {
            CComSafeArray<VARIANT> inputs1(11);
            inputs1.SetAt(0, _variant_t(false));
            inputs1.SetAt(1, _variant_t(1));
            inputs1.SetAt(2, _variant_t(2));
            inputs1.SetAt(3, _variant_t(3));
            inputs1.SetAt(4, _variant_t(4));
            inputs1.SetAt(5, _variant_t(5));
            inputs1.SetAt(6, _variant_t(6));
            inputs1.SetAt(7, _variant_t(7));
            inputs1.SetAt(8, _variant_t(8));
            inputs1.SetAt(9, _variant_t(9));
            inputs1.SetAt(10, _variant_t(10));

            CComSafeArray<VARIANT> typeCodes1(11);
            typeCodes1.SetAt(0, _variant_t(TypeCode_Boolean));
            typeCodes1.SetAt(1, _variant_t(TypeCode_SByte));
            typeCodes1.SetAt(2, _variant_t(TypeCode_Byte));
            typeCodes1.SetAt(3, _variant_t(TypeCode_Int16));
            typeCodes1.SetAt(4, _variant_t(TypeCode_UInt16));
            typeCodes1.SetAt(5, _variant_t(TypeCode_Int32));
            typeCodes1.SetAt(6, _variant_t(TypeCode_UInt32));
            typeCodes1.SetAt(7, _variant_t(TypeCode_Int64));
            typeCodes1.SetAt(8, _variant_t(TypeCode_UInt64));
            typeCodes1.SetAt(9, _variant_t(TypeCode_Single));
            typeCodes1.SetAt(10, _variant_t(TypeCode_Double));
            CComVariant vTypeCodes1(typeCodes1);

            _UACallArgumentsPtr CallArguments1Ptr(__uuidof(UACallArguments));
            CallArguments1Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
                CallArguments1Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10755";
            CallArguments1Ptr->MethodNodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10756";
            CallArguments1Ptr->InputArguments = inputs1;
            CallArguments1Ptr->InputTypeCodes = vTypeCodes1;

            CComSafeArray<VARIANT> inputs2(12);
            inputs2.SetAt(0, _variant_t(false));
            inputs2.SetAt(1, _variant_t(1));
            inputs2.SetAt(2, _variant_t(2));
            inputs2.SetAt(3, _variant_t(3));
            inputs2.SetAt(4, _variant_t(4));
            inputs2.SetAt(5, _variant_t(5));
            inputs2.SetAt(6, _variant_t(6));
            inputs2.SetAt(7, _variant_t(7));
            inputs2.SetAt(8, _variant_t(8));
            inputs2.SetAt(9, _variant_t(9));
            inputs2.SetAt(10, _variant_t(10));
            inputs2.SetAt(11, _variant_t(L"eleven"));

            CComSafeArray<VARIANT> typeCodes2(12);
            typeCodes2.SetAt(0, _variant_t(TypeCode_Boolean));
            typeCodes2.SetAt(1, _variant_t(TypeCode_SByte));
            typeCodes2.SetAt(2, _variant_t(TypeCode_Byte));
            typeCodes2.SetAt(3, _variant_t(TypeCode_Int16));
            typeCodes2.SetAt(4, _variant_t(TypeCode_UInt16));
            typeCodes2.SetAt(5, _variant_t(TypeCode_Int32));
            typeCodes2.SetAt(6, _variant_t(TypeCode_UInt32));
            typeCodes2.SetAt(7, _variant_t(TypeCode_Int64));
            typeCodes2.SetAt(8, _variant_t(TypeCode_UInt64));
            typeCodes2.SetAt(9, _variant_t(TypeCode_Single));
            typeCodes2.SetAt(10, _variant_t(TypeCode_Double));
            typeCodes2.SetAt(11, _variant_t(TypeCode_String));
            CComVariant vTypeCodes2(typeCodes2);

            _UACallArgumentsPtr CallArguments2Ptr(__uuidof(UACallArguments));
            CallArguments2Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            CallArguments2Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10755";
            CallArguments2Ptr->MethodNodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10774";
            CallArguments2Ptr->InputArguments = inputs2;
            CallArguments2Ptr->InputTypeCodes = vTypeCodes2;

            CComSafeArray<VARIANT> arguments(2);
            arguments.SetAt(0, _variant_t((IDispatch*)CallArguments1Ptr));
            arguments.SetAt(1, _variant_t((IDispatch*)CallArguments2Ptr));
            CComVariant vArguments(arguments);

            // Instantiate the client object
            _EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));

            // Perform the operation
            CComSafeArray<VARIANT> results;
            results.Attach(ClientPtr->CallMultipleMethods(&vArguments));
    
            // Display results
            for (int i = results.GetLowerBound(); i <= results.GetUpperBound(); i++)
            {
                _tprintf(_T("\n"));
                _tprintf(_T("results(%d):\n"), i);
                _ValueArrayResultPtr ResultPtr = results[i];

                if (ResultPtr->Exception == NULL)
                {
                    CComVariant valueArray(ResultPtr->ValueArray);
                    CComSafeArray<VARIANT> outputs(valueArray.parray);
                    for (int j = outputs.GetLowerBound(); j <= outputs.GetUpperBound(); j++)
                    {
                        _variant_t output(outputs[j]);
                        _variant_t vString;
                        vString.ChangeType(VT_BSTR, &output);
                        _tprintf(_T("    outputs(d)s\n"), i, (LPCTSTR)CW2CT((_bstr_t)vString));
                    }
                }
                else
                    _tprintf(_T("*** Error: %s\n"), (LPCTSTR)CW2CT(ResultPtr->Exception->ToString));
            }
        }
         // Release all interface pointers BEFORE calling CoUninitialize()
        CoUninitialize();
    }
}

Python

# This example shows how to call multiple methods, and pass arguments to and
# from them.
#
# Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-OpcStudio/Latest/examples.html .
# OPC client and subscriber examples in Python on GitHub: https://github.com/OPCLabs/Examples-QuickOPC-Python .
# Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
# a commercial license in order to use Online Forums, and we reply to every post.
# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from System import *
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'
nodeDescriptor = UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10755')

#
inputs1 = [False, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
typeCodes1 = [
    TypeCode.Boolean,
    TypeCode.SByte,
    TypeCode.Byte,
    TypeCode.Int16,
    TypeCode.UInt16,
    TypeCode.Int32,
    TypeCode.UInt32,
    TypeCode.Int64,
    TypeCode.UInt64,
    TypeCode.Single,
    TypeCode.Double,
    ]

inputs2 = [False, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 'eleven']
typeCodes2 = [
    TypeCode.Boolean,
    TypeCode.SByte,
    TypeCode.Byte,
    TypeCode.Int16,
    TypeCode.UInt16,
    TypeCode.Int32,
    TypeCode.UInt32,
    TypeCode.Int64,
    TypeCode.UInt64,
    TypeCode.Single,
    TypeCode.Double,
    TypeCode.String,
    ]

# Instantiate the client object.
client = EasyUAClient()

# Perform the operation.
try:
    valueArrayResultArray = client.CallMultipleMethods([
        UACallArguments(endpointDescriptor, nodeDescriptor,
                        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10756'), inputs1, typeCodes1),
        UACallArguments(endpointDescriptor, nodeDescriptor,
                        UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10774'), inputs2, typeCodes2),
        ])
except UAException as uaException:
    print('*** Failure: ' + uaException.GetBaseException().Message)
    exit()

# Display results.
for i, valueArrayResult in enumerate(valueArrayResultArray):
    print()
    print('valueArrayResultArray[', i, ']:', sep='')
    if valueArrayResult.Succeeded:
        assert valueArrayResult.ValueArray is not None
        for j, outputValueArray in enumerate(valueArrayResult.ValueArray):
            print('    valueArray[', j, ']: ', outputValueArray, sep='')
    else:
        print('*** Failure: ', valueArrayResult.ErrorMessageBrief, sep='')

print()
print('Finished.')

 

See Also

Concepts