/// <summary> /// Ctor of the topology worker /// </summary> /// <param name="tree">Topology tree to query</param> public RDXTopologyWorker(ITopologyTree tree) { _busyWorkers = 0; _workerStartDelayed = 0; _tree = tree; _topology = _tree as ContosoTopology; _workers = new List <Task>(); }
/// <summary> /// Test the explorer url for all stations /// </summary> /// <param name="topology"></param> public static void TestExplorerViews(ContosoTopology topology) { List <string> stations = topology.GetAllChildren(topology.TopologyRoot.Key, typeof(Station)); int count = 0; DateTime Now = DateTime.UtcNow; string url; url = GetExplorerDefaultView(Now.Subtract(TimeSpan.FromHours(8)), Now, false); RDXTrace.TraceInformation(url); url = GetExplorerDefaultView(Now.Subtract(TimeSpan.FromDays(1)), Now, true); RDXTrace.TraceInformation(url); foreach (string appUri in stations) { url = GetExplorerStationView(Now.Subtract(TimeSpan.FromHours(1)), Now, appUri, (count & 1) == 0, (count & 2) == 0); RDXTrace.TraceInformation(url); count++; } }
/// <summary> /// Test the aggregation view for all stations and nodes. /// </summary> /// <param name="topology"></param> public static async Task TestAggregatedNodeId(ContosoTopology topology) { foreach (ContosoTopologyNode.AggregationView aggregationView in Enum.GetValues(typeof(ContosoTopologyNode.AggregationView))) { List <string> stations = topology.GetAllChildren(topology.TopologyRoot.Key, typeof(Station)); foreach (string appUri in stations) { Station station = topology[appUri] as Station; if (station != null) { foreach (ContosoOpcUaNode node in station.NodeList) { if (IsAggregatedOperator(node.OpCode)) { await RDXUtils.AggregatedNodeId(station, node, aggregationView); } } } } } }
/// <summary> /// Queries all intervals, servers and nodes in a topology for new values. /// Updates all relevances and checks for alerts. /// Returns list of task. /// Caller must wait for tasks to run to completion before topology is fully up to date. /// </summary> /// <param name="totalSearchSpan">Search span of query</param> /// <param name="topology">Topology to update</param> /// <param name="fullQuery">The cached query for the search span</param> /// <param name="opcUaServers">List of OPC UA servers to query for values</param> /// <param name="tasks">List of async tasks processing queries</param> /// <param name="aggregateIndex">The index of the aggregate in the topology nodes</param> public async Task ScheduleAllOeeKpiQueries( DateTimeRange totalSearchSpan, ContosoTopology topology, RDXCachedAggregatedQuery fullQuery, List <string> opcUaServers, List <Task> tasks, int aggregateIndex) { RDXAggregatedQueryCache queryCache = new RDXAggregatedQueryCache(); queryCache.List.Add(fullQuery); foreach (string appUri in opcUaServers) { Station station = topology[appUri] as Station; if (station != null) { ContosoAggregatedOeeKpiHistogram oeeKpiHistogram = station[aggregateIndex]; DateTime toTime = totalSearchSpan.To; int intervals = oeeKpiHistogram.Intervals.Count; oeeKpiHistogram.EndTime = toTime; station[aggregateIndex].EndTime = toTime; foreach (ContosoAggregatedOeeKpiTimeSpan oeeKpiTimeSpan in oeeKpiHistogram.Intervals) { DateTime fromTime; // first interval is current time if (totalSearchSpan.To != toTime || intervals == 1) { fromTime = toTime.Subtract(oeeKpiTimeSpan.IntervalTimeSpan); } else { fromTime = RDXUtils.RoundDateTimeToTimeSpan(toTime.Subtract(TimeSpan.FromSeconds(1)), oeeKpiTimeSpan.IntervalTimeSpan); } DateTimeRange intervalSearchSpan = new DateTimeRange(fromTime, toTime); if (toTime <= oeeKpiTimeSpan.EndTime) { // The interval is still up to date from a previous query, skip toTime = fromTime; continue; } oeeKpiTimeSpan.EndTime = toTime; toTime = fromTime; // find a cached query, if not try to cache the aggregation for this search span RDXCachedAggregatedQuery aggregatedQuery = queryCache.Find(intervalSearchSpan); if (aggregatedQuery == null) { RDXCachedAggregatedQuery newQuery = new RDXCachedAggregatedQuery(_opcUaQueries); queryCache.List.Add(newQuery); tasks.Add(newQuery.Execute(intervalSearchSpan)); aggregatedQuery = queryCache.Find(intervalSearchSpan); } RDXOeeKpiQuery oeeKpiQuery = new RDXOeeKpiQuery(_opcUaQueries, intervalSearchSpan, appUri, oeeKpiTimeSpan); await oeeKpiQuery.QueryAllNodes(tasks, station.NodeList, oeeKpiHistogram.AwaitTasks, aggregatedQuery); if (oeeKpiHistogram.CheckAlerts) { station.Status = ContosoPerformanceStatus.Good; foreach (ContosoOpcUaNode node in station.NodeList) { if (node.Minimum != null || node.Maximum != null) { station.Status |= await CheckAlert(intervalSearchSpan, appUri, station, node); } } } } } } }
public void ConfigureTopology() { Topology = new ContosoTopology(System.Web.HttpContext.Current.Server.MapPath(@"~/bin/Contoso/Topology/ContosoTopologyDescription.json")); }