LGPL Pure Python OPC-UA Client and Server

Overview

Pure Python OPC UA / IEC 62541 Client and Server Python 2, 3 and pypy. http://freeopcua.github.io/, https://github.com/FreeOpcUa/python-opcua

Build Status Scrutinizer Code Quality Code Coverage Codacy Badge Code Climate

PyPI Package

The library is in maintenance mode. The plan is now to focus on the asyncio version of this library: opcua-asyncio which also has a sync-wrapper, with very few changes in API

PR to fix bugs to python-opcua are welcome, but if you want to write new fancy features or architectural changes, please look at opcua-asyncio

Why asyncio? because it makes code easier to read and safer(read: less chances for bugs) and since python is monoprocess it might even be faster. It is also a good timing to remove all Python2 code

OPC UA binary protocol implementation is quasi complete and has been tested against many different OPC UA stacks. API offers both a low level interface to send and receive all UA defined structures and high level classes allowing to write a server or a client in a few lines. It is easy to mix high level objects and low level UA calls in one application.

Most low level code is autogenerated from xml specification, thus adding missing functionality to client or server is often trivial.

coverage.py reports a test coverage of over 95 % of code, most of non-tested code is autogenerated code that is not used yet.

Installation

With pip (note: the package was ealier called freeopcua)

pip install opcua

Ubuntu:

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

Dependencies:

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

Documentation

Some documentation is available on ReadTheDocs.

A simple GUI client is available: https://github.com/FreeOpcUa/opcua-client-gui

Examples: https://github.com/FreeOpcUa/python-opcua/tree/master/examples

Minimal client example: https://github.com/FreeOpcUa/python-opcua/blob/master/examples/client-minimal.py Minimal server example: https://github.com/FreeOpcUa/python-opcua/blob/master/examples/server-minimal.py

A set of command line tools also available: https://github.com/FreeOpcUa/python-opcua/tree/master/tools

  • uadiscover (find_servers, get_endpoints and find_servers_on_network calls)
  • uals (list children of a node)
  • uahistoryread
  • uaread (read attribute of a node)
  • uawrite (write attribute of a node)
  • uacall (call method of a node)
  • uasubscribe (subscribe to a node and print datachange events)
  • uaclient (connect to server and start python shell)
  • uaserver (starts a demo OPC UA server)
    tools/uaserver --populate --certificate cert.pem --private_key pk.pem

How to generate certificate: https://github.com/FreeOpcUa/python-opcua/tree/master/examples/generate_certificate.sh

Client

What works:

  • 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

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

Not implemented yet:

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

Server

What works:

  • creating channel and sessions
  • read/set attributes and browse
  • getting nodes by path and nodeids
  • autogenerate address space from spec
  • adding nodes to address space
  • datachange events
  • events
  • methods
  • basic user implementation (one existing user called admin, which can be disabled, all others are read only)
  • encryption
  • certificate handling
  • removing nodes
  • history support for data change and events

Tested clients: freeopcua C++, freeopcua Python, uaexpert, prosys, quickopc

Not yet implemented:

  • more high level solution to create custom structures
  • UDP
  • session restore
  • alarms
  • XML protocol
  • views
  • localized text features
  • better security model with users and password

Running a server on a Raspberry Pi

Setting up the standard address-space from XML is the most time-consuming step of the startup process which may lead to long startup times on less powerful devices like a Raspberry Pi. By passing a path to a cache-file to the server constructor, a shelve holding the address space will be created during the first startup. All following startups will make use of the cache-file which leads to significantly better startup performance (~3.5 vs 125 seconds on a Raspberry Pi Model B).

Development

Code follows PEP8 apart for line lengths which should be max 120 characters and OPC UA structures that keep camel case from XML definition.

All protocol code is under opcua directory

  • opcua/ua contains all UA structures from specification, most are autogenerated
  • opcua/common contains high level objects and methods used both in server and client
  • opcua/client contains client specific code
  • opcua/server contains server specific code
  • opcua/utils contains some utilities function and classes
  • opcua/tools contains code for command lines tools
  • schemas contains the XML and text files from specification and the python scripts used to autogenerate code
  • tests contains tests
  • docs contains files to auto generate documentation from doc strings
  • examples contains many example files
  • tools contains python scripts that can be used to run command line tools from repository without installing

