I'm facing a task which is to extract historical data from an OPC system, and then store these data into a standalone database for our BI team.
Although I'm a experienced developer, but I never use OPC UA before. I found the latest library provided by OPC Foundation here:
https://github.com/OPCFoundation/UA-.NETStandardLibrary
There is a sample console client app in this repo. However, I didn't find any clue for HDA (Historical Data Access). So, could anyone help out?
Also, I'm actually the only IT background person in my company. The manager told me that there is another guy who is maintaining the OPC system using some 3rd party application, so that I assume that it is not necessary to implement anything about the OPC server. In other words, I suppose I just need to implement an OPC client connecting to some URLs which can be found in that OPC application. Does my assumption correct?
To sum up, there are two questions:
How to implement an OPC UA Client to extract historical data with OPC UA-.NETStandardLibrary
Given that the current OPC system is running on top of a 3rd party application, does that mean I don't need to code anything about the "Server"?
Any help will be appreciated.
Unless you actually need to support .NET Standard, you should rather be looking at a different GitHub project: https://github.com/OPCFoundation/UA-.NET . Under SampleApplications/Samples/HistoryClient you should find what you need.
And yes, if the OPC UA server is in place, configured and running, your development task should be just to write an OPC UA client. You need to "know" about what data the server presents to you through OPC (or browse for it from the code), but you need not to know about the internal implementation of the server (its code).
Related
I have Siemens panel TP1200 Comfort in which there are many alarms.
I have used UAExpert to connect to the server, and I can navigate through the tags, but I am not able to see the way the to navigate to do it through the alarms.
My idea it is if I could subscribe to the alarms, so if I implement a OPC UA client with C#, I could handle it, send some email or save the data in a database.
For the client, I am trying to use the library from OPC Fundation: https://github.com/OPCFoundation/UA-.NETStandard.
Thanks.
Yes it is possible. The UAExpert can e.g. subscripte to events and alarms.
You can find the doc here
I think the .net stack also can do it because its the reference implementation in C# but I could not found an example.
Edit: Here is an Example for AlarmConditions UA-.NETStandard Alarm Condition Sample
I have a C# application that is running as an OPC client, with a Siemens S7-300 PLC as the device with which it needs to communicate over a DP coupler (profibus). I am using Siemens OPC Server running on a CPC to facilitate the communications, but in order to do this, I have to feed my application some OPC server information, including the Server Name and Server ProgID (which I've been told is also known as the CLSID?)
The goal is to be able to load my application onto the CPC, run it with the PLC connected to the CPC via profibus, and then have communication capabilities between software & PLC.
As a result of the research I've done so far, I have my Server Name set to localhost/OPC.SimaticNET.1 and the Server ProgID set to {B6EACB30-42D5-11D0-9517-0020AFAA4B3C} so that my actual OPC connection string looks like opcda://localhost/OPC.SimaticNET.1/{B6EACB30-42D5-11D0-9517-0020AFAA4B3C}but my program cannot read or write through the OPC server. Since I am using the DP couplers specifically, I am unsure if I should instead be using OPC.SimaticNET.DP.1 and its associated {5F30A70F-8256-4ee3-8FCD-A65CF62C25CA} CLSID. I have played around with both ideas, but neither seems to yield solid results.
What might I try to get my application to correctly communicate with the OPC server?
Is it possible to implement client/server communication between a C++ program (client program) running in linux OS with a C# program(server program) running in Windows using RMI implementation?Can anyone suggest any possible way...Any kind of helpful reference is welcome
You would need to go along the lines of Google Protobuf. It is available with C++ and C# as well.
A similar answer from MSDN
It does not matter if you send data from java,c++ or c#, when it goes
over the network it's just 1s and 0s. It's a matter of what you do
with it on the client/server side. So, be sure that the data that you
receive corresponds with the structure that you have (that you want to
deserialize to).
Sometimes you need to manually put the bits and bytes together to get
it all working out. However, there is something called "Protobuff"
that can help you get a common structure of the data that you send,
google it and read all about it.
You can implement client server with sockets and serialize/deserialize it using protobuf.
(MSDN link might help in solution)
I think message passing libraries would fit best in to this. Take a look at ZMQ for instance; they have binding for many languages found here
so you may have your event dispatcher in one language and listener in the other language. Also take a look at apache thrift
CORBA is one IPC mechanism that will provide the RPC mechanism that you are looking for.
Here is a link describing communication between C# server and JAVA client.
http://iiop-net.sourceforge.net/dnAdderRmiClient.html
At one of the companies I worked previously, it was used for communication between c++ and java programs in a client/server model.
They used a combination of ACE/TAO libraries.
http://www.cs.wustl.edu/~schmidt/TAO.html
I would recommend that you do not use remote method invocation for communication between a client and a server. In the nineteen-nineties we used to believe that RMI is a good idea, but since then we have realized that there are much better ways for communication between computers.
The most popular way is by using Web Services, and the easiest flavor of Web Services is RESTful Web Services. (Look them up.) This has the benefit of not caring at all whether the runtime environment of the client looks anything like the runtime environment of the server, as the case is with your setup, where your client is C++ on Linux and your server is C# on Windows.
Mozilla's XPCOM might be your bridge. There is also PyXPCOM. Realistically though the easiest way is to have an intermediate VBox. So you run a VBox instance (running Windows) on the linux machine and then use VBox API (from C++) to issue commands within VBox. So you end up with
Linux <--xpCom--> VBox <--COM--> Windows
When working over network it's protocol what matters, not the client/server.
In telecommunications, a communications protocol is a system of rules that allow two or more entities of a communications system to transmit information via any kind of variation of a physical quantity. These are the rules or standard that defines the syntax, semantics and synchronization of communication and possible error recovery methods.
Source Emphasis is mine.
So, in order to communicate your C++ client and C# server you need to choose or define protocol that will be used for communication.
Your protocol can be build above another protocol. For example, you can use HTTP for transportation purposes and define your protocol describing what syntax should be used for messages in HTTP requests and responses bodies. This will help you, because there're many ready-to-use solutions for HTTP communication.
Actually you will build your protocol based on another anyway. HTTP itself build above TCP. You'll need to choose whether it would be low level or high level protocols. They all have their pros and cons.
But you will have to deal with messaging between your client and server yourself.
As an alternative you can use some Remote Procedure Call(or RPC) solution:
Remote procedure call (RPC) is an inter-process communication that allows a computer program to cause a subroutine or procedure to execute in another address space (commonly on another computer on a shared network) without the programmer explicitly coding the details for this remote interaction.
So that means that you only have to follow guidelines how to build your client and server and all communication will be hidden and will look like as just calling object's method.
Source
Here's short list of possible RPC solutions:
Component Object Model with DCOM. Wiki: COM,DCOM. MSDN: COM, DCOM.
Simple Object Access Protocol. Wiki.
Windows Communication Foundation. Wiki. MSDN. SO(credits to Sanju for link).
To wrap it up:
It's not a problem that your client and server are in different environments and are developed using different platforms. You only have to build communications between them using either your own messaging system based on some protocol, or some RPC system.
We could just write a C# program to listen messages from a particular port and write another C++ client program to write message to that port.As thus we could communicate both application.
I am just learning c#, and am programming a Windows client that collects temperature data from the computer and needs to send it to a remote linux mySQL Database.
I was going to program it directly in the c# client, but I want to learn more ways to do this and gain experience. And programming it directly would be less secure and most likely require an extra connector.
Can any of you advise me of other ways, or ways you would do this?
Any way to program a C# program that acts as a web-service on my linux mySQL Server? Where should I look/search to learn more about this. Is it called something special? Or maybe its not done in C#?
Should I program a php script that accepts HTTP SEND/GET requests from my C# Desktop client?
Any other way?
What way is most 'professional' in the real world? Trying to learn on my own! :D
FORMAT:
Windows Desktop: client programmed in C# That retrieves temp data and needs to send to server
Linux Server: Runs Apache and mySQL Server with a database already setup. Closed to outside Connections
My advice is to set up a web service to communicate with your windows client. Directly connecting to mysql server is ok if they both resident in a same lan, but if not, for example your windows client is running on some laptop travelling everywhere or even the mysql server permits local incoming connection only, your should set up a web service. Also the http connection can usually go through firewalls while connections over other ports are blocked.
php is a good way to do this. Since you are learning c#, you may want to use c# to do the server side programming as well, so why not give a try of mono?
Directly exposing a MySQL Server to the internet is strongly dicouraged, Additionally this gives you a rather coarse-grained set of access rights, that might not be enough for your application, so running some sort of server app is the right way to go.
With mono you can run a lot of .Net (and thus C#) based code on a Linux server just fine. Rule of thumb is: If it doesn't have a Winforms GUI and no P/Invoke it will work just fine. Ofcourse this needs mono on the server, which is not given on most commercial hosts.
Running the server in PHP makes it a lot more portable, but has a performance overhead. Additionally it doesn't allow for some of your busines logic objects to be implemented in a DLL assembly and used on both sides.
As for the protocol: Chose your poison. Rule of thumb again is, that predefined protocols such as SOAP tend to need a bit more work (and more learning in the first go), but on the long term tend to be more robust.
For your special use-case I'd personally go with a quick PHP based solution where the protocol is just a simple GET with a few parameters, one being the temperature(s) and the others authenticating the client.
If the temperature sensor generates events, then I would 'push' the data from the Windows box to the Linux box - this will save the latter checking often and finding no updates. However if you are just taking temperature samples, I would 'pull' the data from the Linux machine. Either way, if you want to use HTTP you will need a web service on either side.
Alternatively, you could just connect to your MySQL database remotely from C#, and write the data directly (no web service would then be required). That might be the quickest way to get this working.
The 'which is professional' question is subjective - all three options above are fine. Just make the code clear and concise :)
I am developing OPC Client in windows C#. I have developed the code and reading
OPC Items on Sampling as well as event based (OnDataChange). When I am
working with local machine then my code works fine with both Sampling as well
as OnDataChange, but when I am trying to read data from Remote OPC Server
then Sampling works fine but I am not able fetch data on event based process.
I am able to connect to the OPC Server but when i am adding subscription to
it then i am getting error.
HRESULT : 0x80040202.
group1.DataChanged += new DataChangeEventHandler(this.DataChangeHandler);
group1.AdviseIOPCDataCallback();//exception HRESULT : 0x80040202.
OPC server connected & then register the group also but i got the exception when reading data.
The issue usually is that when you use Advise(), the server will make a DCOM connection back to the client (standard DCOM connection points). The client needs to be set up properly to allow this to happen (i.e. the right security settings to allow the server to execute code on the client).
You should read this page: http://www.softwaretoolbox.com/xpsp2/, it covers a lot of recommendations on how to set up DCOM properly for OPC usage. There are a lot of security concerns here. The Software Toolbox site has a lot of great information (and videos too). If you are still having trouble getting it to work, I recommend investing in an OPC tunneling product that will allow you to do remote OPC without having to jump through all the DCOM loops.
You don't have to be using OPCDA.NET to have the same issue. You can use any OPC client and get it working first with your remote server, then focus on figuring out how to get it all hooked up in OPCDA.NET. I recommend OPC Quick Client (comes with Software Toolbox TOP Server demo).
The problem you are actually having is with the callback. In other words, it isn't the advise call that is failing you, it is the callback from the OPC server (which advise triggers). This error is usually caused by user authentication problems (i.e. the user accounts do not match on both computers). Check out the OPC server's user account on the remote computer. If it doesn't exist on your local computer, you found the problem!
There is an automated application to help you figure out your problem. I recommend you download OPC Expert (Google it). It is a free application, does not require installation, and does not change Windows Registry. It has saved me many times. Also, the vendor (OPCTI) is extremely helpful, so check them out.
That problem is because when you connect to the server, you might use the first connect function, which is server.connect();
Instead, try:
server.connect(new Opc.ConnectData(new System.Net.NetworkCredential()));
This works for me. Hope it helps:)