Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
opcua-asyncio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nikola Balog
opcua-asyncio
Commits
0d8303df
Commit
0d8303df
authored
Feb 20, 2021
by
Koseng
Committed by
oroulet
Feb 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix create events with special EventFilter and add Tests
parent
f6aa7a97
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
90 additions
and
14 deletions
+90
-14
asyncua/common/events.py
asyncua/common/events.py
+17
-14
tests/test_server.py
tests/test_server.py
+17
-0
tests/test_subscriptions.py
tests/test_subscriptions.py
+56
-0
No files found.
asyncua/common/events.py
View file @
0d8303df
...
...
@@ -91,8 +91,11 @@ class Event:
return a field list using a select clause and the object properties
"""
fields
=
[]
for
sattr
in
select_clauses
:
name
=
self
.
simple_attribute_to_attribute_name
(
sattr
)
for
sattr
in
select_clauses
:
if
len
(
sattr
.
BrowsePath
)
==
0
:
name
=
ua
.
AttributeIds
(
sattr
.
AttributeId
).
name
else
:
name
=
self
.
browse_path_to_attribute_name
(
sattr
.
BrowsePath
)
try
:
val
=
getattr
(
self
,
name
)
except
AttributeError
:
...
...
@@ -113,22 +116,22 @@ class Event:
ev
=
Event
()
ev
.
select_clauses
=
select_clauses
ev
.
event_fields
=
fields
for
idx
,
sattr
in
enumerate
(
select_clauses
):
name
=
Event
.
simple_attribute_to_attribute_name
(
sattr
)
for
idx
,
sattr
in
enumerate
(
select_clauses
):
if
len
(
sattr
.
BrowsePath
)
==
0
:
name
=
sattr
.
AttributeId
.
name
else
:
name
=
Event
.
browse_path_to_attribute_name
(
sattr
.
BrowsePath
)
ev
.
add_property
(
name
,
fields
[
idx
].
Value
,
fields
[
idx
].
VariantType
)
return
ev
@
staticmethod
def
simple_attribute_to_attribute_name
(
simpleAttribute
):
if
len
(
simpleAttribute
.
BrowsePath
)
==
0
:
name
=
simpleAttribute
.
AttributeId
.
name
else
:
name
=
simpleAttribute
.
BrowsePath
[
0
].
Name
# Append the sub-property of a VariableType with '/'
iter_paths
=
iter
(
simpleAttribute
.
BrowsePath
)
next
(
iter_paths
)
for
path
in
iter_paths
:
name
+=
'/'
+
path
.
Name
def
browse_path_to_attribute_name
(
browsePath
):
name
=
browsePath
[
0
].
Name
# Append the sub-property of a VariableType with '/'
iter_paths
=
iter
(
browsePath
)
next
(
iter_paths
)
for
path
in
iter_paths
:
name
+=
'/'
+
path
.
Name
return
name
...
...
tests/test_server.py
View file @
0d8303df
...
...
@@ -431,6 +431,23 @@ async def test_eventgenerator_custom_event(server):
await
server
.
delete_nodes
([
etype
])
async
def
test_eventgenerator_custom_event_with_variables
(
server
):
# Here use generic create_custom_object_type
# Variables are still missing in create_custom_event_type
properties
=
[(
'PropertyNum'
,
ua
.
VariantType
.
Int32
),
(
'PropertyString'
,
ua
.
VariantType
.
String
)]
variables
=
[(
'VariableString'
,
ua
.
VariantType
.
String
),
(
'MyEnumVar'
,
ua
.
VariantType
.
Int32
,
ua
.
NodeId
(
ua
.
ObjectIds
.
ApplicationType
))]
etype
=
await
server
.
create_custom_object_type
(
2
,
'MyEvent33'
,
ua
.
ObjectIds
.
BaseEventType
,
properties
,
variables
)
evgen
=
await
server
.
get_event_generator
(
etype
,
ua
.
ObjectIds
.
Server
)
check_eventgenerator_custom_event
(
evgen
,
etype
,
server
)
await
check_eventgenerator_source_server
(
evgen
,
server
)
assert
0
==
evgen
.
event
.
PropertyNum
assert
evgen
.
event
.
PropertyString
is
None
await
server
.
delete_nodes
([
etype
])
async
def
test_eventgenerator_double_custom_event
(
server
):
event1
=
await
server
.
create_custom_event_type
(
3
,
'MyEvent4'
,
ua
.
ObjectIds
.
BaseEventType
,
[(
'PropertyNum'
,
ua
.
VariantType
.
Int32
),
...
...
tests/test_subscriptions.py
View file @
0d8303df
...
...
@@ -648,6 +648,62 @@ async def test_events_CustomEvent(opc):
await
opc
.
opc
.
delete_nodes
([
etype
])
async
def
test_events_CustomEvent_CustomFilter
(
opc
):
etype
=
await
opc
.
server
.
create_custom_event_type
(
2
,
'MyEvent'
,
ua
.
ObjectIds
.
ProgramTransitionAuditEventType
,
[(
'NodeId'
,
ua
.
VariantType
.
NodeId
),
(
'PropertyString'
,
ua
.
VariantType
.
String
)])
# Create Custom Event filter including AttributeId.NodeId
efilter
=
ua
.
EventFilter
()
browsePathes
=
[[
ua
.
uatypes
.
QualifiedName
(
"PropertyString"
,
2
)],
[
ua
.
uatypes
.
QualifiedName
(
"Transition"
),
ua
.
uatypes
.
QualifiedName
(
"Id"
)],
[
ua
.
uatypes
.
QualifiedName
(
"Message"
)],
[
ua
.
uatypes
.
QualifiedName
(
"EventType"
)]]
# SelectClause
for
bp
in
browsePathes
:
op
=
ua
.
SimpleAttributeOperand
()
op
.
AttributeId
=
ua
.
AttributeIds
.
Value
op
.
BrowsePath
=
bp
efilter
.
SelectClauses
.
append
(
op
)
op
=
ua
.
SimpleAttributeOperand
()
# For NodeId
op
.
AttributeId
=
ua
.
AttributeIds
.
NodeId
op
.
TypeDefinitionId
=
ua
.
NodeId
(
ua
.
ObjectIds
.
BaseEventType
)
efilter
.
SelectClauses
.
append
(
op
)
# WhereClause
el
=
ua
.
ContentFilterElement
()
el
.
FilterOperator
=
ua
.
FilterOperator
.
OfType
op
=
ua
.
LiteralOperand
()
op
.
Value
=
ua
.
Variant
(
etype
.
nodeid
)
# Define type
el
.
FilterOperands
.
append
(
op
)
efilter
.
WhereClause
.
Elements
.
append
(
el
)
# Create Subscription
myhandler
=
MySubHandler
()
sub
=
await
opc
.
opc
.
create_subscription
(
100
,
myhandler
)
handle
=
await
sub
.
subscribe_events
(
evtypes
=
etype
,
evfilter
=
efilter
)
# Create Custom Event
evgen
=
await
opc
.
server
.
get_event_generator
(
etype
)
propertystring
=
"This is my test"
msg
=
"this is my msg "
myNodeId
=
ua
.
NodeId
(
8
)
transId
=
ua
.
NodeId
(
99
)
evgen
.
event
.
PropertyString
=
propertystring
evgen
.
event
.
Message
=
ua
.
LocalizedText
(
msg
)
evgen
.
event
.
NodeId
=
myNodeId
setattr
(
evgen
.
event
,
"Transition/Id"
,
transId
)
# Fire Custom Event
await
evgen
.
trigger
()
ev
=
await
myhandler
.
result
()
# Perform tests
assert
ev
is
not
None
# we did not receive event
assert
etype
.
nodeid
==
ev
.
EventType
assert
msg
==
ev
.
Message
.
Text
assert
propertystring
==
ev
.
PropertyString
assert
myNodeId
==
ev
.
NodeId
assert
transId
==
getattr
(
ev
,
"Transition/Id"
)
await
sub
.
unsubscribe
(
handle
)
await
sub
.
delete
()
await
opc
.
opc
.
delete_nodes
([
etype
])
async
def
test_events_CustomEvent_MyObject
(
opc
):
objects
=
opc
.
server
.
nodes
.
objects
o
=
await
objects
.
add_object
(
3
,
'MyObject'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment