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
2566969b
Commit
2566969b
authored
Jan 18, 2016
by
ORD
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #114 from iirob/master
Server side deleting of nodes.
parents
6ee90273
96958774
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
261 additions
and
95 deletions
+261
-95
examples/example-client_deleting.py
examples/example-client_deleting.py
+101
-0
examples/example-server.py
examples/example-server.py
+1
-1
opcua/client/binary_client.py
opcua/client/binary_client.py
+2
-2
opcua/client/client.py
opcua/client/client.py
+3
-3
opcua/common/node.py
opcua/common/node.py
+1
-2
opcua/common/subscription.py
opcua/common/subscription.py
+12
-6
opcua/server/address_space.py
opcua/server/address_space.py
+70
-1
opcua/server/internal_server.py
opcua/server/internal_server.py
+11
-5
opcua/server/internal_subscription.py
opcua/server/internal_subscription.py
+15
-11
opcua/server/uaprocessor.py
opcua/server/uaprocessor.py
+12
-0
opcua/ua/uaprotocol_auto.py
opcua/ua/uaprotocol_auto.py
+23
-54
schemas/generate_model.py
schemas/generate_model.py
+10
-10
No files found.
examples/example-client_deleting.py
0 → 100644
View file @
2566969b
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
)
def
status_change_notification
(
self
,
status
):
print
(
"Python: New status change"
,
status
)
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 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
)
print
(
"Children of MyObject are: "
,
obj
.
get_children
())
print
(
"myvar should be still there"
)
deletenode
=
ua
.
DeleteNodesItem
()
deletenode
.
NodeId
=
obj
.
get_child
([
"2:MyVariable"
]).
nodeid
deletenode
.
DeleteTargetReferences
=
True
results
=
client
.
bclient
.
delete_nodes
([
deletenode
])
results
[
0
].
check
()
print
(
"Children of MyObject are: "
,
obj
.
get_children
())
print
(
"myvar should disapear"
)
embed
()
finally
:
client
.
disconnect
()
examples/example-server.py
View file @
2566969b
...
...
@@ -14,7 +14,7 @@ except ImportError:
shell
.
interact
()
from
opcua
import
ua
,
uamethod
,
Server
,
Event
from
opcua
import
ua
,
uamethod
,
Server
,
Event
class
SubHandler
(
object
):
...
...
opcua/client/binary_client.py
View file @
2566969b
...
...
@@ -423,13 +423,13 @@ class BinaryClient(object):
response
=
ua
.
AddNodesResponse
.
from_binary
(
data
)
response
.
ResponseHeader
.
ServiceResult
.
check
()
return
response
.
Results
def
delete_nodes
(
self
,
nodestodelete
):
self
.
logger
.
info
(
"delete_nodes"
)
request
=
ua
.
DeleteNodesRequest
()
request
.
Parameters
.
NodesToDelete
=
nodestodelete
data
=
self
.
_uasocket
.
send_request
(
request
)
response
=
ua
.
Add
NodesResponse
.
from_binary
(
data
)
response
=
ua
.
Delete
NodesResponse
.
from_binary
(
data
)
response
.
ResponseHeader
.
ServiceResult
.
check
()
return
response
.
Results
...
...
opcua/client/client.py
View file @
2566969b
...
...
@@ -285,7 +285,7 @@ class Client(object):
uris
=
[]
params
=
ua
.
FindServersParameters
()
params
.
EndpointUrl
=
self
.
server_url
.
geturl
()
params
.
ServerUris
=
uris
params
.
ServerUris
=
uris
return
self
.
bclient
.
find_servers
(
params
)
def
find_servers_on_network
(
self
):
...
...
@@ -357,7 +357,7 @@ class Client(object):
params
.
UserTokenSignature
.
Signature
=
sig
else
:
params
.
UserIdentityToken
=
ua
.
UserNameIdentityToken
()
params
.
UserIdentityToken
.
UserName
=
username
params
.
UserIdentityToken
.
UserName
=
username
if
self
.
server_url
.
password
:
pubkey
=
uacrypto
.
x509_from_der
(
self
.
security_policy
.
server_certificate
).
public_key
()
# see specs part 4, 7.36.3: if the token is encrypted, password
...
...
@@ -401,7 +401,7 @@ class Client(object):
handler argument is a class with data_change and/or event methods.
These methods will be called when notfication from server are received.
See example-client.py.
Do not do expensive/slow or network operation from these methods
Do not do expensive/slow or network operation from these methods
since they are called directly from receiving thread. This is a design choice,
start another thread if you need to do such a thing.
"""
...
...
opcua/common/node.py
View file @
2566969b
...
...
@@ -288,7 +288,7 @@ class Node(object):
# Hack for convenience methods
# local import is ugly but necessary for python2 support
# feel fri to propose something better but I want to split all those
# feel fri to propose something better but I want to split all those
# create methods fro Node
def
add_folder
(
*
args
,
**
kwargs
):
...
...
@@ -314,4 +314,3 @@ class Node(object):
def
call_method
(
*
args
,
**
kwargs
):
from
opcua.common
import
methods
return
methods
.
call_method
(
*
args
,
**
kwargs
)
opcua/common/subscription.py
View file @
2566969b
...
...
@@ -33,6 +33,12 @@ class SubHandler(object):
"""
pass
def
status_change_notification
(
self
,
status
):
"""
called for every status change notfication from server
"""
pass
def
event
(
self
,
handle
,
event
):
"""
Deprecated use event_notification
...
...
@@ -82,7 +88,7 @@ class Subscription(object):
"""
Subscription object returned by Server or Client objects.
The object represent a subscription to an opc-ua server.
This is a high level class, especially subscribe_data_change
This is a high level class, especially subscribe_data_change
and subscribe_events methods. If more control is necessary look at
code and/or use create_monitored_items method.
"""
...
...
@@ -176,7 +182,7 @@ class Subscription(object):
def
_call_status
(
self
,
status
):
try
:
self
.
_handler
.
status_change
(
status
.
Status
)
self
.
_handler
.
status_change
_notification
(
status
.
Status
)
except
Exception
:
self
.
logger
.
exception
(
"Exception calling status change handler"
)
...
...
@@ -211,7 +217,7 @@ class Subscription(object):
def
subscribe_events
(
self
,
sourcenode
=
ua
.
ObjectIds
.
Server
,
evtype
=
ua
.
ObjectIds
.
BaseEventType
):
"""
Subscribe to events from a node. Default node is Server node.
Subscribe to events from a node. Default node is Server node.
In most servers the server node is the only one you can subscribe to.
Return a handle which can be used to unsubscribe
"""
...
...
@@ -265,14 +271,14 @@ class Subscription(object):
params
.
SubscriptionId
=
self
.
subscription_id
params
.
ItemsToCreate
=
monitored_items
params
.
TimestampsToReturn
=
ua
.
TimestampsToReturn
.
Neither
mids
=
[]
results
=
self
.
server
.
create_monitored_items
(
params
)
# FIXME: Race condition here
# We lock as early as possible. But in some situation, a notification may arrives before
# locking and we will not be able to prosess it. To avoid issues, users should subscribe
# locking and we will not be able to prosess it. To avoid issues, users should subscribe
# to all nodes at once
with
self
.
_lock
:
with
self
.
_lock
:
for
idx
,
result
in
enumerate
(
results
):
mi
=
params
.
ItemsToCreate
[
idx
]
if
not
result
.
StatusCode
.
is_good
():
...
...
opcua/server/address_space.py
View file @
2566969b
...
...
@@ -181,7 +181,7 @@ class NodeManagementService(object):
result
=
ua
.
AddNodesResult
()
if
item
.
RequestedNewNodeId
in
self
.
_aspace
:
self
.
logger
.
warning
(
"AddNodeItem: node already exists"
)
self
.
logger
.
warning
(
"AddNode
s
Item: node already exists"
)
result
.
StatusCode
=
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadNodeIdExists
)
return
result
nodedata
=
NodeData
(
item
.
RequestedNewNodeId
)
...
...
@@ -233,6 +233,37 @@ class NodeManagementService(object):
return
result
def
delete_nodes
(
self
,
deletenodeitems
,
user
=
User
.
Admin
):
results
=
[]
for
item
in
deletenodeitems
:
results
.
append
(
self
.
_delete_node
(
item
,
user
))
return
results
def
_delete_node
(
self
,
item
,
user
):
if
not
user
==
User
.
Admin
:
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadUserAccessDenied
)
if
item
.
NodeId
not
in
self
.
_aspace
:
self
.
logger
.
warning
(
"DeleteNodesItem: node does not exists"
)
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadNodeIdUnknown
)
if
item
.
DeleteTargetReferences
:
for
elem
in
self
.
_aspace
.
keys
():
for
rdesc
in
self
.
_aspace
[
elem
].
references
:
if
rdesc
.
NodeId
==
item
.
NodeId
:
self
.
_aspace
[
elem
].
references
.
remove
(
rdesc
)
for
handle
,
callback
in
list
(
self
.
_aspace
[
item
.
NodeId
].
attributes
[
ua
.
AttributeIds
.
Value
].
datachange_callbacks
.
items
()):
try
:
callback
(
handle
,
None
,
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadNodeIdUnknown
))
self
.
_aspace
.
delete_datachange_callback
(
handle
)
except
Exception
as
ex
:
self
.
logger
.
exception
(
"Error calling datachange callback %s, %s, %s"
,
k
,
v
,
ex
)
del
self
.
_aspace
[
item
.
NodeId
]
return
ua
.
StatusCode
()
def
add_references
(
self
,
refs
,
user
=
User
.
Admin
):
result
=
[]
for
ref
in
refs
:
...
...
@@ -260,6 +291,36 @@ class NodeManagementService(object):
self
.
_aspace
[
addref
.
SourceNodeId
].
references
.
append
(
rdesc
)
return
ua
.
StatusCode
()
def
delete_references
(
self
,
refs
,
user
=
User
.
Admin
):
result
=
[]
for
ref
in
refs
:
result
.
append
(
self
.
_delete_reference
(
ref
,
user
))
return
result
def
_delete_reference
(
self
,
item
,
user
):
if
item
.
SourceNodeId
not
in
self
.
_aspace
:
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadSourceNodeIdInvalid
)
if
item
.
TargetNodeId
not
in
self
.
_aspace
:
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadTargetNodeIdInvalid
)
if
not
user
==
User
.
Admin
:
return
ua
.
StatusCode
(
ua
.
StatusCodes
.
BadUserAccessDenied
)
for
rdesc
in
self
.
_aspace
[
item
.
SourceNodeId
].
references
:
if
rdesc
.
NodeId
is
item
.
TargetNodeId
:
if
rdesc
.
RefrenceTypeId
!=
item
.
RefrenceTypeId
:
return
ua
.
StatusCode
(
ua
.
StatusCode
.
BadReferenceTypeInvalid
)
if
rdesc
.
IsForward
==
item
.
IsForward
or
item
.
DeleteBidirectional
:
self
.
_aspace
[
item
.
SourceNodeId
].
references
.
remove
(
rdesc
)
for
rdesc
in
self
.
_aspace
[
item
.
TargetNodeId
].
references
:
if
rdesc
.
NodeId
is
item
.
SourceNodeId
:
if
rdesc
.
RefrenceTypeId
!=
item
.
RefrenceTypeId
:
return
ua
.
StatusCode
(
ua
.
StatusCode
.
BadReferenceTypeInvalid
)
if
rdesc
.
IsForward
==
item
.
IsForward
or
item
.
DeleteBidirectional
:
self
.
_aspace
[
item
.
SourceNodeId
].
references
.
remove
(
rdesc
)
return
ua
.
StatusCode
()
def
_add_node_attr
(
self
,
item
,
nodedata
,
name
,
vtype
=
None
):
if
item
.
SpecifiedAttributes
&
getattr
(
ua
.
NodeAttributesMask
,
name
):
dv
=
ua
.
DataValue
(
ua
.
Variant
(
getattr
(
item
,
name
),
vtype
))
...
...
@@ -351,6 +412,14 @@ class AddressSpace(object):
with
self
.
_lock
:
return
self
.
_nodes
.
__contains__
(
nodeid
)
def
__delitem__
(
self
,
nodeid
):
with
self
.
_lock
:
self
.
_nodes
.
__delitem__
(
nodeid
)
def
keys
(
self
):
with
self
.
_lock
:
return
self
.
_nodes
.
keys
()
def
dump
(
self
,
path
):
"""
dump address space as binary to file
...
...
opcua/server/internal_server.py
View file @
2566969b
...
...
@@ -55,9 +55,9 @@ class InternalServer(object):
self
.
method_service
=
MethodService
(
self
.
aspace
)
self
.
node_mgt_service
=
NodeManagementService
(
self
.
aspace
)
# import address space from code generated from xml
standard_address_space
.
fill_address_space
(
self
.
node_mgt_service
)
standard_address_space
.
fill_address_space
(
self
.
node_mgt_service
)
# import address space from save db to disc
#standard_address_space.fill_address_space_from_disk(self.aspace)
#standard_address_space.fill_address_space_from_disk(self.aspace)
# import address space directly from xml, this has preformance impact so disabled
#importer = xmlimporter.XmlImporter(self.node_mgt_service)
...
...
@@ -120,7 +120,7 @@ class InternalServer(object):
def
find_servers
(
self
,
params
):
if
not
params
.
ServerUris
:
return
[
desc
.
Server
for
desc
in
self
.
_known_servers
.
values
()]
return
[
desc
.
Server
for
desc
in
self
.
_known_servers
.
values
()]
servers
=
[]
for
serv
in
self
.
_known_servers
.
values
():
serv_uri
=
serv
.
Server
.
ApplicationUri
.
split
(
":"
)
...
...
@@ -215,8 +215,8 @@ class InternalSession(object):
return
self
.
iserver
.
attribute_service
.
read
(
params
)
def
write
(
self
,
params
):
if
not
self
.
external
:
# If session is internal we need to store a copy og object, not a reference,
if
not
self
.
external
:
# If session is internal we need to store a copy og object, not a reference,
#otherwise users may change it and we will not generate expected events
for
ntw
in
params
.
NodesToWrite
:
ntw
.
Value
.
Value
.
Value
=
copy
(
ntw
.
Value
.
Value
.
Value
)
...
...
@@ -231,9 +231,15 @@ class InternalSession(object):
def
add_nodes
(
self
,
params
):
return
self
.
iserver
.
node_mgt_service
.
add_nodes
(
params
,
self
.
user
)
def
delete_nodes
(
self
,
params
):
return
self
.
iserver
.
node_mgt_service
.
delete_nodes
(
params
,
self
.
user
)
def
add_references
(
self
,
params
):
return
self
.
iserver
.
node_mgt_service
.
add_references
(
params
,
self
.
user
)
def
delete_references
(
self
,
params
):
return
self
.
iserver
.
node_mgt_service
.
delete_references
(
params
,
self
.
user
)
def
add_method_callback
(
self
,
methodid
,
callback
):
return
self
.
aspace
.
add_method_callback
(
methodid
,
callback
)
...
...
opcua/server/internal_subscription.py
View file @
2566969b
...
...
@@ -107,7 +107,7 @@ class MonitoredItemService(object):
if
result
.
StatusCode
.
is_good
():
# force data change event generation
self
.
trigger_datachange
(
handle
,
params
.
ItemToMonitor
.
NodeId
,
params
.
ItemToMonitor
.
AttributeId
)
if
not
result
.
StatusCode
.
is_good
():
del
(
self
.
_monitored_items
[
result
.
MonitoredItemId
])
self
.
_monitored_item_counter
-=
1
...
...
@@ -137,15 +137,19 @@ class MonitoredItemService(object):
self
.
_monitored_items
.
pop
(
mid
)
return
ua
.
StatusCode
()
def
datachange_callback
(
self
,
handle
,
value
):
self
.
logger
.
info
(
"subscription %s: datachange callback called with handle '%s' and value '%s'"
,
self
,
handle
,
value
.
Value
)
event
=
ua
.
MonitoredItemNotification
()
with
self
.
_lock
:
mid
=
self
.
_monitored_datachange
[
handle
]
mdata
=
self
.
_monitored_items
[
mid
]
event
.
ClientHandle
=
mdata
.
client_handle
event
.
Value
=
value
self
.
isub
.
enqueue_datachange_event
(
mid
,
event
,
mdata
.
parameters
.
RevisedQueueSize
)
def
datachange_callback
(
self
,
handle
,
value
,
error
=
None
):
if
error
:
self
.
logger
.
info
(
"subscription %s: datachange callback called with handle '%s' and erorr '%s'"
,
self
,
handle
,
error
)
self
.
trigger_statuschange
(
error
)
else
:
self
.
logger
.
info
(
"subscription %s: datachange callback called with handle '%s' and value '%s'"
,
self
,
handle
,
value
.
Value
)
event
=
ua
.
MonitoredItemNotification
()
with
self
.
_lock
:
mid
=
self
.
_monitored_datachange
[
handle
]
mdata
=
self
.
_monitored_items
[
mid
]
event
.
ClientHandle
=
mdata
.
client_handle
event
.
Value
=
value
self
.
isub
.
enqueue_datachange_event
(
mid
,
event
,
mdata
.
parameters
.
RevisedQueueSize
)
def
trigger_event
(
self
,
event
):
with
self
.
_lock
:
...
...
@@ -289,7 +293,7 @@ class InternalSubscription(object):
notif
=
ua
.
StatusChangeNotification
()
notif
.
Status
=
self
.
_triggered_statuschanges
.
pop
(
0
)
result
.
NotificationMessage
.
NotificationData
.
append
(
notif
)
self
.
logger
.
debug
(
"sending event notification %s"
,
len
(
notif
.
Status
)
)
self
.
logger
.
debug
(
"sending event notification %s"
,
notif
.
Status
)
def
publish
(
self
,
nb
):
with
self
.
_lock
:
...
...
opcua/server/uaprocessor.py
View file @
2566969b
...
...
@@ -256,6 +256,18 @@ class UAProcessor(object):
self
.
logger
.
info
(
"sending add node response"
)
self
.
send_response
(
requesthdr
.
RequestHandle
,
algohdr
,
seqhdr
,
response
)
elif
typeid
==
ua
.
NodeId
(
ua
.
ObjectIds
.
DeleteNodesRequest_Encoding_DefaultBinary
):
self
.
logger
.
info
(
"delete nodes request"
)
params
=
ua
.
DeleteNodesParameters
.
from_binary
(
body
)
results
=
self
.
session
.
delete_nodes
(
params
.
NodesToDelete
)
response
=
ua
.
DeleteNodesResponse
()
response
.
Results
=
results
self
.
logger
.
info
(
"sending delete node response"
)
self
.
send_response
(
requesthdr
.
RequestHandle
,
algohdr
,
seqhdr
,
response
)
elif
typeid
==
ua
.
NodeId
(
ua
.
ObjectIds
.
CreateSubscriptionRequest_Encoding_DefaultBinary
):
self
.
logger
.
info
(
"create subscription request"
)
params
=
ua
.
CreateSubscriptionParameters
.
from_binary
(
body
)
...
...
opcua/ua/uaprotocol_auto.py
View file @
2566969b
...
...
@@ -760,19 +760,19 @@ class DiagnosticInfo(FrozenClass):
if
self
.
InnerStatusCode
:
self
.
Encoding
|=
(
1
<<
5
)
if
self
.
InnerDiagnosticInfo
:
self
.
Encoding
|=
(
1
<<
6
)
packet
.
append
(
uatype_UInt8
.
pack
(
self
.
Encoding
))
if
self
.
SymbolicId
:
if
self
.
SymbolicId
:
packet
.
append
(
uatype_Int32
.
pack
(
self
.
SymbolicId
))
if
self
.
NamespaceURI
:
if
self
.
NamespaceURI
:
packet
.
append
(
uatype_Int32
.
pack
(
self
.
NamespaceURI
))
if
self
.
Locale
:
if
self
.
Locale
:
packet
.
append
(
uatype_Int32
.
pack
(
self
.
Locale
))
if
self
.
LocalizedText
:
if
self
.
LocalizedText
:
packet
.
append
(
uatype_Int32
.
pack
(
self
.
LocalizedText
))
if
self
.
AdditionalInfo
:
if
self
.
AdditionalInfo
:
packet
.
append
(
pack_bytes
(
self
.
AdditionalInfo
))
if
self
.
InnerStatusCode
:
if
self
.
InnerStatusCode
:
packet
.
append
(
self
.
InnerStatusCode
.
to_binary
())
if
self
.
InnerDiagnosticInfo
:
if
self
.
InnerDiagnosticInfo
:
packet
.
append
(
self
.
InnerDiagnosticInfo
.
to_binary
())
return
b''
.
join
(
packet
)
...
...
@@ -4930,8 +4930,14 @@ class DeleteNodesRequest(FrozenClass):
__repr__
=
__str__
class
DeleteNodesRes
ult
(
FrozenClass
):
class
DeleteNodesRes
ponse
(
FrozenClass
):
'''
Delete one or more nodes from the server address space.
:ivar TypeId:
:vartype TypeId: NodeId
:ivar ResponseHeader:
:vartype ResponseHeader: ResponseHeader
:ivar Results:
:vartype Results: StatusCode
:ivar DiagnosticInfos:
...
...
@@ -4942,12 +4948,16 @@ class DeleteNodesResult(FrozenClass):
self
.
_binary_init
(
binary
)
self
.
_freeze
=
True
return
self
.
TypeId
=
FourByteNodeId
(
ObjectIds
.
DeleteNodesResponse_Encoding_DefaultBinary
)
self
.
ResponseHeader
=
ResponseHeader
()
self
.
Results
=
[]
self
.
DiagnosticInfos
=
[]
self
.
_freeze
=
True
def
to_binary
(
self
):
packet
=
[]
packet
.
append
(
self
.
TypeId
.
to_binary
())
packet
.
append
(
self
.
ResponseHeader
.
to_binary
())
packet
.
append
(
uatype_Int32
.
pack
(
len
(
self
.
Results
)))
for
fieldname
in
self
.
Results
:
packet
.
append
(
fieldname
.
to_binary
())
...
...
@@ -4958,9 +4968,11 @@ class DeleteNodesResult(FrozenClass):
@
staticmethod
def
from_binary
(
data
):
return
DeleteNodesRes
ult
(
data
)
return
DeleteNodesRes
ponse
(
data
)
def
_binary_init
(
self
,
data
):
self
.
TypeId
=
NodeId
.
from_binary
(
data
)
self
.
ResponseHeader
=
ResponseHeader
.
from_binary
(
data
)
length
=
uatype_Int32
.
unpack
(
data
.
read
(
4
))[
0
]
array
=
[]
if
length
!=
-
1
:
...
...
@@ -4974,54 +4986,11 @@ class DeleteNodesResult(FrozenClass):
array
.
append
(
DiagnosticInfo
.
from_binary
(
data
))
self
.
DiagnosticInfos
=
array
def
__str__
(
self
):
return
'DeleteNodesResult('
+
'Results:'
+
str
(
self
.
Results
)
+
', '
+
\
'DiagnosticInfos:'
+
str
(
self
.
DiagnosticInfos
)
+
')'
__repr__
=
__str__
class
DeleteNodesResponse
(
FrozenClass
):
'''
Delete one or more nodes from the server address space.
:ivar TypeId:
:vartype TypeId: NodeId
:ivar ResponseHeader:
:vartype ResponseHeader: ResponseHeader
:ivar Parameters:
:vartype Parameters: DeleteNodesResult
'''
def
__init__
(
self
,
binary
=
None
):
if
binary
is
not
None
:
self
.
_binary_init
(
binary
)
self
.
_freeze
=
True
return
self
.
TypeId
=
FourByteNodeId
(
ObjectIds
.
DeleteNodesResponse_Encoding_DefaultBinary
)
self
.
ResponseHeader
=
ResponseHeader
()
self
.
Parameters
=
DeleteNodesResult
()
self
.
_freeze
=
True
def
to_binary
(
self
):
packet
=
[]
packet
.
append
(
self
.
TypeId
.
to_binary
())
packet
.
append
(
self
.
ResponseHeader
.
to_binary
())
packet
.
append
(
self
.
Parameters
.
to_binary
())
return
b''
.
join
(
packet
)
@
staticmethod
def
from_binary
(
data
):
return
DeleteNodesResponse
(
data
)
def
_binary_init
(
self
,
data
):
self
.
TypeId
=
NodeId
.
from_binary
(
data
)
self
.
ResponseHeader
=
ResponseHeader
.
from_binary
(
data
)
self
.
Parameters
=
DeleteNodesResult
.
from_binary
(
data
)
def
__str__
(
self
):
return
'DeleteNodesResponse('
+
'TypeId:'
+
str
(
self
.
TypeId
)
+
', '
+
\
'ResponseHeader:'
+
str
(
self
.
ResponseHeader
)
+
', '
+
\
'Parameters:'
+
str
(
self
.
Parameters
)
+
')'
'Results:'
+
str
(
self
.
Results
)
+
', '
+
\
'DiagnosticInfos:'
+
str
(
self
.
DiagnosticInfos
)
+
')'
__repr__
=
__str__
...
...
schemas/generate_model.py
View file @
2566969b
...
...
@@ -11,10 +11,10 @@ import xml.etree.ElementTree as ET
NeedOverride
=
[]
NeedConstructor
=
[]
#["RelativePathElement", "ReadValueId", "OpenSecureChannelParameters", "UserIdentityToken", "RequestHeader", "ResponseHeader", "ReadParameters", "UserIdentityToken", "BrowseDescription", "ReferenceDescription", "CreateSubscriptionParameters", "PublishResult", "NotificationMessage", "SetPublishingModeParameters"]
IgnoredEnums
=
[]
#["IdType", "NodeIdType"]
#we want to implement som struct by hand, to make better interface or simply because they are too complicated
#we want to implement som struct by hand, to make better interface or simply because they are too complicated
IgnoredStructs
=
[]
#["NodeId", "ExpandedNodeId", "Variant", "QualifiedName", "DataValue", "LocalizedText"]#, "ExtensionObject"]
#by default we split requests and respons in header and parameters, but some are so simple we do not split them
NoSplitStruct
=
[
"GetEndpointsResponse"
,
"CloseSessionRequest"
,
"AddNodesResponse"
,
"BrowseResponse"
,
"HistoryReadResponse"
,
"HistoryUpdateResponse"
,
"RegisterServerResponse"
,
"CloseSecureChannelRequest"
,
"CloseSecureChannelResponse"
,
"CloseSessionRequest"
,
"CloseSessionResponse"
,
"UnregisterNodesResponse"
,
"MonitoredItemModifyRequest"
,
"MonitoredItemsCreateRequest"
,
"ReadResponse"
,
"WriteResponse"
,
"TranslateBrowsePathsToNodeIdsResponse"
,
"DeleteSubscriptionsResponse"
,
"DeleteMonitoredItemsResponse"
,
"CreateMonitoredItemsResponse"
,
"ServiceFault"
,
"AddReferencesRequest"
,
"AddReferencesResponse"
,
"ModifyMonitoredItemsResponse"
,
"RepublishResponse"
,
"CallResponse"
,
"FindServersResponse"
,
"RegisterServerRequest"
,
"RegisterServer2Response"
]
NoSplitStruct
=
[
"GetEndpointsResponse"
,
"CloseSessionRequest"
,
"AddNodesResponse"
,
"
DeleteNodesResponse"
,
"
BrowseResponse"
,
"HistoryReadResponse"
,
"HistoryUpdateResponse"
,
"RegisterServerResponse"
,
"CloseSecureChannelRequest"
,
"CloseSecureChannelResponse"
,
"CloseSessionRequest"
,
"CloseSessionResponse"
,
"UnregisterNodesResponse"
,
"MonitoredItemModifyRequest"
,
"MonitoredItemsCreateRequest"
,
"ReadResponse"
,
"WriteResponse"
,
"TranslateBrowsePathsToNodeIdsResponse"
,
"DeleteSubscriptionsResponse"
,
"DeleteMonitoredItemsResponse"
,
"CreateMonitoredItemsResponse"
,
"ServiceFault"
,
"AddReferencesRequest"
,
"AddReferencesResponse"
,
"ModifyMonitoredItemsResponse"
,
"RepublishResponse"
,
"CallResponse"
,
"FindServersResponse"
,
"RegisterServerRequest"
,
"RegisterServer2Response"
]
#structs that end with Request or Response but are not
NotRequest
=
[
"MonitoredItemCreateRequest"
,
"MonitoredItemModifyRequest"
,
"CallMethodRequest"
]
OverrideTypes
=
{}
#AttributeId": "AttributeID", "ResultMask": "BrowseResultMask", "NodeClassMask": "NodeClass", "AccessLevel": "VariableAccessLevel", "UserAccessLevel": "VariableAccessLevel", "NotificationData": "NotificationData"}
...
...
@@ -54,7 +54,7 @@ class Struct(object):
if
f
.
name
==
name
:
return
f
raise
Exception
(
"field not found: "
+
name
)
def
__str__
(
self
):
return
"Struct {}:{}"
.
format
(
self
.
name
,
self
.
basetype
)
...
...
@@ -69,7 +69,7 @@ class Field(object):
self
.
sourcetype
=
None
self
.
switchfield
=
None
self
.
switchvalue
=
None
self
.
bitlength
=
1
self
.
bitlength
=
1
def
__str__
(
self
):
return
"Field {}({})"
.
format
(
self
.
name
,
self
.
uatype
)
...
...
@@ -213,7 +213,7 @@ def remove_duplicates(model):
names
.
append
(
field
.
name
)
fields
.
append
(
field
)
struct
.
fields
=
fields
def
add_encoding_field
(
model
):
for
struct
in
model
.
structs
:
newfields
=
[]
...
...
@@ -226,7 +226,7 @@ def add_encoding_field(model):
b
.
name
=
field
.
name
b
.
idx
=
0
b
.
container
=
container
b
.
length
=
6
b
.
length
=
6
idx
=
b
.
length
struct
.
bits
[
b
.
name
]
=
b
...
...
@@ -299,10 +299,10 @@ def split_requests(model):
paramstruct
=
Struct
()
if
structtype
==
"Request"
:
basename
=
struct
.
name
.
replace
(
"Request"
,
""
)
+
"Parameters"
paramstruct
.
name
=
basename
paramstruct
.
name
=
basename
else
:
basename
=
struct
.
name
.
replace
(
"Response"
,
""
)
+
"Result"
paramstruct
.
name
=
basename
paramstruct
.
name
=
basename
paramstruct
.
fields
=
struct
.
fields
[
2
:]
paramstruct
.
bits
=
struct
.
bits
...
...
@@ -311,8 +311,8 @@ def split_requests(model):
structs
.
append
(
paramstruct
)
typeid
=
Field
()
typeid
.
name
=
"Parameters"
typeid
.
uatype
=
paramstruct
.
name
typeid
.
name
=
"Parameters"
typeid
.
uatype
=
paramstruct
.
name
struct
.
fields
.
append
(
typeid
)
structs
.
append
(
struct
)
model
.
structs
=
structs
...
...
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