Tuesday 25 January 2022

OPC UA (A new standard Protocol for M2M)

Standard

What is OPC?

OPC: Open Platform Communication:

OPC is the interoperability standard for the secure and reliable exchange of data in the industrial automation space and in other industries. It is platform independent and ensures the seamless flow of information among devices from multiple vendors. The OPC Foundation is responsible for the development and maintenance of this standard.

Initially, the OPC standard was restricted to the Windows operating system. As such, the acronym OPC was borne from OLE (object linking and embedding) for Process Control. These specifications, which are now known as OPC Classic, have enjoyed widespread adoption across multiple industries, including manufacturing, building automation, oil and gas, renewable energy and utilities, among others.

When the standard was first released in 1996, its purpose was to abstract PLC specific protocols (such as Modbus, Profibus, etc.) into a standardized interface allowing HMI/SCADA systems to interface with a “middle-man” who would convert generic-OPC read/write requests into device-specific requests and vice-versa. As a result, an entire cottage industry of products emerged allowing end-users to implement systems using best-of-breed products all seamlessly interacting via OPC.

Communication Architecture before & after OPC:



For. e.g.








[For more, Reference: What is OPC? - OPC Foundation]


Various OPC Standards & their functions:


When examining the standards of OPC, OPC server / client terms should also be emphasized. OPC server (server); is a software application designed to work with one or more OPC features. OPC servers can be thought of as interpreters connecting the OPC environment with the devices’ local communication protocols or interfaces.

The task of the OPC server is to receive or send information to the device according to the commands of the OPC client. If it is an OPC client; are software used by an application to communicate with any compatible OPC server. OPC clients can be considered as a data-sink, as they carry out the initiation and control of communication with OPC servers. The OPC client sends communication requests to the OPC server.

Let's understand the data transmission between OPC Client & Server diagrammatically.



When data is returned from the OPC server, the OPC client converts this data to the local format in the application to be used; Thus, correct operation of the application is checked and ensured.

OPC servers can provide communication from one OPC client to another, and if we consider this in reverse, OPC clients can communicate with more than one OPC server at the same time.





Purpose of OPC Protocol:

The purpose of the initial creation of OPC was to read data from automation devices such as PLC / DCS. However, OPC interface is also available in software to be found in other data communications today.

What is OPC DA?

OPC Data Access is a group of clients–server standards that provides specifications for communicating real-time data from data acquisition devices such as PLCs to display and interface devices like Human–Machine Interfaces (HMI), SCADA systems and also ERP/MES systems. The specifications focus on the continuous communication of data.

OPC DA Data consists of:
  1. a value,
  2. the quality of the value, and
  3. a timestamp.

OPC DA Architecture:





What is OPC UA?

OPC UA is the next generation of OPC technology. It’s a more secure, open, reliable mechanism for transferring information between servers and clients. It provides more open transports, better security and a more complete information model than the original OPC DA (a.k.a. OPC Classic). It provides a very flexible and adaptable mechanism for moving data between enterprise-type systems and the kinds of controls, monitoring devices and sensors that interact with real-world data.

OPC UA uses scalable platforms, multiple security models, multiple transport layers and a sophisticated information model to allow the smallest dedicated controller to freely interact with complex, high-end server applications. It can communicate anything from simple downtime status to massive amounts of highly complex plant-wide information.

OPC UA Architecture:

OPC UA Implementation Diagram





OPC UA Features:

  • Scalability – It’s scalable and platform-independent. Both high-end servers and low-end sensors can support it. UA uses discoverable profiles to include tiny, embedded platforms as servers in a UA system.
  • A Flexible Address Space – The address space is organized around the concept of an object. Objects are entities that consist of variables and methods and provide a standard way for servers to transfer information to clients.
  • Common Transports and Encodings – It uses standard transports and encodings to ensure that connectivity can be easily achieved in both embedded and enterprise environments.
  • Security – It implements a sophisticated security model that ensures the authentication of clients and servers, the authentication of users and the integrity of their communication.
  • Internet Capability – It’s fully capable of moving data over the internet.
  • A Robust Set of Services – OPC UA provides a full suite of services for eventing, alarming, reading, writing, discovery and more.
  • Certified Interoperability – It certifies profiles such that connectivity between a client and server using a defined profile can be guaranteed.
  • A Sophisticated Information Model – It profiles more than just an object model. True Information is shared between clients and servers because of the way it connects objects.
  • Sophisticated Alarming and Event Management – UA provides a highly configurable mechanism for providing alarms and event notifications to interested Clients. The alarming and event mechanisms go well beyond the standard change-in-value type alarming found in most protocols.
  • Integration with Standard Industry-Specific Data Models – The OPC Foundation is working with several industry trade groups that define specific information models for their industries to support those information models within UA.
OPC UA vs OPC DA protocol:




Let's Start Working on Open Source OPC UA Client using Python:

Installation:

 Using Python PIP:

pip install opcua

For Ubuntu / Raspberry Pi / Any Debian System Terminal:

apt install python-opcua # Library
apt install python-opcua-tools # Command-line tools

Dependencies:

  • Python > 3.4: cryptographydateutillxml and pytz.
  • Python 2.7 or pypy < 3: you also need to install enum34trollius (asyncio), and futures (concurrent.futures), with pip for example.

These features are implemented & successfully working:

  • connection to server, opening channel, session
  • browsing and reading attributes value
  • getting nodes by path and nodeids
  • creating subscriptions
  • subscribing to items for data change
  • subscribing to events
  • adding nodes
  • method call
  • user and password
  • history read
  • login with certificate
  • communication encryption
  • removing nodes