Running tests:

./run-tests.sh

Coverage

coverage run tests.py
coverage html
firefox htmlcov/index.html
Comments
  • History support  server side

    History support server side

    Hey,

    first of all, awesome work guys! I am really happy this project exists :+1:

    In the last days I was using the opc ua server for some monitoring of energy usage. Now, I got to the point that I can not report any errors which occurred while reading the energy stats in the opc ua server. As I understand it, reporting events like errors right now in OPC UA only work using the subscription or history method.

    As I do only want to connect once a day to the opc ua server, i discarded the subscription method. (band with / data usage reasons)

    What do you think? Is there any plan or idea how to implement the history function for the opc ua server?

    If I would get a better understanding and some help, maybe I could also start working on it.

    opened by plieningerweb 61
  • Fix history_sql.py emitting node is not the source - sql error

    Fix history_sql.py emitting node is not the source - sql error

    changes:

        def save_event(self, event):
            with self._lock:
                _c_sub = self._conn.cursor()
    
                table = self._get_table_name(event.SourceNode) #Emitting node is not always the Source (event.SourceNode)
                columns, placeholders, evtup = self._format_event(event) #from event_prop_dict
                event_type = event.EventType  # useful for troubleshooting database
    
                # insert the event into the database
                try:
                    _c_sub.execute(
                        'INSERT INTO "{tn}" ("_Id", "_Timestamp", "_EventTypeName", {co}) VALUES (NULL, "{ts}", "{et}", {pl})'
                        .format(tn=table, co=columns, ts=event.Time, et=event_type, pl=placeholders), evtup)
    
                except sqlite3.Error as e:
                    self.logger.error('Historizing SQL Insert Error for events from %s: %s', event.SourceNode, e)
    
                self._conn.commit()
    
                # get this node's period from the period dict and calculate the limit
                period = self._datachanges_period[event.SourceNode]
    
                if period:
                    # after the insert, if a period was specified delete all records older than period
                    date_limit = datetime.utcnow() - period
    
                    try:
                        _c_sub.execute('DELETE FROM "{tn}" WHERE Time < ?'.format(tn=table),
                                       (date_limit.isoformat(' '),))
                    except sqlite3.Error as e:
                        self.logger.error('Historizing SQL Delete Old Data Error for events from %s: %s',
                                          event.SourceNode, e)
    
                    self._conn.commit()
    
    opened by AndreasHeine 43
  • [Server/Noob Question] How do I get methods to work in my custom types?

    [Server/Noob Question] How do I get methods to work in my custom types?

    Hello!

    I recently started working on OPC UA and Python, so I'm still trying to wrap my head around most things, so please, bear with me. This might be a pretty stupid question, but I just can't get it right, so I need to ask anyway - how do I get methods to work in my custom types?

    Here's a short the example, based on the "server-minimal" example:

    smoothexample

    Whenever I call the method via Test Client, it always returns "BadNothingToDo". But I know this method works just fine! If I add it to an object, like the SmoothSample above, the method runs successfully when called by the client. But that can't be the only solution, right? I know I'm doing something wrong...

    Please help me out!

    Daniel

    opened by stillero 28
  • WhereClause support

    WhereClause support

    I finally tok some time to understand WhereClause stuff. WhereClause is clearly the correct way to filter by event type

    Here is a first implementation to setup where clause from client when subscribing to events.

    • this is not finished, we should have a recursive option to subscrive_events
    • Need parsing of WhereClause on server, but this might be a bit complex...
    opened by oroulet 28
  • opc ua client: get value very slow

    opc ua client: get value very slow

    Hey guys,

    I am currently building a small program with which I use the opcua client to retrieve data from a controller and write it to a database.

    The data retrieval is very slow, can you please tell me where my error is? The entire For grinding process takes almost 2 seconds.

    thank you very much

    `import sys
    sys.path.insert(0, "..")
    
    
    #import opcua und mysql libs
    from opcua import Client
    from opcua import ua
    from opcua import *
    import mysql.connector
    #import Time libs
    import datetime
    import time
    #import multiprocesses
    import multiprocessing
    from threading import Timer
    
    import logging
    logging.basicConfig()
    #logging.basicConfig(level=logging.DEBUG)
    
    #def worker():
    #    """worker function"""
    #    print('Worker')
    
    def sec():
        """worker function"""
        sekunde = 0
    
        clientSec = Client("opc.tcp://"+login+ip+":"+port,timeout=10)
        try:
            clientSec.connect()
            connectionSec = mysql.connector.connect(host=host,database=db,port=dbPort,user=userdb,password=pwdb)
            cursorSec = connectionSec.cursor()
            # Get UA nodes in root
            root = clientSec.get_root_node()
            print("Client Sec connected")
    
            while 1:
                #time.sleep(1)
                t=time.time()
                while 1:
                    if time.time()-t > 1:
                        print(time.time())
                        print('sec')
                        sekunde = sekunde +1
                        print(sekunde)
                        for P in range(PWU):
                            for S in range(STR):
                                for M in range(MDL):
                                    
                                    var = clientSec.get_node("ns=6;s=::AsGlobalPV:BCS.PWU["+str(P)+"].STR["+str(S)+"].MDL["+str(M)+"].iVoltTotal")
                                    #Time = var.get_data_value().SourceTimestamp
                                    iVoltTotal = round(var.get_value(),6)
    
                                    var = clientSec.get_node("ns=6;s=::AsGlobalPV:BCS.PWU["+str(P)+"].STR["+str(S)+"].MDL["+str(M)+"].iCurrTotal")
                                    #Time = var.get_data_value().SourceTimestamp
                                    iCurrTotal = round(var.get_value(),6)
    
                                    var = clientSec.get_node("ns=6;s=::AsGlobalPV:BCS.PWU["+str(P)+"].STR["+str(S)+"].MDL["+str(M)+"].iSoc")
                                    #Time = var.get_data_value().SourceTimestamp
                                    iSoc = round(var.get_value(),3)
    
                                    Datum_Zeit = datetime.datetime.now()
    
                                    
                                    #cursorSec = connectionSec.cursor()
                                    cursorSec.execute("INSERT INTO Pwu"+str(P)+"Strang"+str(S)+"Modul"+str(M)+" (Zeit,iVoltTotal,iCurrTotal,iSoc) VALUES (%s,%s,%s,%s)",(Datum_Zeit,iVoltTotal,iCurrTotal,iSoc))
                                    #cursorSec.close()
                                    connectionSec.commit()
                        t=time.time()                
        finally:
            clientSec.disconnect()
            connectionSec.close()
    
    
    def min1():
        """worker function"""
        while 1:
            time.sleep(60)
            print('min1')
        
    
    def min5():
        """worker function"""
        
        while 1:
            time.sleep(60*5)
            print('min5')
    
    def sub():
        """worker function"""
        
        while 1:
            time.sleep(60)
            print('sub')
    
    
    #Hauptframework
    if __name__ == '__main__':
        jobs = []
        x=0
       #zugangsdaten
        
        #OpcUA
        ip      =   "10.96.7.10"
        port    =   "4840"
        login   =   "*****:****@"
        #MariaDB
        host    =   '10.96.7.245'
        db      =   'OpcUA'
        dbPort  =   '3307'
        userdb  =   '*****'
        pwdb    =   '*****'
        
        #Parameter
        PWU = 1   
        STR = 7
        MDL = 1
        #Variablen erstellen
        P = 0
        S = 0
        M = 0
        #maridB connect
        connection = mysql.connector.connect(host=host,database=db,port=dbPort,user=userdb,password=pwdb)
        print("Tabellen erzeugen")
        for P in range(PWU):
            for S in range (STR):
                for M in range (MDL):
                    cursor = connection.cursor()
                    cursor.execute("CREATE TABLE IF NOT EXISTS Pwu"+str(P)+"Strang"+str(S)+"Modul"+str(M)+"(id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,Zeit varchar(23),iTempMin0 float(4),iTempMin1 float(4),iTempMax0 float(4),iTempMax1 float(4),iTempCellAvg float(4),iVoltTotal float(6),iCurrTotal float(6),iSoc int(3))")
                    #Alle Tabellen löschen:
                    #cursor.execute("DROP TABLE Pwu"+str(P)+"Strang"+str(S)+"Modul"+str(M))
                    cursor.close()
                    print(P,S,M)
        
        #OpcUA Verbindung aufbauen
        client = Client("opc.tcp://"+login+ip+":"+port,timeout=10)
        #client = Client("opc.tcp://[email protected]:4840") #connect using a user
        try:
            client.connect()
    
            # Get UA nodes in root
            root = client.get_root_node()
    
            print("client connected")
            OPCtrue = client.get_node("ns=6;s=::AsGlobalPV:OPCtrue")
    
            #öffnen der einzelnen Prozesse
            for x in range(1):
                #Sekundne Prozess
                secjob = multiprocessing.Process(target=sec)
                jobs.append(secjob)
                secjob.start()
                #1 Minuten Prozess
                min1job = multiprocessing.Process(target=min1)
                jobs.append(min1job)
                min1job.start()
                #5 min Prozess
                min5job = multiprocessing.Process(target=min5)
                jobs.append(min5job)
                min5job.start()
                #Substription Prozess
                subjob = multiprocessing.Process(target=sub)
                jobs.append(subjob)
                subjob.start()
        finally:
            client.disconnect()
            connection.close()
            print("ENDE")    
    `
    
    opened by badsmoke 26
  • Using FreeOpcUa for OPC DA server

    Using FreeOpcUa for OPC DA server

    Hi all,

    I have a OPC DA server running on it. I have tested it on windows with client software and is working fine. I need make an application which will connect to this OPC DA server from linux. Is it possible to use this FreeOPCUA python for DA. Is this library compatible with OPC DA.

    Thanks

    opened by abhinavrawat27 26
  • No name 'ua' in module 'opcua'

    No name 'ua' in module 'opcua'

    Hello, I have install opcua but when I use this code by Visual Code (Python 3.8.2 32bit) from opcua import Client,ua I get the problem

    No name 'ua' in module 'opcua' (no-name-in-module) image

    How can I fix it ?

    opened by xuplus6493 24
  • High load problem

    High load problem

    Hello, recently I've noticed that under pretty high load the python-opcua periodically throws errors:

    ERROR:opcua.server.binary_server_asyncio:Exception raised while parsing message from client, closing
    Traceback (most recent call last):
      File "/home/user/_dev/python-opcua/opcua/server/binary_server_asyncio.py", line 85, in _process_data
        ret = self.processor.process(hdr, buf)
      File "/home/user/_dev/python-opcua/opcua/server/uaprocessor.py", line 73, in process
        msg = self._connection.receive_from_header_and_body(header, body)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 592, in receive_from_header_and_body
        return self._receive(chunk)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 623, in _receive
        self._check_incoming_chunk(msg)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 550, in _check_incoming_chunk
        self._security_token.ChannelId))
    UaError: Wrong channel id 113, expected 180
    ('Cleanup client connection: ', ('127.0.0.1', 43833))
    
    ERROR:opcua.server.binary_server_asyncio:Exception raised while parsing message from client, closing
    Traceback (most recent call last):
      File "/home/user/_dev/python-opcua/opcua/server/binary_server_asyncio.py", line 85, in _process_data
        ret = self.processor.process(hdr, buf)
      File "/home/user/_dev/python-opcua/opcua/server/uaprocessor.py", line 73, in process
        msg = self._connection.receive_from_header_and_body(header, body)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 592, in receive_from_header_and_body
        return self._receive(chunk)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 623, in _receive
        self._check_incoming_chunk(msg)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 550, in _check_incoming_chunk
        self._security_token.ChannelId))
    UaError: Wrong channel id 113, expected 181
    ('Cleanup client connection: ', ('127.0.0.1', 43834))
    
    ERROR:opcua.server.binary_server_asyncio:Exception raised while parsing message from client, closing
    Traceback (most recent call last):
      File "/home/user/_dev/python-opcua/opcua/server/binary_server_asyncio.py", line 85, in _process_data
        ret = self.processor.process(hdr, buf)
      File "/home/user/_dev/python-opcua/opcua/server/uaprocessor.py", line 73, in process
        msg = self._connection.receive_from_header_and_body(header, body)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 592, in receive_from_header_and_body
        return self._receive(chunk)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 623, in _receive
        self._check_incoming_chunk(msg)
      File "/home/user/_dev/python-opcua/opcua/ua/uaprotocol_hand.py", line 550, in _check_incoming_chunk
        self._security_token.ChannelId))
    UaError: Wrong channel id 113, expected 182
    ('Cleanup client connection: ', ('127.0.0.1', 43835))
    

    After each such error the server shuts down and restarts.

    Currently I have around 140 datapoints (mostly double and int64) in 12 folders and they are updated inside python script every 0.5 seconds. The client (Prosys Java SDK based client) queries all the datapoints around each second. What is the issue and how to solve it? Thanks.

    opened by ghost 24
  • BadWriteNotSupported error with latest version (0.98.5) only

    BadWriteNotSupported error with latest version (0.98.5) only

    Dear all, I have an issue with the latest version of python-opcua. All versions up to 0.98.3 work fine, but with version 0.98.5 I get the following error:

    Traceback (most recent call last):
      File "./client_example_minimal.py", line 23, in <module>
        var.set_value(True) # set node value using implicit data type
      File "/usr/lib/python3.7/site-packages/opcua/common/node.py", line 211, in set_value
        self.set_attribute(ua.AttributeIds.Value, datavalue)
      File "/usr/lib/python3.7/site-packages/opcua/common/node.py", line 257, in set_attribute
        result[0].check()
      File "/usr/lib/python3.7/site-packages/opcua/ua/uatypes.py", line 233, in check
        raise UaStatusCodeError(self.value)
    opcua.ua.uaerrors._auto.BadWriteNotSupported: The server does not support writing the combination of value, status and timestamps provided.(BadWriteNotSupported)
    

    This is the code that generates the error (taken by the client-minimal example):

    #!/usr/bin/python3
    
    import sys
    sys.path.insert(0, "..")
    
    from opcua import Client
    
    if __name__ == "__main__":
    
        client = Client("opc.tcp://localhost:4840")
        try:
            client.connect()
    
            # get a specific node knowing its node id
            var = client.get_node("ns=4;s=MAIN.OutletTLSC.CloseCMD")
            #var = client.get_node("ns=4;s=MAIN.ConditionAutoClose.sGiveHour")
    
            #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(True) # set node value using implicit data type
    
        finally:
            client.disconnect()
    

    I hope you can help me run the latest version of the software. Thank you.

    opened by fcep 23
  • [Server] Import XML and generate namespace

    [Server] Import XML and generate namespace

    Hi,

    I am currently working with several companion specifications and trying to load them via server.import_xml(filename). Since the companion standards use the namespaceId 1 in their spec, the xml import always tries to import exactly in the defined namespace index that is given in the file instead of in the namespace index which must be generated by the server on startup.

    As I read this it seems that the "correct" way is:

    1. Load UA namespace (ns:0)
    2. Create custom namespace (ns:1) -> server.register_namespace(uri)
    3. Load XML File and translate the nodes given in the xml file to correct namespace (ns:2)
    4. Load XML File and translate the nodes given in the xml file to correct namespace (ns:3)

    The order of the Uri elements in <NameSpaceUris> should determine the file local namespace indexes:

        <NamespaceUris>
            <Uri>http://somemodel.org</Uri>
            <Uri>http://anothermodel.org/</Uri>
        </NamespaceUris>
    

    Then in the XML file, references to ns=1;i=... must be translated to the the index of the first uri, i.e. http://somemodel.org while nodes reference to ns=2;i=... must be translated to the index of the second uri.

    The index of the uris must be managed by the server, i.e. the order of loading models determines the namespace index.

    Since I am a novice in OPC, I hope I described the scenario correct. Just wondering how other handle this scenario.

    opened by maljac 23
  • Caching fixes

    Caching fixes

    Bring back dump and load to do their original function and add methods for caching.

    These serve different purposes. load and dump: just dump the entire address space to binary and then reload it cache: tries to speed up loading default address space, it doesn't support saving custom nodes and has other drawbacks; for example you can't delete nodes if using the cache

    Also added isession.close() to the server stop code. This ensures all clean up is done, including the deletion of internal subscriptions (required for dumping address space)

    opened by zerox1212 22
  • Not receiving event after subscribe

    Not receiving event after subscribe

    Describe the bug
    i've used the client-event example to subscribe to node to get the events, the only difference is that i didn't pass the event type when i use the subscribe_event

    To Reproduce

    sys.path.insert(0, "..")
    
    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.tools import uals
    
    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 event_notification(self, event):
            print("New event recived: ", event)
    
    
    if __name__ == "__main__":
    
        client = Client("opc.tcp://192.168.0.5:8119/")
        try:
            client.connect()
    
            # 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)
    
            # Now getting a variable node using its browse path
            obj  = client.get_node('ns=2;s=Notification/Messages')
            print("Objects node is: ", obj)
    
            msclt = SubHandler()
            sub = client.create_subscription(100, msclt)
            handle = sub.subscribe_events(obj)
    
            embed()
            sub.unsubscribe(handle)
            sub.delete()
        finally:
            client.disconnect()
    

    Expected behavior
    wiev print New event recived: ... but getting nothing

    Version
    Python-Version:3.8.6
    python-opcua Version (e.g. master branch, 0.9): 0.98.9

    opened by Darkmagister 16
  • History Read Error

    History Read Error

    I am reading several nodes from opcua server. No issues reading single variable values using self.opcua.get_value(nodes) but when I trying to read history values I get an error "History Read Error: 'ExtensionObject' Object has no attribute 'DataValues'. Verified on UAExpert that the history data is available for the node of interest. Python version 3.10.2 on mac.

    code:

    starttime = "21.11.2022 08:09:09" starttime_dt_format = datetime.datetime.strptime(starttime,"%d.%m.%Y %H:%M:%S")
    endtime = "21.11.2022 08:15:09" endtime_dt_format = datetime.datetime.strptime(endtime,"%d.%m.%Y %H:%M:%S")
    thisnode = self.opcua.client.get_node("ns=2;s=OPCNode.TSInt32Random") data = await thisnode.read_raw_history(starttime=starttime_dt_format, endtime=endtime_dt_format, numvalues=20) #<-- This line returns error

    MicrosoftTeams-image (4)

    opened by sprasoon 1
  • Implementation of security ID check

    Implementation of security ID check

    I'm using python opcua server and client and I'm testing all the possible security features about authentication and communication. As the specs says, there is no implementation about security ID check, then even if I call the method set_security_ID, anonymous connections are still accepted. Is there a way to implement security ID check on a python opcua server ? Any suggestions ?

    opened by fcarli3 5
  • Client can't get notification until method complete

    Client can't get notification until method complete

    Describe the bug

    [What I do]

    1. Create an UA server with a method that can trigger an event

    2. Create UA clientA which register the event.

    3. Create clientB and use it to trigger event by call ua method.

    [ISSUE]

    • I found when I use another ua clientB to call UA_method_for_trigger_event, the event_notification in clientA will executed until UA_method_for_trigger_event complete.

    • Is there any way to let client get notification immediately, while event_generator trigger signal

    [Simple example code are as follows:]

    [server.py]

        def UA_method_for_trigger_event():   # <====== Suppose this is an UA method in UA server.
            event_generator.trigger(message="")
            time.sleep(30)
    

    [clientA.py]

        class UASubscriber(object):
            def __init__(self):
               pass 
    
            def event_notification(self, event):
                # Will execute until  'UA_method_for_trigger_event ' in server complete   <====== ISSUE
                data = event.get_event_props_as_fields_dict()
                print("data = ", data)
    

    Expected behavior

    Is there any way to let client get notification while event_generator.trigger event_generator.trigger singal

    Version

    python 3.8

    opened by frinklai 10
  • Normal connection -> Communication ends after about 1 hour!!  Anyone who knows the exception information below

    Normal connection -> Communication ends after about 1 hour!! Anyone who knows the exception information below

    I succeeded in connecting Siemens CPU through OPC-UA communication. (Attach the code below) However, after a certain period of time, it is terminated after an exception occurs as shown below. Anyone who knows why please help me

    ########################### My Code from opcua import Client import logging import time from datetime import datetime

    url = "opc.tcp://10.27.176.101:4840"

    client = Client(url) client.set_user("OpcUaClient") client.set_password("12345678") client.connect()

    while True: ____try: ________ rst = client.get_node("ns=2;s=/Channel/Spindle/driveLoad[1]")
    ________ print(rst.get_value()) ________print('#==================#') ________time.sleep(0.05) ____except(TimeoutError): ________print('-------------------------------------timeout') ________ print(str(TimeoutError)
    ________continue

    ############################### exception information ERROR:opcua.client.ua_client.Socket:Protocol Error Traceback (most recent call last): File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\ua_client.py", line 101, in _run self._receive() File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\ua_client.py", line 112, in _receive msg = self._connection.receive_from_socket(self._socket) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\connection.py", line 363, in receive_from_socket return self.receive_from_header_and_body(header, ua.utils.Buffer(body)) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\connection.py", line 328, in receive_from_header_and_body self._check_sym_header(security_header) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\connection.py", line 276, in _check_sym_header self.next_security_token.TokenId)) opcua.ua.uaerrors._base.UaError: Invalid security token id 6, expected 5 or 0 ERROR:opcua.client.ua_client.Socket:Protocol Error Traceback (most recent call last): File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\ua_client.py", line 101, in _run self._receive() File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\ua_client.py", line 112, in _receive msg = self._connection.receive_from_socket(self._socket) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\connection.py", line 363, in receive_from_socket return self.receive_from_header_and_body(header, ua.utils.Buffer(body)) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\connection.py", line 335, in receive_from_header_and_body return self._receive(chunk) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\connection.py", line 366, in _receive self._check_incoming_chunk(msg) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\connection.py", line 311, in _check_incoming_chunk .format(self._peer_sequence_number, num)) opcua.ua.uaerrors._base.UaError: Wrong sequence 3061 -> 3063 (server bug or replay attack) Traceback (most recent call last): File "test.py", line 45, in Exception in thread Thread-2: Traceback (most recent call last): File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\threading.py", line 916, in _bootstrap_inner self.run() File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\client.py", line 68, in run val = server_state.get_value() File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\node.py", line 153, in get_value result = self.get_data_value() File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\node.py", line 162, in get_data_value return self.get_attribute(ua.AttributeIds.Value) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\node.py", line 273, in get_attribute result = self.server.read(params) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\ua_client.py", line 337, in read data = self._uasocket.send_request(request) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\ua_client.py", line 83, in send_request data = future.result(self.timeout) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\concurrent\futures_base.py", line 434, in result raise TimeoutError() concurrent.futures._base.TimeoutError logWrite(str(rst.get_value()))

    File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\node.py", line 153, in get_value result = self.get_data_value() File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\node.py", line 162, in get_data_value return self.get_attribute(ua.AttributeIds.Value) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\common\node.py", line 273, in get_attribute result = self.server.read(params) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\ua_client.py", line 337, in read data = self._uasocket.send_request(request) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\site-packages\opcua\client\ua_client.py", line 83, in send_request data = future.result(self.timeout) File "C:\Users\jm0902.kim\AppData\Local\Programs\Python\Python36\lib\concurrent\futures_base.py", line 434, in result raise TimeoutError() concurrent.futures._base.TimeoutError

    opened by zeroche72 1
Owner
Free OPC-UA Library
Open Source C++ and Python OPC-UA Libraries
Free OPC-UA Library
Client library for relay - a service for relaying server side messages to the client side browsers via websockets.

Client library for relay - a service for relaying server side messages to the client side browsers via websockets.

getme 1 Nov 10, 2021
Pywbem - A WBEM client and related utilities, written in pure Python.

Pywbem - A WBEM client and related utilities, written in pure Python Overview Pywbem is a WBEM client and WBEM indication listener and provides relate

PyWBEM Projects 39 Dec 22, 2022
league-connection is a python package to communicate to riot client and league client

league-connection is a python package to communicate to riot client and league client.

Sandbox 1 Sep 13, 2022
A TCP Chatroom built with python and TCP/IP sockets, consisting of a server and multiple clients which can connect with the server and chat with each other.

A TCP Chatroom built with python and TCP/IP sockets, consisting of a server and multiple clients which can connect with the server and chat with each other. It also provides an Admin role with features including kicking and baning of users.

null 3 May 22, 2022
A simple DHCP server and client simulation with python

About The Project This is a simple DHCP server and client simulation. I implemented it for computer network course spring 2021 The client can request

shakiba 3 Feb 8, 2022
A simple multi-threaded time server and client in python.

time-server-client A simple multi-threaded time server and client in Python. This uses the latest match/case command found in Python 3.10 so requires

Zeeshan Mulk 1 Jan 29, 2022
Very simple FTP client, sync folder to FTP server, use python, opensource

ftp-sync-python Opensource, A way to safe your data, avoid lost data by Virus, Randsomware Some functions: Upload a folder automatically to FTP server

null 4 Sep 13, 2022
A Simplest TCP client and echo server

Простейшие TCP-клиент и эхо-сервер Цель работы Познакомиться с приемами работы с сетевыми сокетами в языке программирования Python. Задания для самост

Юля Нагубнева 1 Oct 25, 2021
API to establish connection between server and client

Socket-programming API to establish connection between server and client, socket.socket() creates a socket object that supports the context manager ty

Muziwandile Nkomo 1 Oct 30, 2021
NanoChat - nano chat server and client

NanoChat This is a work in progress! NanoChat is an application for connecting with your friends using Python that uses ONLY default Python libraries.

Miss Bliss 1 Nov 13, 2021
Secure connection between tenhou Window client and server.

tenhou-secure The tenhou Windows client looks awesome. However, the traffic between the client and tenhou server is NOT encrypted, including your uniq

null 1 Nov 11, 2021
A server and client for passing data between computercraft computers/turtles across dimensions or even servers.

ccserver A server and client for passing data between computercraft computers/turtles across dimensions or even servers. pastebin get zUnE5N0v client

null 1 Jan 22, 2022
Test - Python project for Collection Server and API Server

QProjectPython Collection Server 와 API Server 를 위한 Python 프로젝트 입니다. [FastAPI참고]

null 1 Jan 3, 2022
Simple client for the Sirah Matisse Commander TCP server.

Simple client for the Sirah Matisse Commander TCP server.

Nelson Darkwah Oppong 1 Nov 2, 2021
A simple Encrypted IM chat software Server & client based on Python3.

SecretBox A simple Encrypted IM chat software Server & client based on Python3. Version 1.0 命令行版 安装步骤 Server 运行pip3 install -r requirements 安装依赖。 运行py

h3h3da 5 Oct 31, 2022
The OUCH Project - OUCH Server/Client

This software simulates OUCH Server/Client communication through a script which initialises a central server and another script which simulates clients connecting to the server.

Jahin Z. 2 Dec 10, 2022
A pure python implementation of multicast DNS service discovery

python-zeroconf Documentation. This is fork of pyzeroconf, Multicast DNS Service Discovery for Python, originally by Paul Scott-Murphy (https://github

Jakub Stasiak 483 Dec 29, 2022
A pure-Python KSUID implementation

Svix - Webhooks as a service Svix-KSUID This library is inspired by Segment's KSUID implementation: https://github.com/segmentio/ksuid What is a ksuid

Svix 83 Dec 16, 2022
Python Scrcpy Client - allows you to view and control android device in realtime

Python Scrcpy Client This package allows you to view and control android device in realtime. Note: This gif is compressed and experience lower quality

LengYue 126 Jan 2, 2023