Commit ff3bda51 authored by olivier R-D's avatar olivier R-D

whereclause seems to be working, not tests

parent 4a814b56
......@@ -53,10 +53,12 @@ if __name__ == "__main__":
try:
# time.sleep is here just because we want to see events in UaExpert
import time
for i in range(1, 10):
time.sleep(10)
myevgen.trigger(message="This is MyFirstEvent with MyNumericProperty and MyStringProperty.")
mysecondevgen.trigger(message="This is MySecondEvent with MyIntProperty and MyBoolProperty.")
count = 0
while True:
time.sleep(2)
myevgen.trigger(message="MyFirstEvent " + str(count))
mysecondevgen.trigger(message="MySecondEvent " + str(count))
count += 1
embed()
finally:
......
......@@ -234,7 +234,7 @@ class Subscription(object):
el.FilterOperands.append(op)
for subtypeid in [st.nodeid for st in self._get_subtypes(evtype)]:
op = ua.LiteralOperand()
op.Value = subtypeid
op.Value = ua.Variant(subtypeid)
el.FilterOperands.append(op)
el.FilterOperator = ua.FilterOperator.InList
......
......@@ -56,7 +56,7 @@ class EventGenerator(object):
source = Node(self.isession, self.event.SourceNode)
self.event.SourceNode = source.nodeid
self.event.SourceName = source.get_display_name().Text
self.event.SourceName = source.get_browse_name()
source.set_attribute(ua.AttributeIds.EventNotifier, ua.DataValue(ua.Variant(1, ua.VariantType.Byte)))
refs = []
......
......@@ -113,7 +113,7 @@ class MonitoredItemService(object):
for _ in params.RequestedParameters.Filter.SelectClauses:
result.FilterResult.SelectClauseResults.append(ua.StatusCode())
# FIXME: where clause result
mdata.where_clause_evaluator = WhereClauseEvaluator(mdata.mfilter.WhereClause, self.aspace)
mdata.where_clause_evaluator = WhereClauseEvaluator(self.logger, self.aspace, mdata.mfilter.WhereClause)
self._commit_monitored_item(result, mdata)
self._monitored_events[params.ItemToMonitor.NodeId] = result.MonitoredItemId
return result
......@@ -188,9 +188,9 @@ class MonitoredItemService(object):
mid, event, self)
return False
mdata = self._monitored_items[mid]
#if not mdata.where_clause_evaluator.eval(event):
#self.logger.debug("Event does not fit WhereClause, not generating event", mid, event, self)
#return
if not mdata.where_clause_evaluator.eval(event):
self.logger.debug("Event does not fit WhereClause, not generating event", mid, event, self)
return
fieldlist = ua.EventFieldList()
fieldlist.ClientHandle = mdata.client_handle
fieldlist.EventFields = self._get_event_fields(mdata.mfilter, event)
......@@ -363,13 +363,21 @@ class InternalSubscription(object):
class WhereClauseEvaluator(object):
def __init__(self, whereclause, aspace):
def __init__(self, logger, aspace, whereclause):
self.logger = logger
self.elements = whereclause.Elements
self._aspace = aspace
def eval(self, event):
if not self.elements:
return True
# spec says we should only evaluate first element, which may use other elements
return self._eval_el(0, event)
try:
res = self._eval_el(0, event)
except Exception as ex:
self.logger.warning("Exception while evaluating WhereClause %s for event %s: %s", self.elements, event, ex)
return False
return res
def _eval_el(self, index, event):
el = self.elements[index]
......@@ -393,19 +401,23 @@ class WhereClauseEvaluator(object):
print("WhereClause not implemented for element: %s", el)
def _eval_op(self, op, event):
# seems spec says we should return Null if issues
if type(op) is ua.ElementOperand:
el = self.elements[op.FilterOperands[0].Index]
return self._eval_el(el)
elif type(op) is ua.AttributeOperand:
pass
if op.BrowsePath:
return getattr(event, op.BrowsePath.Elements[0].TargetName.Name)
else:
return self._aspace.get_attribute_value(event.EventType, op.AttributeId).Value.Value
# FIXME: check, this is probably broken
elif type(op) is ua.SimpleAttributeOperand:
if op.BrowsePath:
# we only support depth of 1
return getattr(event, op.BrowsePath[0].BrowseName)
elif op.AttributeId:
return True
#return self._aspace.get_attribute_value(event.nodeid, op.AttributeId)
#return getattr(event, op.AttributeId.name) # FIXME: need to add attributeIds
return getattr(event, op.BrowsePath[0].BrowseName.Name)
else:
# TODO: write code for index range.... but doe it make any sense
return self._aspace.get_attribute_value(event.EventType, op.AttributeId).Value.Value
elif type(op) is ua.LiteralOperand:
return op.Value.Value
else:
......
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