These features are not implemented yet:

  • localized text feature
  • XML protocol
  • UDP
  • maybe automatic reconnection...

Tested servers: freeopcua C++, freeopcua Python, prosys, kepware, beckhoff, winCC, B&R.


Code to Connect to OPC Server:

import sys
sys.path.insert(0, "..")
import logging
import time

try:
    from IPython import embed
except ImportError:
    import code

    def embed():
        vars = globals()
        vars.update(locals())
        shell = code.InteractiveConsole(vars)
        shell.interact()


from opcua import Client
from opcua import ua


class SubHandler(object):

    """
    Subscription Handler. To receive events from server for a subscription
    data_change and event methods are called directly from receiving thread.
    Do not do expensive, slow or network operation there. Create another 
    thread if you need to do such a thing
    """

    def datachange_notification(self, node, val, data):
        print("Python: New data change event", node, val)

    def event_notification(self, event):
        print("Python: New event", event)


if __name__ == "__main__":
    logging.basicConfig(level=logging.WARN)
    #logger = logging.getLogger("KeepAlive")
    #logger.setLevel(logging.DEBUG)

    client = Client("opc.tcp://localhost:4840/freeopcua/server/")
    # client = Client("opc.tcp://admin@localhost:4840/freeopcua/server/") #connect using a user
    try:
        client.connect()
        client.load_type_definitions()  # load definition of server specific structures/extension objects

        # Client has a few methods to get proxy to UA nodes that should always be in address space such as Root or Objects
        root = client.get_root_node()
        print("Root node is: ", root)
        objects = client.get_objects_node()
        print("Objects node is: ", objects)

        # Node objects have methods to read and write node attributes as well as browse or populate address space
        print("Children of root are: ", root.get_children())

        # get a specific node knowing its node id
        #var = client.get_node(ua.NodeId(1002, 2))
        #var = client.get_node("ns=3;i=2002")
        #var = client.get_node("ns=2;g=1be5ba38-d004-46bd-aa3a-b5b87940c698")
        #print(var)
        #var.get_data_value() # get value of node as a DataValue object
        #var.get_value() # get value of node as a python builtin
        #var.set_value(ua.Variant([23], ua.VariantType.Int64)) #set node value using explicit data type
        #var.set_value(3.9) # set node value using implicit data type

        # gettting our namespace idx
        uri = "http://examples.freeopcua.github.io"
        idx = client.get_namespace_index(uri)

        # Now getting a variable node using its browse path
        myvar = root.get_child(["0:Objects", "{}:MyObject".format(idx), "{}:MyVariable".format(idx)])
        obj = root.get_child(["0:Objects", "{}:MyObject".format(idx)])
        print("myvar is: ", myvar)

        # subscribing to a variable node
        handler = SubHandler()
        sub = client.create_subscription(500, handler)
        handle = sub.subscribe_data_change(myvar)
        time.sleep(0.1)

        # we can also subscribe to events from server
        sub.subscribe_events()
        # sub.unsubscribe(handle)
        # sub.delete()

        # calling a method on server
        res = obj.call_method("{}:multiply".format(idx), 3, "klk")
        print("method result is: ", res)

        embed()
    finally:
        client.disconnect()



Code to Connect to Kepware OPCUA Server:


import sys
sys.path.insert(0, "..")
import logging

from opcua import Client


class SubHandler(object):

    """
    Client to subscription. It will receive events from server
    """

    def datachange_notification(self, node, val, data):
        print("Python: New data change event", node, val)

    def event_notification(self, event):
        print("Python: New event", event)


if __name__ == "__main__":
    #from IPython import embed
    logging.basicConfig(level=logging.WARN)
    client = Client("opc.tcp://192.168.56.100:49320/OPCUA/SimulationServer/")
    #client = Client("opc.tcp://192.168.56.100:4840/OPCUA/SimulationServer/")
    #client = Client("opc.tcp://olivier:olivierpass@localhost:53530/OPCUA/SimulationServer/")
    try:
        client.connect()
        root = client.get_root_node()
        print("Root is", root)
        print("childs of root are: ", root.get_children())
        print("name of root is", root.get_browse_name())
        objects = client.get_objects_node()
        print("childs og objects are: ", objects.get_children())


        tag1 = client.get_node("ns=2;s=Channel1.Device1.Tag1")
        print("tag1 is: {0} with value {1} ".format(tag1, tag1.get_value()))
        tag2 = client.get_node("ns=2;s=Channel1.Device1.Tag2")
        print("tag2 is: {0} with value {1} ".format(tag2, tag2.get_value()))

        handler = SubHandler()
        sub = client.create_subscription(500, handler)
        handle1 = sub.subscribe_data_change(tag1)
        handle2 = sub.subscribe_data_change(tag2)

        from IPython import embed
        embed()

        
        sub.unsubscribe(handle1)
        sub.unsubscribe(handle2)
        sub.delete()
    finally:
        client.disconnect()
For More Code Examples & reference, please refer to this link: python-opcua/examples at master · FreeOpcUa/python-opcua · GitHub

1 comment:

  1. Are you looking information on how to fund a home based business? Here is what you need to know. From risky business to power couple partnership, discover why couples everywhere are learning the secrets to running a successful business together while deepening their relationship. Find out why couple entrepreneurs are building the lifestyle of their dreams and protecting their assets and how you can too, by starting a business, growing your relationship and learning to achieve success together. Human Design Reading

    ReplyDelete