Вопрос

I am using Interop.OPCAutomation.DLL (OPC DA Automation Wrapper 2.02) and connecting with a Kepware server which is configured to talk to some remote I/O. The client handles communication just fine when everything is working, but isn't smart enough to tell if the connection is lost (the machine's Ethernet cable has been unplugged, etc.)

I am guessing that my only choice for getting Remote I/O status will be to subscribe to ConnectedGroup_DataChange and monitor OPC Item quality information, but is there a more simple way? Something like "-ping- hello remote I/O, are you still there?"

Similarly, I need a way to check if the server is alive or even exists (-ping- are you there server?) As it stands, I don't have any kind of handshaking and my client connects to the server with two simple lines:

ConnectedOPCServer = New OPCAutomation.OPCServer
ConnectedOPCServer.Connect(OPCServerName, OPCNodeName)

I have created a function to return the server state but always seems to return 1, even after I've exited KEPServerEX. EDIT: I found out that exiting the program doesn't actually close the server. Using Process explorer from the sysinternals suite I found the server and suspended it. Doing so made my application hang on the .Connect line. Getting the server state is impossible until I'm actually connected, so how can I check if the server is there before trying to connect?

Public Function GetServerState() As String
    Dim state As String = ConnectedOPCServer.ServerState.ToString
    Return state
End Function

Update

Thought I would share the relevant piece of the final project. I ended up writing a new Interop.OPCAutomation dll wrapper class in C#.

Because of the COM object nature of the OPCAutomation dll, if anything goes wrong with the communication it throws exceptions. Thus, I've implemented exception catching for every function in the OPC communication class. I look for specific error messages and take action accordingly.
It beats crashing the application for something dumb that can be easily recovered from.
For ServerState, I don't even care what the message is so I don't catch the exception object.

Here's my status function:

public bool GetServerState()
{
    try
    {
        int state = ConnectedOPCServer.ServerState;
        return true;
    }
    catch
    {
        // If server is unavailable, exception is thrown.
        CrossThreadLoggingEvent(
            Properties.Resources.MSG_Error_OPC08, optional_Lvl:3);
        return false; 
    }
}

As you can see I don't bother to do anything with 'int state' because it will always return "1", or throw an exception.

Since I'm doing all OPC communication on a thread, I've implemented a thread-safe way to report logging events back to the main thread.

That's it. Hope it helps someone.

Это было полезно?

Решение

If the server is installed and configured properly, it will start automatically, when you access it (or it may always be running as service). So unless the server is not installed or does not properly start up, you will always get access to it and it will respond with "Running" status to GetServerStatus. If it's not installed, you cannot get the server object.

You can monitor the connection to the data source only through OPC Items, via a sync read or data change callbacks.

Другие советы

The server object should have a 'GetServerStatus' method that you can periodically call. If that call fails, or the server returns a status that indicates a problem, then you may not be getting data.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top