12:59, EEST
August 23, 2022
Hi,
I managed to build both an UA Client and Server App, but some new questions arose.
1) How do I create a TUaVariant containing an array of values? There are only constructos/Create methods for basic types like boolean, integer, etc.
2) Does the SDK allow an application to be OPC UA Server and OPC UA Client simultaneously? I made a sample application which is both client and server, everything works well except when I make the client write a value. In this case the value is transferred to the server, but the client reports an error (timeout when writing attributes). I can see the updated value in the server, so it works at least partially.
15:42, EEST
December 21, 2011
Hi Guido,
Sounds good that you made progress!
1) You can create a normal Variant array and initialise TUaVariant with that. See the TUaCppSampleServerForm::CreateDynamicStructureValue() for some examples.
2) Yes, your application should be possible to act both as a server and a client at the same time. TUaCient depends on Windows messages, so you will need to make sure that for example Application->ProcessMessages() is called to make them handled, although I am not sure if the write call should depend on that. Do you have a normal or a service application?
16:10, EEST
August 23, 2022
Hello Jouni,
thanks for your quick response.
The application is a regular VCL Forms application, nothing fancy. The application is both OPC UA Server and OPC UA Client, with a couple of variables registered.
I have got these test cases:
1) Reading a variable using the TUaServer object: works
2) Writing a variable using the TUaServer object: works
3) Reading a variable from the server using the TUaClient object: works
4) Writing a variable to the server using the TUaClient object: fails
The exact error message is: “Failed to write attributes. StatusCode=Bad_Timeout (0x800A0000 – The operation timed out.)
However, if I start the test application twice and make one instance the server and the other the client, the client can write the variable successfully.
I noticed the SDK uses a lot of static variables and methods, is it possible there´s a conflcit when TUaServer and TUaClient use the same static variables?
12:34, EEST
December 21, 2011
Hi Guido,
I tried this out myself and writing to the Prosys OPC UA Simulation Server works fine.
I added ‘TUaClient UaClient1’ and ‘TButton Button1’ on the UaCppSampleServerForm and wrote the following event handlers in code:
{
if (!UaClient1->Connected)
{
UaServer->ApplicationIdentity->ApplicationDescription =
TUaApplicationDescription::Builder->Init(UaServer->ApplicationIdentity->ApplicationDescription)
->ApplicationType(atClientAndServer)
->Build();
UaClient1->ApplicationIdentity->Assign(UaServer->ApplicationIdentity);
UaClient1->Connect();
TargetNodeId = UaClient1->NamespaceTable->ParseNodeId("nsu=http://www.prosysopc.com/OPCUA/StaticNodes;s=DoubleAnalogItem");
MyLevel->OnValueChange = MyLevelChange;
}
UaClient1->WriteValue(TargetNodeId, TUaVariant::Create(((double) Random(1000))/1000));
Log("Write OK");
}
//—————————————————————————
void __fastcall TUaCppSampleServerForm::MyLevelChange(TObject *Sender, const TUaDataValue &DataValue)
{
UaClient1->WriteValue(TargetNodeId, DataValue);
}
These go to the header file:
void __fastcall MyLevelChange(TObject *Sender, const TUaDataValue &DataValue);
I also had to specify many types like ‘TUaVariable’ as ‘Prosysopc::Uaserver::TUaVariable’ due to the ambiguity with the respective client classes, unfortunately.
But, having done that, I have a button that I can click on the form and it writes to the server alright – and after that the simulation in MyLevel starts being reflected to the SimulationServer.
Also, if I switch Simulation Off and write from Prosys OPC UA Browser to MyLevel that gets copied to the Simulation Server’s DoubleAnalogItem (in StaticNodes folder) without any problems.
PS. Unfortunately, the code tag trims the lines incorrectly…
15:16, EEST
December 21, 2011
And the respective functionality in the Delphi UaSampleServer:
begin
if not UaClient1.Connected then
begin
UaServer.ApplicationIdentity.ApplicationDescription :=
TUaApplicationDescription.Builder.Init(UaServer.ApplicationIdentity.ApplicationDescription)
.ApplicationType(atClientAndServer)
.Build;
UaClient1.ApplicationIdentity.Assign(UaServer.ApplicationIdentity);
UaClient1.Connect;
TargetNodeId := UaClient1.NamespaceTable.ParseNodeId(‘nsu=http://www.prosysopc.com/OPCUA/StaticNodes;s=DoubleAnalogItem’);
MyLevel.OnValueChange := MyLevelChange;
end;
UaClient1.WriteValue(TargetNodeId, Random(1000)/1000);
Log(‘Write OK’);
end;
procedure TUaSampleServerForm.MyLevelChange(Sender: TObject; const DataValue:
TUaDataValue);
begin
UaClient1.WriteValue(TargetNodeId, DataValue);
end;
Seems like Delphi can resolve the types better so they don’t need namespace specifiers even when the client and server objects are used in the same file.
Just make sure that ‘ProsysOPC.UaClient’ is defined before ‘ProsysOPC.UaServer’ in the uses clause.
Most Users Ever Online: 1919
Currently Online:
18 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 734
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1523
Posts: 6449
Newest Members:
christamcdowall, redaahern07571, nigelbdhmp, travistimmons, AnnelCib, dalenegettinger, howardkennerley, Thomassnism, biancacraft16, edgardo3518Moderators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0
Administrators: admin: 1