async def read_raw_history(self, starttime=None, endtime=None, numvalues=0, return_bounds=True): """ Read raw history of a node result code from server is checked and an exception is raised in case of error If numvalues is > 0 and number of events in period is > numvalues then result will be truncated """ details = ua.ReadRawModifiedDetails() details.IsReadModified = False if starttime: details.StartTime = starttime else: details.StartTime = ua.get_win_epoch() if endtime: details.EndTime = endtime else: details.EndTime = ua.get_win_epoch() details.NumValuesPerNode = numvalues details.ReturnBounds = return_bounds history = [] continuation_point = None while True: result = await self.history_read(details, continuation_point) result.StatusCode.check() continuation_point = result.ContinuationPoint history.extend(result.HistoryData.DataValues) # No more data available if continuation_point is None: break return history
async def read_event_history(self, starttime=None, endtime=None, numvalues=0, evtypes=ua.ObjectIds.BaseEventType): """ Read event history of a source node result code from server is checked and an exception is raised in case of error If numvalues is > 0 and number of events in period is > numvalues then result will be truncated """ details = ua.ReadEventDetails() if starttime: details.StartTime = starttime else: details.StartTime = ua.get_win_epoch() if endtime: details.EndTime = endtime else: details.EndTime = ua.get_win_epoch() details.NumValuesPerNode = numvalues if not isinstance(evtypes, (list, tuple)): evtypes = [evtypes] evtypes = [Node(self.server, evtype) for evtype in evtypes] evfilter = await get_filter_from_event_type(evtypes) details.Filter = evfilter result = await self.history_read_events(details) result.StatusCode.check() event_res = [] for res in result.HistoryData.Events: event_res.append( Event.from_event_fields(evfilter.SelectClauses, res.EventFields)) return event_res
async def read_event_history(self, source_id, start, end, nb_values, evfilter): cont = None if source_id not in self._events: logger.warning( "Error attempt to read event history for node %s which does not historize events", source_id, ) return [], cont else: if start is None: start = ua.get_win_epoch() if end is None: end = ua.get_win_epoch() if start == ua.get_win_epoch(): results = [ev for ev in reversed(self._events[source_id]) if start <= ev.Time] elif end == ua.get_win_epoch(): results = [ev for ev in self._events[source_id] if start <= ev.Time] elif start > end: results = [ ev for ev in reversed(self._events[source_id]) if end <= ev.Time <= start ] else: results = [ev for ev in self._events[source_id] if start <= ev.Time <= end] if nb_values and len(results) > nb_values: cont = results[nb_values + 1].Time results = results[:nb_values] return results, cont
async def read_node_history(self, node_id, start, end, nb_values): cont = None if node_id not in self._datachanges: logger.warning("Error attempt to read history for a node which is not historized") return [], cont else: if start is None: start = ua.get_win_epoch() 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.SourceTimestamp ] elif end == ua.get_win_epoch(): 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.SourceTimestamp <= start ] else: 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].SourceTimestamp results = results[:nb_values] return results, cont
async def read_raw_history(self, starttime=None, endtime=None, numvalues=0): """ Read raw history of a node result code from server is checked and an exception is raised in case of error If numvalues is > 0 and number of events in period is > numvalues then result will be truncated """ details = ua.ReadRawModifiedDetails() details.IsReadModified = False if starttime: details.StartTime = starttime else: details.StartTime = ua.get_win_epoch() if endtime: details.EndTime = endtime else: details.EndTime = ua.get_win_epoch() details.NumValuesPerNode = numvalues details.ReturnBounds = True result = await self.history_read(details) result.StatusCode.check() return result.HistoryData.DataValues
async def get_references(self, refs=ua.ObjectIds.References, direction=ua.BrowseDirection.Both, nodeclassmask=ua.NodeClass.Unspecified, includesubtypes=True): """ returns references of the node based on specific filter defined with: refs = ObjectId of the Reference direction = Browse direction for references nodeclassmask = filter nodes based on specific class includesubtypes = If true subtypes of the reference (ref) are also included """ desc = ua.BrowseDescription() desc.BrowseDirection = direction desc.ReferenceTypeId = _to_nodeid(refs) desc.IncludeSubtypes = includesubtypes desc.NodeClassMask = nodeclassmask desc.ResultMask = ua.BrowseResultMask.All desc.NodeId = self.nodeid params = ua.BrowseParameters() params.View.Timestamp = ua.get_win_epoch() params.NodesToBrowse.append(desc) params.RequestedMaxReferencesPerNode = 0 results = await self.server.browse(params) references = await self._browse_next(results) return references
def _get_bounds(start, end, nb_values): order = "ASC" if start is None or start == ua.get_win_epoch(): order = "DESC" start = ua.get_win_epoch() if end is None or end == ua.get_win_epoch(): end = datetime.utcnow() + timedelta(days=1) if start < end: start_time = start.isoformat(" ") end_time = end.isoformat(" ") else: order = "DESC" start_time = end.isoformat(" ") end_time = start.isoformat(" ") if nb_values: limit = nb_values + 1 # add 1 to the number of values for retrieving a continuation point else: limit = -1 # in SQLite a LIMIT of -1 returns all results return start_time, end_time, order, limit