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.

WriteValue with Delphi

More
07 Feb 2018 20:28 #5989 by support
Replied by support on topic WriteValue with Delphi
You are welcome :-)

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

More
07 Feb 2018 20:08 #5988 by alex2027
Replied by alex2027 on topic WriteValue with Delphi
This works perfectly now, thanks for all of your help with this :)

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

More
07 Feb 2018 18:58 #5986 by support
Replied by support on topic WriteValue with Delphi
I made a Delphi example for specifying the type explicitly. In COM, you need to use WriteMultipleValues instead of WriteValue (but you can use it with just one value if you need to).
// This example shows how to write values into 3 nodes at once, specifying a type code explicitly. It tests for success of
// each write and displays the exception message in case of failure.
//
// Reasons for specifying the type explicitly might be:
// - The data type in the server has subtypes, and the client therefore needs to pick the subtype to be written.
// - The data type that the reports is incorrect.
// - Writing with an explicitly specified type is more efficient.
//
// Alternative ways of specifying the type are using the ValueType or ValueTypeFullName properties.
 
class procedure WriteMultipleValues.ValueTypeCode;
var
  Arguments: OleVariant;
  Client: TEasyUAClient;
  I: Cardinal;
  WriteResult: _UAWriteResult;
  WriteValueArguments1, WriteValueArguments2, WriteValueArguments3: _UAWriteValueArguments;
  Results: OleVariant;
begin
  WriteValueArguments1 := CoUAWriteValueArguments.Create;
  WriteValueArguments1.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  WriteValueArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10221';
  WriteValueArguments1.Value := 23456;
  WriteValueArguments1.ValueTypeCode := TypeCode_Int32;    // here is the type explicitly specified
 
  WriteValueArguments2 := CoUAWriteValueArguments.Create;
  WriteValueArguments2.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  WriteValueArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;i=10226';
  WriteValueArguments2.Value := 'This string cannot be converted to Double';
  WriteValueArguments2.ValueTypeCode := TypeCode_Double;    // here is the type explicitly specified
 
  WriteValueArguments3 := CoUAWriteValueArguments.Create;
  WriteValueArguments3.EndpointDescriptor.UrlString := 'http://opcua.demo-this.com:51211/UA/SampleServer';
  WriteValueArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/;s=UnknownNode';
  WriteValueArguments3.Value := 'ABC';
  WriteValueArguments3.ValueTypeCode := TypeCode_String;    // here is the type explicitly specified
 
  Arguments := VarArrayCreate([0, 2], varVariant);
  Arguments[0] := WriteValueArguments1;
  Arguments[1] := WriteValueArguments2;
  Arguments[2] := WriteValueArguments3;
 
  // Instantiate the client object
  Client := TEasyUAClient.Create(nil);
 
  // Modify values of nodes
  TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(Client.WriteMultipleValues(
    PSafeArray(TVarData(Arguments).VArray)));
 
  // Display results
  for I := VarArrayLowBound(Results, 1) to VarArrayHighBound(Results, 1) do
  begin
    WriteResult := IInterface(Results[I]) as _UAWriteResult;
    if WriteResult.Succeeded then
      WriteLn('Result ', I, ' success')
    else
      WriteLn('Result ', I, ': ', WriteResult.Exception.GetBaseException.Message);
  end;
end;

This example works for set of basic types covered by the TypeCode enumeration. I suppose it will be sufficient for your application. There is also an option to specify other types, using the ValueTypeFullName property. If you end up needing that, let me know.

Best regards

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

More
07 Feb 2018 15:19 #5981 by alex2027
Replied by alex2027 on topic WriteValue with Delphi
Thanks, I will try and let them know.

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

More
07 Feb 2018 15:18 #5980 by support
Replied by support on topic WriteValue with Delphi
There is a documentation topic about it: opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...e%20in%20OPC%20UA%20Write.html

Looking at it, it does explain the concepts, but is missing some examples, especially for COM where the various overloads of WriteValue are not available. Please wait a little, and I will work on more documentation and some examples, and will let you know.

Also, I would be really grateful if you can report this problem to Siemens anyway, or if you know a way of doing so, let me know and I can try that myself.

Regards

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

More
07 Feb 2018 14:58 #5979 by alex2027
Replied by alex2027 on topic WriteValue with Delphi
It is a Sinumerik 840D, not sure on the firmware version thought.

I have just checked and even the inbuilt Siemens GUDs look the same.

How do I specify a type explicitly?

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

More
07 Feb 2018 14:18 - 07 Feb 2018 20:31 #5978 by support
Replied by support on topic WriteValue with Delphi
Here is the cause of the problem: The node is *not* a scalar. It is an array.
Its ValueRank attribute is 0, which is OneOrMoreDimensions. According to OPC UA (Vesrion 1.03) Part 3, Table 8, OneOrMoreDimensions denotes "The value is an array with one or more dimensions.".

In addition, its ArrayDimensions attribute is totally off (look at the picture you sent).

For the node to be scalar string, its ValueRank would have to be -1 (Scalar).

QuickOPC attempts to convert the value you provided to the data type of the variable. So, it tries to convert the string or decimal you pass to it to an array of something, but that fails, of course.

Either you need to write an array (which would be effectively impossible given the terribly huge number in ArrayDimensions), or the server actually expects a scalar, but is non-compliant and the vendor should fix it.

I understand this is an OPC Server in a Siemens PLC. Please let me know the PLC model and firmware version.

There may be a way around this by specifying a type explicitly in QuickOPC. Let me know if you want to pursue this way - but the non-compliance on the server part is fairly serious in my view, so that should be fixed first, because it can cause problems at other places too.

Best regards
Last edit: 07 Feb 2018 20:31 by support.

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

More
07 Feb 2018 14:01 #5977 by alex2027
Replied by alex2027 on topic WriteValue with Delphi
Sorry, the test one was renamed, it happens the same on this node (and all other nodes).

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

More
07 Feb 2018 14:00 #5976 by support
Replied by support on topic WriteValue with Delphi
That's not for the node you reported the problem with.

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

More
07 Feb 2018 13:43 #5974 by alex2027
Replied by alex2027 on topic WriteValue with Delphi
The attached is from UaExpert.
Attachments:

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

Moderators: support
Time to create page: 0.076 seconds