Commit 9f0e9bfa authored by Denis Štogl's avatar Denis Štogl

Full implemenation of events

parent 217fb21a
......@@ -41,7 +41,7 @@ class EventGenerator(object):
node = Node(self.isession, ua.NodeId(etype))
if node:
self.event = get_event_from_node(node)
self.event = get_event_from_type_node(node)
if isinstance(source, Node):
pass
......@@ -77,15 +77,15 @@ class EventGenerator(object):
#FIXME: LocalTime is wrong but currently know better. For description s. Part 5 page 18
self.event.LocalTime = datetime.utcnow()
if message:
self.Message = ua.LocalizedText(message)
self.event.Message = ua.LocalizedText(message)
elif not self.event.Message:
self.event.Message = ua.LocalizedText(self.source.get_browse_name().Text)
self.event.Message = ua.LocalizedText(Node(self.isession, self.event.SourceNode).get_browse_name().Text)
self.isession.subscription_service.trigger_event(self.event)
def get_event_from_node(node):
if node.nodeid.Identifier in ua.uaevents_auto.IMPLEMNTED_EVENTS.keys():
return ua.uaevents_auto.IMPLEMNTED_EVENTS[node.nodeid.Identifier]()
def get_event_from_type_node(node):
if node.nodeid.Identifier in ua.uaevents_auto.IMPLEMENTED_EVENTS.keys():
return ua.uaevents_auto.IMPLEMENTED_EVENTS[node.nodeid.Identifier]()
else:
parent_identifier, parent_eventtype = _find_parent_eventtype(node)
if not parent_eventtype:
......@@ -95,12 +95,13 @@ def get_event_from_node(node):
def __init__(self):
super(CustomEvent, self).__init__(extended=True)
self.EventType = node.nodeid
curr_node = node
while curr_node.nodeid.Identifier != parent_identifier:
for prop in curr_node.get_properties():
setattr(self, prop.get_browse_name().Name, prop.get_value())
parents = node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse, includesubtypes=False)
parents = curr_node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse, includesubtypes=False)
if len(parents) != 1: # Something went wrong
return None
curr_node = parents[0]
......@@ -110,12 +111,32 @@ def get_event_from_node(node):
return CustomEvent()
def get_event_properties_from_type_node(node):
properties = []
curr_node = node
print node
while True:
properties.extend(curr_node.get_properties())
if curr_node.nodeid.Identifier == ua.ObjectIds.BaseEventType:
break
parents = curr_node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse, includesubtypes=False)
if len(parents) != 1: # Something went wrong
return None
curr_node = parents[0]
return properties
def _find_parent_eventtype(node):
parents = node.get_referenced_nodes(refs=ua.ObjectIds.HasSubtype, direction=ua.BrowseDirection.Inverse, includesubtypes=False)
if len(parents) != 1: # Something went wrong
return None
if parents[0].nodeid.Identifier in ua.uaevents_auto.IMPLEMNTED_EVENTS.keys():
return parents[0].nodeid.Identifier, ua.uaevents_auto.IMPLEMNTED_EVENTS[parents[0].nodeid.Identifier]
return None, None
if parents[0].nodeid.Identifier in ua.uaevents_auto.IMPLEMENTED_EVENTS.keys():
return parents[0].nodeid.Identifier, ua.uaevents_auto.IMPLEMENTED_EVENTS[parents[0].nodeid.Identifier]
else:
_find_parent_eventtype(parents[0])
return _find_parent_eventtype(parents[0])
......@@ -7,6 +7,7 @@ from threading import Lock
from opcua import ua
from opcua import Node
from opcua.common import event
class SubHandler(object):
......@@ -201,11 +202,11 @@ class Subscription(object):
def _get_filter_from_event_type(self, eventtype):
eventtype = self._get_node(eventtype)
evfilter = ua.EventFilter()
for desc in eventtype.get_children_descriptions(refs=ua.ObjectIds.HasProperty, nodeclassmask=ua.NodeClass.Variable):
for property in event.get_event_properties_from_type_node(eventtype):
op = ua.SimpleAttributeOperand()
op.TypeDefinitionId = eventtype.nodeid
op.AttributeId = ua.AttributeIds.Value
op.BrowsePath = [desc.BrowseName]
op.BrowsePath = [property.get_browse_name()]
evfilter.SelectClauses.append(op)
return evfilter
......
......@@ -338,7 +338,7 @@ class Server(object):
etype = ua.BaseEvent()
return EventGenerator(self.iserver.isession, etype, source)
def create_custom_event(self, idx, name, baseetype=ua.ObjectIds.BaseEventType, properties=[]):
def create_custom_event_type(self, idx, name, baseetype=ua.ObjectIds.BaseEventType, properties=[]):
if isinstance(baseetype, Node):
base_event = baseetype
......
......@@ -36,6 +36,7 @@ class AuditEvent(BaseEvent):
'''
def __init__(self, sourcenode=None, message=None, severity=1, extended=False):
super(AuditEvent, self).__init__(sourcenode, message, severity, True)
self.EventType = NodeId(ObjectIds.AuditEventType)
self.ActionTimeStamp = None
self.Status = False
......@@ -46,7 +47,7 @@ class AuditEvent(BaseEvent):
self._freeze = True
IMPLEMNTED_EVENTS = {
IMPLEMENTED_EVENTS = {
ObjectIds.BaseEventType: BaseEvent,
ObjectIds.AuditEventType: AuditEvent,
}
# encoding: utf-8
from concurrent.futures import Future
from concurrent.futures import Future, TimeoutError
import time
from datetime import datetime
from datetime import timedelta
import math
import opcua
from opcua import ua
from opcua import EventGenerator
from opcua import uamethod
......@@ -288,29 +288,162 @@ class CommonTests(object):
handle = sub.subscribe_events(v)
sub.delete()
#def test_events(self):
#msclt = MySubHandler()
#sub = self.opc.create_subscription(100, msclt)
#handle = sub.subscribe_events()
#ev = EventGenerator(self.srv.iserver.isession)
#msg = b"this is my msg "
#ev.Message.Text = msg
#tid = datetime.utcnow()
#ev.Time = tid
#ev.Severity = 500
#ev.trigger()
#ev = msclt.future.result()
#self.assertIsNot(ev, None) # we did not receive event
#self.assertEqual(ev.SourceNode, self.opc.get_server_node().nodeid)
#self.assertEqual(ev.Message.Text, msg)
##self.assertEqual(msclt.ev.Time, tid)
#self.assertEqual(ev.Severity, 500)
## time.sleep(0.1)
#sub.unsubscribe(handle)
#sub.delete()
def test_get_event_from_type_node_BaseEvent(self):
etype = self.opc.get_node(ua.ObjectIds.BaseEventType)
properties = opcua.common.event.get_event_properties_from_type_node(etype)
for child in etype.get_properties():
self.assertTrue(child in properties)
def test_get_event_from_type_node_CustomEvent(self):
etype = self.srv.create_custom_event_type(2, 'MyEvent', ua.ObjectIds.AuditEventType, [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)])
properties = opcua.common.event.get_event_properties_from_type_node(etype)
for child in self.opc.get_node(ua.ObjectIds.BaseEventType).get_properties():
self.assertTrue(child in properties)
for child in self.opc.get_node(ua.ObjectIds.AuditEventType).get_properties():
self.assertTrue(child in properties)
for child in self.opc.get_node(etype.nodeid).get_properties():
self.assertTrue(child in properties)
self.assertTrue(etype.get_child("2:PropertyNum") in properties)
self.assertTrue(etype.get_child("2:PropertyString") in properties)
def test_events_default(self):
evgen = self.srv.get_event_generator()
msclt = MySubHandler()
sub = self.opc.create_subscription(100, msclt)
handle = sub.subscribe_events()
tid = datetime.utcnow()
msg = b"this is my msg "
evgen.trigger(tid, msg)
ev = msclt.future.result()
self.assertIsNot(ev, None) # we did not receive event
self.assertEqual(ev.EventType, ua.NodeId(ua.ObjectIds.BaseEventType))
self.assertEqual(ev.Severity, 1)
self.assertEqual(ev.SourceName, self.opc.get_server_node().get_display_name().Text)
self.assertEqual(ev.SourceNode, self.opc.get_server_node().nodeid)
self.assertEqual(ev.Message.Text, msg)
self.assertEqual(ev.Time, tid)
# time.sleep(0.1)
sub.unsubscribe(handle)
sub.delete()
def test_events_MyObject(self):
objects = self.srv.get_objects_node()
o = objects.add_object(3, 'MyObject')
evgen = self.srv.get_event_generator(source=o)
msclt = MySubHandler()
sub = self.opc.create_subscription(100, msclt)
handle = sub.subscribe_events(o)
tid = datetime.utcnow()
msg = b"this is my msg "
evgen.trigger(tid, msg)
ev = msclt.future.result(10)
self.assertIsNot(ev, None) # we did not receive event
self.assertEqual(ev.EventType, ua.NodeId(ua.ObjectIds.BaseEventType))
self.assertEqual(ev.Severity, 1)
self.assertEqual(ev.SourceName, "MyObject")
self.assertEqual(ev.SourceNode, o.nodeid)
self.assertEqual(ev.Message.Text, msg)
self.assertEqual(ev.Time, tid)
# time.sleep(0.1)
sub.unsubscribe(handle)
sub.delete()
def test_events_wrong_source(self):
objects = self.srv.get_objects_node()
o = objects.add_object(3, 'MyObject')
evgen = self.srv.get_event_generator(source=o)
msclt = MySubHandler()
sub = self.opc.create_subscription(100, msclt)
handle = sub.subscribe_events()
tid = datetime.utcnow()
msg = b"this is my msg "
evgen.trigger(tid, msg)
with self.assertRaises(TimeoutError): # we should not receive event
ev = msclt.future.result(10)
# time.sleep(0.1)
sub.unsubscribe(handle)
sub.delete()
def test_events_CustomEvent(self):
etype = self.srv.create_custom_event_type(2, 'MyEvent', ua.ObjectIds.BaseEventType, [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)])
evgen = self.srv.get_event_generator(etype)
msclt = MySubHandler()
sub = self.opc.create_subscription(100, msclt)
handle = sub.subscribe_events(evtype=etype)
propertynum = 2
propertystring = "This is my test"
evgen.event.PropertyNum = propertynum
evgen.event.PropertyString = propertystring
serverity = 500
evgen.event.Severity = serverity
tid = datetime.utcnow()
msg = b"this is my msg "
evgen.trigger(tid, msg)
ev = msclt.future.result(10)
self.assertIsNot(ev, None) # we did not receive event
self.assertEqual(ev.EventType, etype.nodeid)
self.assertEqual(ev.Severity, serverity)
self.assertEqual(ev.SourceName, self.opc.get_server_node().get_display_name().Text)
self.assertEqual(ev.SourceNode, self.opc.get_server_node().nodeid)
self.assertEqual(ev.Message.Text, msg)
self.assertEqual(ev.Time, tid)
self.assertEqual(ev.PropertyNum, propertynum)
self.assertEqual(ev.PropertyString, propertystring)
# time.sleep(0.1)
sub.unsubscribe(handle)
sub.delete()
def test_events_CustomEvent_MyObject(self):
objects = self.srv.get_objects_node()
o = objects.add_object(3, 'MyObject')
etype = self.srv.create_custom_event_type(2, 'MyEvent', ua.ObjectIds.BaseEventType, [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)])
evgen = self.srv.get_event_generator(etype, o)
msclt = MySubHandler()
sub = self.opc.create_subscription(100, msclt)
handle = sub.subscribe_events(o, etype)
propertynum = 2
propertystring = "This is my test"
evgen.event.PropertyNum = propertynum
evgen.event.PropertyString = propertystring
tid = datetime.utcnow()
msg = b"this is my msg "
evgen.trigger(tid, msg)
ev = msclt.future.result(10)
self.assertIsNot(ev, None) # we did not receive event
self.assertEqual(ev.EventType, etype.nodeid)
self.assertEqual(ev.Severity, 1)
self.assertEqual(ev.SourceName, "MyObject")
self.assertEqual(ev.SourceNode, o.nodeid)
self.assertEqual(ev.Message.Text, msg)
self.assertEqual(ev.Time, tid)
self.assertEqual(ev.PropertyNum, propertynum)
self.assertEqual(ev.PropertyString, propertystring)
# time.sleep(0.1)
sub.unsubscribe(handle)
sub.delete()
def test_non_existing_path(self):
root = self.opc.get_root_node()
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment