Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Make/asyncio just to easily see diff DO NOT MERGE #667

Open
wants to merge 114 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
2fba780
[ADD] async modules wip
Jan 28, 2018
a8d3732
[ADD] async refactoring of ua client wip
Jan 28, 2018
7906e1e
[ADD] wip
Jan 29, 2018
ce83f6c
[ADD] replaced code (sync with async)
Jan 29, 2018
56d7198
[ADD] subscription wip
Jan 29, 2018
9320ceb
[ADD] refactor tests, server, client, examples
Jan 30, 2018
654c766
[ADD] wip
Jan 30, 2018
d59f63b
[ADD] refactor server
Jan 31, 2018
0b1252a
[ADD] refactored client receive buffer
Feb 3, 2018
18e54bf
[ADD] Server wip
Feb 4, 2018
41f5568
[ADD] refactor server wip
Feb 5, 2018
d45d5f0
[ADD] wip
Feb 7, 2018
542f784
[ADD] wip
Mar 23, 2018
5c02c0d
[ADD] uaprotocol f-string refactoring
Mar 24, 2018
115ab4a
[ADD] refactor auto protocol generation
Mar 25, 2018
6e01f04
[ADD] refactor auto code generation
Mar 25, 2018
33ae4d7
[ADD] wip
Mar 28, 2018
191f820
[ADD] wip
Mar 28, 2018
e3ff540
[FIX] missing parens
Mar 29, 2018
1a863e9
[ADD] client subscription examplpe
Apr 12, 2018
4cdcfb7
[FIX] Subscription publish on init without waiting
May 29, 2018
a45556b
[ADD] async modules wip
Jan 28, 2018
c67c8aa
[ADD] async refactoring of ua client wip
Jan 28, 2018
b67034b
[ADD] wip
Jan 29, 2018
8447da1
[ADD] replaced code (sync with async)
Jan 29, 2018
a51fdea
[ADD] subscription wip
Jan 29, 2018
4e086e7
[ADD] refactor tests, server, client, examples
Jan 30, 2018
a85b89a
[ADD] wip
Jan 30, 2018
b0168f5
[ADD] refactor server
Jan 31, 2018
4606b79
[ADD] refactored client receive buffer
Feb 3, 2018
fd5678e
[ADD] Server wip
Feb 4, 2018
b28ae40
[ADD] refactor server wip
Feb 5, 2018
5985076
[ADD] wip
Feb 7, 2018
7418fbb
[ADD] wip
Mar 23, 2018
68214cb
[ADD] uaprotocol f-string refactoring
Mar 24, 2018
63456b2
[ADD] refactor auto protocol generation
Mar 25, 2018
43da5a7
[ADD] refactor auto code generation
Mar 25, 2018
38f5faa
[ADD] wip
Mar 28, 2018
2e6b26c
[ADD] wip
Mar 28, 2018
f01f76b
[FIX] missing parens
Mar 29, 2018
60ba1a3
[ADD] client subscription examplpe
Apr 12, 2018
2e43323
[FIX] Subscription publish on init without waiting
May 29, 2018
9568638
cherry pick/merge 96bac7c39fb668a381f5b2ae30b7a44e00a73de7
oroulet Jan 31, 2018
5309eb2
cherry pick/merge 78840a61e2402fa9f236573ac13313a42a6b726f
harua8n Jan 15, 2018
ce49fbf
cleanup
Jul 30, 2018
51f27d3
cherry pick/merge 0ed614359d716c4be588e11b81283c9dd1d1fdb3
harua8n Jan 16, 2018
40dc3dc
cherry pick/merge 0cb222bfbf05928a059602bd346fc2252cc9a82c
harua8n Jan 22, 2018
1762722
empty dist not sdist in release script
oroulet Mar 2, 2018
08f5836
new release
oroulet Mar 2, 2018
654d708
cleanup
Jul 30, 2018
60855c2
cherry-pick/merge 5d5bbfdec0cdc99f55ea207aba5eb504209228e6
oroulet Mar 7, 2018
db2cd00
add client example to connect to prosys server using Basic256
oroulet Mar 7, 2018
ee39f2e
Added Dockerfile
arykovanov Mar 3, 2018
8abec21
cherry-pick/merge 1354c094e3b8d4583ab9bcabdedf19cfa9e2c999
cirp-usf Apr 13, 2018
a17000d
cherry-pick/merge e2df3d761a228242a2aadcf03a638b268ed545ea
cirp-usf Apr 13, 2018
4e9f8fe
cherry-pick/merge a1a621f00506a11d6efc717b3d2055acd0c59a82
cirp-usf Apr 13, 2018
069149c
Update tests
cirp-usf Apr 13, 2018
093ab1c
cherry-pick/merge b01896556b74114ad26e1ffce8fe7e4ca7a7dc8e
oroulet May 1, 2018
258c975
cherry-pick/merge 12562266b7400f39a605d4898eb5b0b8cd29705f
oroulet May 2, 2018
92a8dea
cherry-pick/merge 12562266b7400f39a605d4898eb5b0b8cd29705f
Jul 30, 2018
272865b
cherry-pick/merge 183a6b74169271f518ae9d23e359cbd3c0c88b39
oroulet May 2, 2018
99ae4b8
remove one more assert in operating code that should never have been …
oroulet May 2, 2018
818a1ff
new release
oroulet May 2, 2018
6faf349
fix server example for api change
oroulet May 2, 2018
54d6378
Allow importing XML from string
helmut-jacob May 8, 2018
01fe0a8
cherry-pick/merge 4e5e65e2383556aaa8bf4d0c3a58e9b95b08a7bd
oroulet May 21, 2018
a17d878
cleanup
Jul 30, 2018
c71ac81
cherry puck/merge 86711c1f918be95cc712aead3688f05e3f7cd974
jonemo May 28, 2018
a78aa7e
cherry puck/merge bbf752c624f505ec2afb8eacaed61e2b14331013
jonemo May 28, 2018
226f90d
setup.cfg for flake8 settings
jonemo May 28, 2018
741ad33
Parsing of custom structures
jobasto May 23, 2018
e2a4aa3
cherry puck/merge d552f1f2c3e34f1b1eb62961b1eca584354aae07
jobasto May 23, 2018
9c17a2f
new release
oroulet May 29, 2018
c1dab64
cleanup
Jul 30, 2018
c42190c
small doc update
oroulet May 31, 2018
13a21ce
cherry pick/merge ddfff2c1cee9189b33dc8edd76741f3681ee756f
oroulet May 31, 2018
b90398e
cherry pick/merge cc12f5fb5ef737b2462ed0e88617fe5dd126e69d
oroulet Jun 1, 2018
75dc638
cleanup
Jul 30, 2018
7c247f6
cherry pick/merge 8b665fbed0b8e9241708c0d7d9a729cc2df798de
Jun 2, 2018
951b0ca
cleanup
Jul 30, 2018
ac108cc
cherry pick/merge 3759134aba6d67fc268e51dad02c4280ca5aee84
Jun 4, 2018
00ae5f4
cleanup
Jul 30, 2018
f7aaa25
example in server-example.py\
Jun 4, 2018
7991a66
cherry pick/merge f82f044033cd46624373721fe52b55e75deba3c0
oroulet May 30, 2018
cbe733d
attempt to speed up node comparison
oroulet May 30, 2018
e0c9d1f
cherry pick/merge c1162fb470c83b567653372e5bfd4b5917f8015a
oroulet May 30, 2018
90939cb
only add timestamps for value attribute and not for standard address …
oroulet May 31, 2018
e429fee
cherry pick/merge f86f82b189ab6b1c6ac5269569a919285b68e6d5
oroulet May 31, 2018
bc636f1
while importing xml override ParentNodeId attribute with the referenc…
oroulet Jun 4, 2018
a9a7eb1
cherry pick/merge c0cbca000e306e3f70453266b125a55b9b7fbe27
Jun 4, 2018
053cf74
cleanup
Jul 30, 2018
f4a5dc5
cleanup
Jul 30, 2018
af2d044
cherry pick 33bf3850bf09a1410b0f6fb0f2f7624aab414259
kleskjr Jun 7, 2018
122b99d
wip
Jul 30, 2018
a21a123
tests refactored
Jul 30, 2018
74338f9
tests refactored
Jul 30, 2018
fc60e03
refactored common tests (wip)
Jul 30, 2018
b7a7f42
test refactoring wip
Jul 31, 2018
7faafe6
refactored tests and server-events example
Jul 31, 2018
006689d
Merge branch 'asyncio_rebase' into make/asyncio
Jul 31, 2018
4221be7
refactored tests and async fixes
Aug 1, 2018
3505fc6
refactored tests and async fixes
Aug 1, 2018
a5a8df6
refactored import structure, cleanup
Aug 2, 2018
a05b957
fix async method service call
Aug 2, 2018
5821a6e
cryptography signer -> sign, verifier -> verify migration
Aug 2, 2018
106606d
cleanup, refactor Subscription tests
Aug 2, 2018
a1af517
refactor uaprocessor Publish queues
Aug 2, 2018
90d2f31
refactor subscription tests
Aug 2, 2018
48e212f
cleanup, typing, async fixes
Aug 2, 2018
3a301ea
fix OPCUAProtocol (added message queue)
Aug 2, 2018
db33f8d
refactored xml tests, cleanup
Aug 3, 2018
b1a353d
downloaded new schemas, cleanup auto code generators
Aug 4, 2018
bc15b01
fix generate_address_space typo
Aug 4, 2018
60c4f4e
cleanup, test refactoring, xml import/export with threadpool executor
Aug 5, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM python:3.6

RUN pip install opcua

CMD uaserver
3 changes: 3 additions & 0 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pytest
pytest-asyncio
coverage
66 changes: 31 additions & 35 deletions examples/client-events.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,53 @@
import sys
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()


import asyncio
import logging
from opcua import Client

logging.basicConfig(level=logging.INFO)
_logger = logging.getLogger('opcua')

class SubHandler(object):

class SubHandler:
"""
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)
_logger.info("New event received: %r", event)


if __name__ == "__main__":

client = Client("opc.tcp://localhost:4840/freeopcua/server/")
# client = Client("opc.tcp://admin@localhost:4840/freeopcua/server/") #connect using a user
try:
client.connect()
async def task():
url = "opc.tcp://localhost:4840/freeopcua/server/"
# url = "opc.tcp://admin@localhost:4840/freeopcua/server/" #connect using a user

async with Client(url=url) as client:
# 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("Objects node is: ", root)
_logger.info("Objects node is: %r", root)

# Now getting a variable node using its browse path
obj = root.get_child(["0:Objects", "2:MyObject"])
print("MyObject is: ", obj)
obj = await root.get_child(["0:Objects", "2:MyObject"])
_logger.info("MyObject is: %r", obj)

myevent = root.get_child(["0:Types", "0:EventTypes", "0:BaseEventType", "2:MyFirstEvent"])
print("MyFirstEventType is: ", myevent)
myevent = await root.get_child(["0:Types", "0:EventTypes", "0:BaseEventType", "2:MyFirstEvent"])
_logger.info("MyFirstEventType is: %r", myevent)

msclt = SubHandler()
sub = client.create_subscription(100, msclt)
handle = sub.subscribe_events(obj, myevent)

embed()
sub.unsubscribe(handle)
sub.delete()
finally:
client.disconnect()
sub = await client.create_subscription(100, msclt)
handle = await sub.subscribe_events(obj, myevent)
await asyncio.sleep(10)
await sub.unsubscribe(handle)
await sub.delete()


def main():
loop = asyncio.get_event_loop()
loop.set_debug(True)
loop.run_until_complete(task())
loop.close()


if __name__ == "__main__":
main()
130 changes: 61 additions & 69 deletions examples/client-example.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
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()

import time
import asyncio
import logging

from opcua import Client
from opcua import ua

logging.basicConfig(level=logging.INFO)
_logger = logging.getLogger('opcua')

class SubHandler(object):

class SubHandler(object):
"""
Subscription Handler. To receive events from server for a subscription
data_change and event methods are called directly from receiving thread.
Expand All @@ -29,60 +18,63 @@ class SubHandler(object):
"""

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

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

print("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
async def task(loop):
url = "opc.tcp://commsvr.com:51234/UA/CAS_UA_Server"
# url = "opc.tcp://localhost:4840/freeopcua/server/"
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)
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")
#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

# Now getting a variable node using its browse path
myvar = root.get_child(["0:Objects", "2:MyObject", "2:MyVariable"])
obj = root.get_child(["0:Objects", "2:MyObject"])
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("2:multiply", 3, "klk")
print("method result is: ", res)

embed()
finally:
client.disconnect()
async with Client(url=url) as client:
root = client.get_root_node()
_logger.info("Root node is: %r", root)
objects = client.get_objects_node()
_logger.info("Objects node is: %r", objects)

# Node objects have methods to read and write node attributes as well as browse or populate address space
_logger.info("Children of root are: %r", await 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")
#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

# Now getting a variable node using its browse path
myvar = await root.get_child(["0:Objects", "2:MyObject", "2:MyVariable"])
obj = await root.get_child(["0:Objects", "2:MyObject"])
_logger.info("myvar is: %r", myvar)

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

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

# calling a method on server
res = obj.call_method("2:multiply", 3, "klk")
_logger.info("method result is: %r", res)
except Exception:
_logger.exception('error')


def main():
loop = asyncio.get_event_loop()
loop.set_debug(True)
loop.run_until_complete(task(loop))
loop.close()


if __name__ == "__main__":
main()
69 changes: 69 additions & 0 deletions examples/client-minimal-auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import asyncio
import logging
from opcua import Client, Node, ua

logging.basicConfig(level=logging.INFO)
_logger = logging.getLogger('opcua')


async def browse_nodes(node: Node):
"""
Build a nested node tree dict by recursion (filtered by OPC UA objects and variables).
"""
node_class = await node.get_node_class()
children = []
for child in await node.get_children():
if await child.get_node_class() in [ua.NodeClass.Object, ua.NodeClass.Variable]:
children.append(
await browse_nodes(child)
)
if node_class != ua.NodeClass.Variable:
var_type = None
else:
try:
var_type = (await node.get_data_type_as_variant_type()).value
except ua.UaError:
_logger.warning('Node Variable Type could not be determined for %r', node)
var_type = None
return {
'id': node.nodeid.to_string(),
'name': (await node.get_display_name()).Text,
'cls': node_class.value,
'children': children,
'type': var_type,
}


async def task(loop):
url = "opc.tcp://192.168.2.64:4840"
# url = "opc.tcp://localhost:4840/freeopcua/server/"
try:
client = Client(url=url)
client.set_user('test')
client.set_password('test')
# client.set_security_string()
await 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()
_logger.info("Objects node is: %r", root)

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

tree = await browse_nodes(client.get_objects_node())
_logger.info('Node tree: %r', tree)
except Exception:
_logger.exception('error')
finally:
await client.disconnect()


def main():
loop = asyncio.get_event_loop()
loop.set_debug(True)
loop.run_until_complete(task(loop))
loop.close()


if __name__ == "__main__":
main()
Loading