Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

How to connect to SPS Siemens S7

More
15 Jul 2021 13:54 #9998 by support
Agreed, it all points to the OPC UA (Data Access part). And the EasyUAClient then, as you listed.

So we can continue forward... To avoid confusion, please describe the symptoms you mean by "the server throws a certificate at me" - the steps taken, and the observed behavior. I have solutions but need to be sure what is it we are dealing with.

Best regards

Please Log in or Create an account to join the conversation.

More
15 Jul 2021 13:30 #9997 by Götz Heinemann
Thank you, thank you, thank you,

now i understand. Sorry, that the PLC-People and me were totally confused.
So i have to use a Data-Access through OPC-UA.

That means i have to start here:
_EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));

First problem: After connecting, the server throws a certificate at me.
In the factory building, there is no security problem.
Is there any way to accept this certificate always (only in my program)?
Is there any way to set the Security level to "None" (only in my program"?

Best regards

Please Log in or Create an account to join the conversation.

More
15 Jul 2021 12:26 #9995 by support
I still do not understand this, sorry.

1)
If, by "DA", you mean OPC DA (COM-DCOM based), it is basically *impossible* that the server that resides directly the PLC supports it. OPC DA Servers can only run on Windows. So, there can be an OPC DA server that runs on Windows and connects to the PLC. Is that the case? If so, what have you used to verify that "... an access with DA... is much more stable on my PC."?

2)
The other meaning of DA (Data Access) may be the Data Access part of the OPC UA specification. That would be quite normal to use with OPC UA, in fact many times it does not even get mentioned. It is *this* that was meant in the picture from Siemens that you earlier posted. But, if that is what you want, then it is *still* OPC UA what you end up using. "DA" in OPC UA does *not* mean "OPC DA" - that is a different thing.

Regards

Please Log in or Create an account to join the conversation.

More
15 Jul 2021 12:12 #9994 by Götz Heinemann
OK, let's start new.

Hello, I have the following problem:
My PC (an IPC with Win7) shall read variables from a PLC (Siemens S7) via an OPC-UA-Server.
I.E.: "Root/Objects/SIMOTION/unit/RFID_Data_Interface.udt_oRFID_Data_1.Fabnummer"
In this variable i can find a string, which i need for further actions.

1. The OPC-UA-Server is programmed to allow access as UA and DA.
2. The OPC-UA-Server also allows an access with only "username" and "password", because it's a standalone in a factory without connection to the internet.

After testing several possiblilities, i would prefer an access with DA, because this is much more stable on my PC.
I hope, that it's possible

Best regards

Please Log in or Create an account to join the conversation.

More
14 Jul 2021 15:34 #9987 by support
I think we need to step back and ask what is it that you are trying or achieve, or what is the problem you are trying to solve by using the code pieces you have provided.
The immediate cause for the problem is the fact that the default value of UAEndpointDescriptor.CertificateAcceptancePolicy is null, so in fact the right approach syntax-wise is to create the UACertificateAcceptancePolicy object and assign it to UAEndpointDescriptor.CertificateAcceptancePolicy and then change its AcceptAnyCertificate (I apologize that I have not fully explained this in my last answer).

But, I am *not* telling you to do the above. Because it won't work in the end anyway. The UAEndpointDescriptor.CertificateAcceptancePolicy property is a leftover from earlier versions and the documentation tells:

DO NOT SET THIS PROPERTY. Currently, any non-null value different from the global settings will cause an
error upon connection to the endpoint, because endpoint-specific certificate acceptance policy cannot be
reliably implemented with the underlying UA stack.


So, what is it that you are trying or achieve, or what is the problem you are trying to solve by using the code pieces you have provided?

Regards

Please Log in or Create an account to join the conversation.

More
14 Jul 2021 13:29 #9985 by Götz Heinemann
Hello,

the exception error occurs if either:
_EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));
ClientPtr->InstanceParameters->gdsEndpointDescriptor->CertificateAcceptancePolicy->put_AcceptAnyCertificate(VARIANT_TRUE);

or:
_UAReadArgumentsPtr ReadArguments0Ptr(_uuidof(UAReadArguments));
ReadArguments0Ptr->EndpointDescriptor->CertificateAcceptancePolicy->AcceptAnyCertificate = VARIANT_TRUE;

Best regards

Please Log in or Create an account to join the conversation.

More
02 Jul 2021 09:42 - 15 Jul 2021 12:19 #9877 by support
Hello.

The UnauthorizedAccessException, most likely, has nothing to do with accessing OPC UA servers. It probably indicates a coding error - accessing a memory using an incorrect pointer. In single-operand calls such as Read/ReadValue, OPC errors are indicated by throwing OpcException (for OPC Classic) or UAException (for OPC UA), and nothing else. On which statement does the exception occur?

Furthermore:

If you just create instances of various "parameters" object and modify their value, there will be no effect. These objects must be "rooted" inside the EasyDAClient or EasyUAClient object. So instead of creating them, you would normally start with the EasyDAClient/EasyUAClient, get its properties such as InstanceParameters, and then the sub-property, and so on, until you get to the object you want to modify, and then you would make the "property put".

Best regards
Last edit: 15 Jul 2021 12:19 by support.

Please Log in or Create an account to join the conversation.

More
01 Jul 2021 12:19 #9871 by Götz Heinemann
Hello and thank you so far..

When i try to get access, i get an exception: results(1). Exception: 252 System.UnauthorizedAccessException: Zugriff verweigert (access denied)

I think i can avoid this in UA with either
_UACertificateAcceptancePolicyPtr UAcapPtr(__uuidof(UACertificateAcceptancePolicy));
VARIANT_BOOL pRetVal;
pRetVal = VARIANT_TRUE;
UAcapPtr->put_AcceptAnyCertificate(pRetVal);
UAcapPtr->AcceptAnyCertificate = VARIANT_TRUE;

or:
_EasyUASharedParametersPtr EUASPPtr(__uuidof(EasyUASharedParameters));
_EasyUAEngineParametersPtr EUAEPPtr(__uuidof(EasyUAEngineParameters));
EUAEPPtr->CertificateAcceptancePolicy->AcceptAnyCertificate = VARIANT_TRUE;
EUASPPtr->putref_EngineParameters(EUAEPPtr);

1. Do i need both or just one of them or do i need to take another way?

2. Is there a similiar possibility in OPC DA?

Best regards

Please Log in or Create an account to join the conversation.

More
22 Jun 2021 09:15 - 22 Jun 2021 09:15 #9806 by support
Hello.

The C++ examples source code on the Web is a direct copy of what is in the product (example projects). But, the example projects contains additional pieces that are not listed with each example on the Web - for example, the stdafx.h file with extra "includes". It is therefore not possible to copy the source code from the Web into any project and expect it to work right away - you also need to take care of the other missing pieces. I suppose this is the cause for the compilation errors you listed.

Regardless of that, there still seems to be some confusion about which OPC specification to use. My recap (but I might be wrong) is as this:
1. I think you cannot use OPC DA ("Classic", COM/DCOM based) because the PLC does not support it and you do not have a separate OPC DA server.
2. There is a chance that there is OPC XML-DA support available for the PLC, but that seems to be a separate license on the PLC side, and there is no indication you have that.
3. The PLC supports OPC UA. Therefore that's what you have to use.

I think you should verify the above with some documentation or somebody knowledgeable. If it is correct, then the source code you listed in your last post cannot be used at all, because it is for OPC DA (uses the EasyDAClient object), and the questions below it therefore make little sense. Yo would need to use OPC UA, and therefore the EasyUAClient object, and start from the examples that use the EasyUAClient object.

Best regards
Last edit: 22 Jun 2021 09:15 by support.

Please Log in or Create an account to join the conversation.

More
22 Jun 2021 08:14 #9804 by Götz Heinemann
Hello,
thank you for the given examples:
- opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...s%20of%20OPC%20UA%20Nodes.html
- opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...20nodes%20or%20attributes.html

But both are not compilable. The compiler stops in both examples at the line:
results.Attach(ClientPtr->ReadMultiple(&vArguments));

The error message is:
1>d:\projekte\draeger\safety\rfid-click\software2021\rfid-click\rfid-click\sps-client.cpp(285) : error C2664: 'OpcLabs_EasyOpcUA::_EasyUAClient::ReadMultiple': Konvertierung des Parameters 1 von 'ATL::CComVariant *__w64 ' in 'SAFEARRAY **' nicht möglich

