Commit 90939cb5 authored by oroulet's avatar oroulet Committed by Christian Bergmiller

only add timestamps for value attribute and not for standard address space

fix timestamp typo and use SourceTimestamp in histry

make History always use SourceTimestamp not ServerTimestamp (ServerTimestampd is often not set)
parent e0c9d1f9
......@@ -229,7 +229,7 @@ class NodeManagementService(object):
nodedata = NodeData(item.RequestedNewNodeId)
self._add_node_attributes(nodedata, item)
self._add_node_attributes(nodedata, item, add_timestamps=check)
# now add our node to db
self._aspace[nodedata.nodeid] = nodedata
......@@ -247,7 +247,7 @@ class NodeManagementService(object):
return result
def _add_node_attributes(self, nodedata, item):
def _add_node_attributes(self, nodedata, item, add_timestamps):
# add common attrs
nodedata.attributes[ua.AttributeIds.NodeId] = AttributeValue(
ua.DataValue(ua.Variant(nodedata.nodeid, ua.VariantType.NodeId))
......@@ -259,7 +259,7 @@ class NodeManagementService(object):
ua.DataValue(ua.Variant(item.NodeClass, ua.VariantType.Int32))
)
# add requested attrs
self._add_nodeattributes(item.NodeAttributes, nodedata)
self._add_nodeattributes(item.NodeAttributes, nodedata, add_timestamps)
def _add_unique_reference(self, nodedata, desc):
for r in nodedata.references:
......@@ -403,14 +403,15 @@ class NodeManagementService(object):
self._delete_unique_reference(item, True)
return self._delete_unique_reference(item)
def _add_node_attr(self, item, nodedata, name, vtype=None):
def _add_node_attr(self, item, nodedata, name, vtype=None, add_timestamps=False):
if item.SpecifiedAttributes & getattr(ua.NodeAttributesMask, name):
dv = ua.DataValue(ua.Variant(getattr(item, name), vtype))
dv.ServerTimestamp = datetime.utcnow()
dv.SourceTimestamp = datetime.utcnow()
if add_timestamps:
# dv.ServerTimestamp = datetime.utcnow() # Disabled until someone explains us it should be there
dv.SourceTimestamp = datetime.utcnow()
nodedata.attributes[getattr(ua.AttributeIds, name)] = AttributeValue(dv)
def _add_nodeattributes(self, item, nodedata):
def _add_nodeattributes(self, item, nodedata, add_timestamps):
self._add_node_attr(item, nodedata, "AccessLevel", ua.VariantType.Byte)
self._add_node_attr(item, nodedata, "ArrayDimensions", ua.VariantType.UInt32)
self._add_node_attr(item, nodedata, "BrowseName", ua.VariantType.QualifiedName)
......@@ -433,7 +434,7 @@ class NodeManagementService(object):
self._add_node_attr(item, nodedata, "ValueRank", ua.VariantType.Int32)
self._add_node_attr(item, nodedata, "WriteMask", ua.VariantType.UInt32)
self._add_node_attr(item, nodedata, "UserWriteMask", ua.VariantType.UInt32)
self._add_node_attr(item, nodedata, "Value")
self._add_node_attr(item, nodedata, "Value", add_timestamps=add_timestamps)
class MethodService(object):
......
......@@ -39,7 +39,7 @@ class HistoryStorageInterface(object):
nb_values is the max number of values to read. Ignored if 0
Start time and end time are inclusive
Returns a list of DataValues and a continuation point which
is None if all nodes are read or the ServerTimeStamp of the last rejected DataValue
is None if all nodes are read or the SourceTimeStamp of the last rejected DataValue
"""
raise NotImplementedError
......@@ -62,7 +62,7 @@ class HistoryStorageInterface(object):
Called when a client make a history read request for events
Start time and end time are inclusive
Returns a list of Events and a continuation point which
is None if all events are read or the ServerTimeStamp of the last rejected event
is None if all events are read or the SourceTimeStamp of the last rejected event
"""
raise NotImplementedError
......@@ -98,7 +98,7 @@ class HistoryDict(HistoryStorageInterface):
data.append(datavalue)
now = datetime.utcnow()
if period:
while len(data) and now - data[0].ServerTimestamp > period:
while len(data) and now - data[0].SourceTimestamp > period:
data.pop(0)
if count and len(data) > count:
data.pop(0)
......@@ -114,16 +114,16 @@ class HistoryDict(HistoryStorageInterface):
if end is None:
end = ua.get_win_epoch()
if start == ua.get_win_epoch():
results = [dv for dv in reversed(self._datachanges[node_id]) if start <= dv.ServerTimestamp]
results = [dv for dv in reversed(self._datachanges[node_id]) if start <= dv.SourceTimestamp]
elif end == ua.get_win_epoch():
results = [dv for dv in self._datachanges[node_id] if start <= dv.ServerTimestamp]
results = [dv for dv in self._datachanges[node_id] if start <= dv.SourceTimestamp]
elif start > end:
results = [dv for dv in reversed(self._datachanges[node_id]) if end <= dv.ServerTimestamp <= start]
results = [dv for dv in reversed(self._datachanges[node_id]) if end <= dv.SourceTimestamp <= start]
else:
results = [dv for dv in self._datachanges[node_id] if start <= dv.ServerTimestamp <= end]
results = [dv for dv in self._datachanges[node_id] if start <= dv.SourceTimestamp <= end]
if nb_values and len(results) > nb_values:
cont = results[nb_values + 1].ServerTimestamp
cont = results[nb_values + 1].SourceTimestamp
results = results[:nb_values]
return results, cont
......@@ -139,7 +139,7 @@ class HistoryDict(HistoryStorageInterface):
period, count = self._events_periods[event.SourceNode]
now = datetime.utcnow()
if period:
while len(evts) and now - evts[0].ServerTimestamp > period:
while len(evts) and now - evts[0].SourceTimestamp > period:
evts.pop(0)
if count and len(evts) > count:
evts.pop(0)
......
......@@ -91,12 +91,12 @@ class HistorySQLite(HistoryStorageInterface):
if period:
# after the insert, if a period was specified delete all records older than period
date_limit = datetime.utcnow() - period
execute_sql_delete('ServerTimestamp < ?', (date_limit,))
execute_sql_delete('SourceTimestamp < ?', (date_limit,))
if count:
# ensure that no more than count records are stored for the specified node
execute_sql_delete('ServerTimestamp = (SELECT CASE WHEN COUNT(*) > ? '
'THEN MIN(ServerTimestamp) ELSE NULL END FROM "{tn}")', (count,))
execute_sql_delete('SourceTimestamp = (SELECT CASE WHEN COUNT(*) > ? '
'THEN MIN(SourceTimestamp) ELSE NULL END FROM "{tn}")', (count,))
def read_node_history(self, node_id, start, end, nb_values):
with self._lock:
......@@ -110,13 +110,13 @@ class HistorySQLite(HistoryStorageInterface):
# select values from the database; recreate UA Variant from binary
try:
for row in _c_read.execute('SELECT * FROM "{tn}" WHERE "ServerTimestamp" BETWEEN ? AND ? '
for row in _c_read.execute('SELECT * FROM "{tn}" WHERE "SourceTimestamp" BETWEEN ? AND ? '
'ORDER BY "_Id" {dir} LIMIT ?'.format(tn=table, dir=order),
(start_time, end_time, limit,)):
# rebuild the data value object
dv = ua.DataValue(variant_from_binary(Buffer(row[6])))
dv.ServerTimestamp = row[1]
dv.SourceTimestamp = row[1]
dv.SourceTimestamp = row[2]
dv.StatusCode = ua.StatusCode(row[3])
......@@ -127,7 +127,7 @@ class HistorySQLite(HistoryStorageInterface):
if nb_values:
if len(results) > nb_values:
cont = results[nb_values].ServerTimestamp
cont = results[nb_values].SourceTimestamp
results = results[:nb_values]
......
......@@ -260,7 +260,7 @@ class TestHistoryLimitsCommon(unittest.TestCase):
def addValue(self, age):
value = ua.DataValue()
value.ServerTimestamp = datetime.utcnow() - timedelta(hours = age)
value.SourceTimestamp = datetime.utcnow() - timedelta(hours = age)
self.history.save_node_value(self.id, value)
def test_count_limit(self):
......
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