Which means: A conversion from CComVariant* to SAFEARRAY** is not possible.
Because: vArgument is defined as:
CComVariant vArguments(arguments);
where as ReadMultiple is defined as:
SAFEARRAY * ReadMultiple (SAFEARRAY * * readArgumentsArray );


OK, the sample code from the software package is compilable:
int	CSPSClient::ReadSPSStartbits(void)
{
	int			retarg, ii, nlen, count;
	CString		cs, cs1;
 
	retarg = 0;
 
    //Initialize the COM library. Note: If you choose STA, you will be responsible for pumping messages.
    CoInitializeEx(NULL, COINIT_MULTITHREADED);
 
    // Instatiate the EasyOPC-DA client object
    _EasyDAClientPtr ClientPtr(__uuidof(EasyDAClient));
 
 
    _DAReadItemArgumentsPtr ReadItemArguments0Ptr(_uuidof(DAReadItemArguments));
	ReadItemArguments0Ptr->ServerDescriptor->MachineName = L"";
    ReadItemArguments0Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2";
    ReadItemArguments0Ptr->ItemDescriptor->ItemId = L"Demo.Ramp";
 
    _DAReadItemArgumentsPtr ReadItemArguments1Ptr(_uuidof(DAReadItemArguments));
	ReadItemArguments1Ptr->ServerDescriptor->MachineName = L"";
    ReadItemArguments1Ptr->ServerDescriptor->ServerClass = L"OPCLabs.KitServer.2";
    ReadItemArguments1Ptr->ItemDescriptor->ItemId = L"Demo.Single";
 
 
    CComSafeArray<VARIANT> ArgumentsArray(2);
    ArgumentsArray.SetAt(0, _variant_t((IDispatch*)ReadItemArguments0Ptr));
    ArgumentsArray.SetAt(1, _variant_t((IDispatch*)ReadItemArguments1Ptr));
 
    LPSAFEARRAY pArgumentsArray = ArgumentsArray.Detach();
    CComSafeArray<VARIANT> ResultArray;
	ResultArray.Attach(ClientPtr->ReadMultipleItems(&pArgumentsArray));
    ArgumentsArray.Attach(pArgumentsArray);
 
 
	count = 0;
 
    for (int i = ResultArray.GetLowerBound(0); i <= ResultArray.GetUpperBound(0); i++)
		{
		count++;
 
        _DAVtqResultPtr DAVtqResultPtr(ResultArray[i]);
 
		_ExceptionPtr ExceptionPtr(DAVtqResultPtr->Exception);
		if (ExceptionPtr != NULL)
			{
	        _variant_t exceptionAsString(ExceptionPtr->ToString);
			nlen = (int) _tcslen(OLE2T(exceptionAsString.bstrVal));
			if (nlen > 100) exceptionAsString.bstrVal[100] = 0;
			cs.Format(_T("results(%d). Exception: %d "), i, exceptionAsString.bVal);
			cs1 = OLE2T(exceptionAsString.bstrVal);
			cs += cs1.Left(50);
			CBlackboard::readerror = cs;
			retarg = 1;
			continue;
			}
 
        _DAVtqPtr DAVtqPtr(DAVtqResultPtr->Vtq);
        _variant_t vtqAsString(DAVtqPtr->ToString);
		cs = vtqAsString.bstrVal;
 
		switch (i)
			{
			case 0: for (ii=0; ii<10; ii++) CBlackboard::SPS2PC.FabDatum1[ii] = (char) cs[ii];
					CBlackboard::SPS2PC.FabDatum1[ii] = 0;						
					break;
			case 1: for (ii=0; ii<10; ii++) CBlackboard::SPS2PC.FabDatum2[ii] = (char) cs[ii];
					CBlackboard::SPS2PC.FabDatum2[ii] = 0;
					break;
 
			}
 
 
		}
 
	cs.Format(_T(" %u Daten gelesen"), count);
	CBlackboard::readresult = cs;
    // Release all interface pointers BEFORE calling CoUninitialize()
	ArgumentsArray.Destroy();
    ResultArray.Destroy();
	ClientPtr->UnsubscribeAllItems();
	ClientPtr.Release();
    ClientPtr = NULL;
 
    CoUninitialize();
 
 
	return retarg;
}

Since this works and does its job (in demo mode). I guess i have to start from here

Best regards

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.116 seconds