/// <summary>
        /// This method splits a point list into severall smaller lists and perform bulk calls on each list
        /// In parallel.  
        /// </summary>
        private void GetRecordedValuesBulkParrallel(DataQuery query, AFTimeRange timeRange, int bulkPageSize, int maxDegOfParallel, int bulkParallelChunkSize, CancellationToken cancelToken)
        {
            _logger.WarnFormat("QUERY (BULK-P) # {5} - TAGS: {6} - PERIOD: {3} to {4} - MAX DEG. PAR. {0}, TAG_CHUNK_SIZE {1}, TAG_PAGE_SIZE {2},", maxDegOfParallel, bulkParallelChunkSize, bulkPageSize, timeRange.StartTime,timeRange.EndTime, query.QueryId, query.PiPoints.Count);

            // PARALLEL bulk
            var pointListList = query.PiPoints.ToList().ChunkBy(bulkParallelChunkSize);
            Parallel.ForEach(pointListList, new ParallelOptions { MaxDegreeOfParallelism = maxDegOfParallel,CancellationToken = cancelToken },
                (pts,state,index) =>
                {
                   var stats=new StatisticsInfo();
                    stats.Stopwatch.Start();

                    PIPagingConfiguration pagingConfiguration = new PIPagingConfiguration(PIPageType.TagCount, bulkPageSize);
                    PIPointList pointList = new PIPointList(pts);

                    try
                    {
                       // _logger.InfoFormat("Bulk query");
                        IEnumerable<AFValues> bulkData = pointList.RecordedValues(timeRange,
                            AFBoundaryType.Inside, String.Empty, false, pagingConfiguration).ToList();

                        if (_enableWrite)
                        {
                            var writeInfo=new WriteInfo()
                            {
                                Data = bulkData,
                                StartTime = timeRange.StartTime,
                                EndTime = timeRange.EndTime,
                                ChunkId = query.ChunkId,
                                SubChunkId= index
                            };

                            _dataWriter.DataQueue.Add(writeInfo, cancelToken);
                        }

                        stats.EventsCount = bulkData.Sum(s=>s.Count);
                        stats.Stopwatch.Stop();
                        stats.EventsInWritingQueue = _dataWriter.DataQueue.Count;
                        Statistics.StatisticsQueue.Add(stats, cancelToken);

                    }
                    catch (OperationCanceledException ex)
                    {
                        _logger.Error(pagingConfiguration.Error);
                    }
                    catch (Exception ex)
                    {

                        _logger.Error(ex);

                    }

                });
        }
Пример #2
0
        /// <summary>
        /// Starts threads and timers to poll the PI server for data
        /// </summary>
        /// <param name="state">Filter string which will get the desired points from PI</param>
        private void StartGettingData(object state)
        {
            try
            {
                string tagFilter = state.ToString();

                m_points = new PIPointList(PIPoint.FindPIPoints(m_connection.Server, tagFilter, true));

                m_dataThread = new Thread(QueryData);
                m_dataThread.IsBackground = true;
                m_dataThread.Start();

                m_publishTimer          = new System.Timers.Timer();
                m_publishTimer.Interval = ProcessingInterval > 0 ? ProcessingInterval : 33;
                m_publishTimer.Elapsed += m_publishTimer_Tick;
                m_publishTimer.Start();
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception e)
            {
                OnProcessException(e);
            }
        }
Пример #3
0
        private void StopGettingData()
        {
            try
            {
                if (m_publishTimer != null)
                {
                    m_publishTimer.Elapsed -= m_publishTimer_Tick;
                    m_publishTimer.Stop();
                    m_publishTimer.Dispose();
                }
                m_publishTimer = null;


                if (m_dataThread != null)
                {
                    m_dataThread.Abort();
                }

                m_dataThread = null;

                m_points = null;
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception ex)
            {
                OnProcessException(ex);
            }
        }
Пример #4
0
        /// <summary>
        /// This method deletes the data stored in specified tags of the PI Data Archive
        /// To delete data, it is required to first read the values that you want to delete, and then
        /// Call the update values method with the AFUpdateOption.Remove option
        /// <remarks>
        /// </remarks>
        /// </summary>
        private void DeleteData()
        {
            try
            {
                ValidateParameters();

                piConnectionMgr = new PiConnectionMgr(Server);
                piConnectionMgr.Connect();
                PIServer server = piConnectionMgr.GetPiServer();

                var timer = Stopwatch.StartNew();

                // Gets the tags and creates a point list with the tags, to prepare for bulk read call
                var points    = PIPoint.FindPIPoints(server, TagList);
                var pointList = new PIPointList(points);
                Logger.InfoFormat("Initialized PI Points for deletion: {0}", string.Join(", ", points.Select(p => p.Name)));

                // converts strings to AFTime objects this will throw an error if invalid
                var startTime = new AFTime(StartTime);
                var endTime   = new AFTime(EndTime);

                if (startTime > endTime)
                {
                    throw new PIDeleteUtilInvalidParameterException("Start Time must be smaller than End Time");
                }

                // defines the data eraser task that will work in parallel as the data querying task
                dataEraser = new DataProcessor(EraseData);
                var eraseTask = Task.Run(() => dataEraser.Run());

                // splits iterates the period, over
                foreach (var period in Library.Helpers.EachNDay(startTime, endTime, Days))
                {
                    Logger.InfoFormat("Getting tags information for period {0} to {1} ({2} Days chunk)", startTime, endTime,
                                      Days);

                    // makes the first data call
                    var data = pointList.RecordedValues(period, AFBoundaryType.Inside, null, false,
                                                        new PIPagingConfiguration(PIPageType.TagCount, 100));

                    Logger.InfoFormat("Adding the data to the queue for deletion. ({0} to {1})", startTime, endTime);
                    // we push this data into the data processor queue so we can continue to query for the rest of the data.
                    dataEraser.DataQueue.Add(data);
                }


                dataEraser.DataQueue.CompleteAdding();
                // // this will tell the data eraser that no more data will be added and allow it to complete

                eraseTask.Wait(); // waiting for the data processor to complete

                Logger.InfoFormat(
                    "Deletion process completed in {0} seconds.  With {1} events deleted (assuming there was no errors).",
                    Math.Round(timer.Elapsed.TotalSeconds, 0), dataEraser.TotalEventProcessed);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }
Пример #5
0
        public static void RecordedBulkParallelByChunks(
            AFTimeRange timeRange,
            int maxDegOfParallel,
            int bulkParallelChunkSize,
            int bulkPageSize,
            bool insertNoData,
            Action <List <AFValue> > insertData,
            PIPointsProvider provider,
            int sleep,
            CancellationToken cancelToken
            )
        {
            int i = 0;

            foreach (var pointsChunk in provider.GetPointsByChunks(bulkParallelChunkSize))
            {
                i++;
                _logger.InfoFormat("Processing tag chunk {0} - (tag chunk size: {1})", i, bulkParallelChunkSize);
                var pointsList = new PIPointList(pointsChunk);

                RecordedBulkParallel(pointsList, timeRange, 4, bulkParallelChunkSize, bulkPageSize, insertNoData, insertData, cancelToken);

                if (sleep > 0)
                {
                    Thread.Sleep(sleep);
                }
            }
        }
Пример #6
0
        public static void RecordedBulkByChunks(
            AFTimeRange timeRange,
            int pointsChunkSize,
            bool insertNoData,
            Action <List <AFValue> > insertData,
            PIPointsProvider provider,
            int sleep,
            CancellationToken cancellationToken
            )
        {
            int i = 0;

            foreach (var pointsChunk in provider.GetPointsByChunks(pointsChunkSize))
            {
                i++;
                _logger.InfoFormat("Processing tag chunk {0} - (tag chunk size: {1})", i, pointsChunkSize);
                var pointsList = new PIPointList(pointsChunk);

                RecordedBulk(pointsList, timeRange, pointsChunkSize, insertNoData, insertData); // todo needs a different setting here

                if (sleep > 0)
                {
                    Thread.Sleep(sleep);
                }
            }
        }
Пример #7
0
        public async IAsyncEnumerable <IFrame> GetData(List <AdaptSignal> signals, DateTime start, DateTime end)
        {
            if (m_server is null || !m_server.ConnectionInfo.IsConnected)
            {
                ConnectPI();
            }


            PIPointList pointList = new PIPointList(signals.Select(s => PIPoint.FindPIPoint(m_server, s.ID)));


            long   startTicks = start.Ticks;
            double totalTicks = end.Ticks - startTicks;

            m_progress = 0.0D;


            TimeOrderedValueReader reader = new()
            {
                Points    = pointList,
                StartTime = start,
                EndTime   = end
            };

            long currentTime = 0;
            Dictionary <string, ITimeSeriesValue> data = new Dictionary <string, ITimeSeriesValue>();

            await foreach (AFValue value in reader.ReadAsync())
            {
                if (value.Value is Exception ex)
                {
                    throw ex;
                }

                if (currentTime != value.Timestamp.UtcTime.Ticks)
                {
                    yield return(new Frame()
                    {
                        Published = true,
                        Timestamp = currentTime,
                        Measurements = new ConcurrentDictionary <string, ITimeSeriesValue>(data)
                    });

                    m_progress  = (currentTime - startTicks) / totalTicks;
                    data        = new Dictionary <string, ITimeSeriesValue>();
                    currentTime = value.Timestamp.UtcTime.Ticks;
                }
                if (data.ContainsKey(value.PIPoint.Name))
                {
                    continue;
                }
                data.Add(value.PIPoint.Name, new AdaptValue(value.PIPoint.Name, Convert.ToDouble(value.Value), currentTime));
            }

            m_progress = 1.0D;
        }
Пример #8
0
        /// <summary>
        /// This method splits a point list into severall smaller lists and perform bulk calls on each list
        /// In parallel.
        /// </summary>
        private void GetRecordedValuesBulkParrallel(DataQuery query, AFTimeRange timeRange, int bulkPageSize, int maxDegOfParallel, int bulkParallelChunkSize, CancellationToken cancelToken)
        {
            _logger.WarnFormat("QUERY (BULK-P) # {5} - TAGS: {6} - PERIOD: {3} to {4} - MAX DEG. PAR. {0}, TAG_CHUNK_SIZE {1}, TAG_PAGE_SIZE {2},", maxDegOfParallel, bulkParallelChunkSize, bulkPageSize, timeRange.StartTime, timeRange.EndTime, query.QueryId, query.PiPoints.Count);

            // PARALLEL bulk
            var pointListList = query.PiPoints.ToList().ChunkBy(bulkParallelChunkSize);

            Parallel.ForEach(pointListList, new ParallelOptions {
                MaxDegreeOfParallelism = maxDegOfParallel, CancellationToken = cancelToken
            },
                             (pts, state, index) =>
            {
                var stats = new StatisticsInfo();
                stats.Stopwatch.Start();

                PIPagingConfiguration pagingConfiguration = new PIPagingConfiguration(PIPageType.TagCount, bulkPageSize);
                PIPointList pointList = new PIPointList(pts);

                try
                {
                    // _logger.InfoFormat("Bulk query");
                    IEnumerable <AFValues> bulkData = pointList.RecordedValues(timeRange,
                                                                               AFBoundaryType.Inside, String.Empty, false, pagingConfiguration).ToList();


                    if (_enableWrite)
                    {
                        var writeInfo = new WriteInfo()
                        {
                            Data       = bulkData,
                            StartTime  = timeRange.StartTime,
                            EndTime    = timeRange.EndTime,
                            ChunkId    = query.ChunkId,
                            SubChunkId = index
                        };

                        _dataWriter.DataQueue.Add(writeInfo, cancelToken);
                    }


                    stats.EventsCount = bulkData.Sum(s => s.Count);
                    stats.Stopwatch.Stop();
                    stats.EventsInWritingQueue = _dataWriter.DataQueue.Count;
                    Statistics.StatisticsQueue.Add(stats, cancelToken);
                }
                catch (OperationCanceledException ex)
                {
                    _logger.Error(pagingConfiguration.Error);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
            });
        }
 // GET: Home
 public ActionResult Index()
 {
     PIServer piServer = new PIServers().DefaultPIServer;
     piServer.Connect();
     IEnumerable<PIPoint> piPointList = PIPoint.FindPIPoints(piServer, "*");
     PIPointList pointList = new PIPointList();
     pointList.AddRange(piPointList);
     AFListResults<PIPoint, AFValue> results = pointList.EndOfStream();
     IEnumerable<PIPointData> pointListData = results.Select(m => new PIPointData(m.PIPoint.Name, m.Value, m.Timestamp.LocalTime, m.PIPoint.ID));
     return View(pointListData);
 }
Пример #10
0
        public List <string> GetPIPoints()
        {
            PIPointList   myPointList = new PIPointList(PIPoint.FindPIPoints(_pi, "*"));
            List <string> piPointList = new List <string> {
            };

            foreach (PIPoint point in myPointList)
            {
                piPointList.Add(point.Name);
            }
            return(piPointList);
        }
 public bool ValidateTagNames(string[] piPoints)
 {
     try
     {
         IList <PIPoint> piPointList = PIPoint.FindPIPoints(piServer, piPoints);
         pointList = new PIPointList(piPointList);
         return(true);
     }
     catch
     {
         return(false);
     }
 }
Пример #12
0
        public static AFListResults <PIPoint, AFValue> ReadValuesFromPi(string[] tagnam)
        {
            IList <PIPoint> points = PIPoint.FindPIPoints(piServer, tagnam);

            // Create an PIPointList object in order to make the bulk call later.
            PIPointList pointList = new PIPointList(points);

            if (pointList == null)
            {
                return(null);
            }

            // MAKE A BULK CALL TO THE PI DATA ARCHIVE
            return(pointList.CurrentValue()); // Requires AF SDK 2.7+
        }
Пример #13
0
        /// <summary>
        /// todo: needs refactoring to remove the if and separate the logic between backfill and not backfill
        /// </summary>
        /// <param name="provider"></param>
        /// <returns></returns>
        private List <AFTimeRange> GetTimeRanges(PIPointsProvider provider)
        {
            DateTime startTime;
            DateTime endTime;

            // when backfilling, we will get the oldest timestamp in the snapshot
            if (_backfill)
            {
                startTime = DateTime.MaxValue;
                int i = 0;
                foreach (var tagChunk in provider.GetPointsByChunks(Settings.General.Default.BackfillTagsChunkSize))
                {
                    i++;
                    _logger.InfoFormat("Looking for minimum snapshot time in the data for tag chunk: {0} - chunk size: {1}", i, Settings.General.Default.BackfillTagsChunkSize);
                    var pointsList = new PIPointList(tagChunk);
                    var time       = pointsList.CurrentValue().Min(v => v.Timestamp.LocalTime);
                    startTime = time < startTime ? time : startTime;
                }


                if (startTime < DateTime.Now - TimeSpan.FromDays(Settings.General.Default.ReplayTimeOffsetDays))
                {
                    startTime = Settings.General.Default.BackfillDefaultStartTime;
                }


                endTime        = DateTime.Now.ToLocalTime();
                _nextStartTime = endTime.AddSeconds(1);

                _logger.InfoFormat("Backfill start time: {0:G} - end time: {1:G}", startTime.ToLocalTime(), endTime.ToLocalTime());
            }
            else
            {
                startTime      = _nextStartTime;
                endTime        = DateTime.Now;
                _nextStartTime = endTime.AddSeconds(1);
            }


            var timeRanges =
                TimeStampsGenerator.GetAfTimeRanges(
                    TimeSpan.FromHours(Settings.General.Default.BackFillHoursPerDataChunk)
                    , startTime - _timeOffset
                    , endTime - _timeOffset);

            return(timeRanges);
        }
Пример #14
0
            /// <summary>
            /// Starts a query that will read data source values, given a set of point IDs and targets, over a time range.
            /// </summary>
            /// <param name="startTime">Start-time for query.</param>
            /// <param name="stopTime">Stop-time for query.</param>
            /// <param name="interval">Interval from Grafana request.</param>
            /// <param name="decimate">Flag that determines if data should be decimated over provided time range.</param>
            /// <param name="targetMap">Set of IDs with associated targets to query.</param>
            /// <returns>Queried data source data in terms of value and time.</returns>
            protected override IEnumerable <DataSourceValue> QueryDataSourceValues(DateTime startTime, DateTime stopTime, string interval, bool decimate, Dictionary <ulong, string> targetMap)
            {
                Dictionary <int, ulong> idMap  = new Dictionary <int, ulong>();
                PIPointList             points = new PIPointList();

                foreach (KeyValuePair <ulong, string> target in targetMap)
                {
                    ulong  metadataID = target.Key;
                    string pointTag   = target.Value;

                    if (!MetadataIDToPIPoint.TryGetValue(metadataID, out PIPoint point))
                    {
                        if (TryFindPIPoint(Connection, Metadata, GetPITagName(pointTag, PrefixRemoveCount), out point))
                        {
                            MetadataIDToPIPoint[metadataID] = point;
                        }
                    }

                    if ((object)point != null)
                    {
                        points.Add(point);
                        idMap[point.ID] = metadataID;
                    }
                }

                // Start data read from historian
                using (IEnumerator <AFValue> dataReader = ReadData(startTime, stopTime, points).GetEnumerator())
                {
                    while (dataReader.MoveNext())
                    {
                        AFValue currentPoint = dataReader.Current;

                        if (currentPoint == null)
                        {
                            continue;
                        }

                        yield return(new DataSourceValue
                        {
                            Target = targetMap[idMap[currentPoint.PIPoint.ID]],
                            Time = (currentPoint.Timestamp.UtcTime.Ticks - m_baseTicks) / (double)Ticks.PerMillisecond,
                            Value = Convert.ToDouble(currentPoint.Value),
                            Flags = ConvertStatusFlags(currentPoint.Status)
                        });
                    }
                }
            }
Пример #15
0
        /// <summary>
        /// Sends a number of events to each PI Point in a PI Point list.
        /// </summary>
        /// <remarks>
        /// By default the events' timestamp increments by 1 second and the values are calculated from the timestamps.
        /// If the eventsToSend parameter is specified then those events are used explicitly.
        /// </remarks>
        /// <param name="startTime">Start time used for event time stamps.</param>
        /// <param name="eventCount">Number of events to write to PI Data Archive.</param>
        /// <param name="piPoints">List of PI Points to which events will be written.</param>
        /// <param name="eventsToSend">OPTIONAL events to use (instead of being generated by routine).</param>
        public void SendTimeBasedPIEvents(AFTime startTime, int eventCount, List <PIPoint> piPoints, Dictionary <DateTime, double> eventsToSend = null)
        {
            // Build PI events as needed
            if (eventsToSend == null)
            {
                DateTime st = startTime;
                eventsToSend = new Dictionary <DateTime, double>();
                for (int i = 0; i < eventCount; i++)
                {
                    DateTime ts = st.AddSeconds(i);
                    eventsToSend.Add(ts, PIFixture.ConvertTimeStampToFloat(ts));
                }
            }

            object[]        vals       = eventsToSend.Values.Cast <object>().ToArray();
            DateTime[]      timeStamps = eventsToSend.Keys.ToArray();
            AFValueStatus[] statuses   = Enumerable.Range(0, eventCount).Select(_ => AFValueStatus.Good).ToArray();
            UOM             nullUOM    = null;

            var newValues = new List <AFValues>();
            var pointList = new PIPointList(piPoints);

            foreach (PIPoint pt in pointList)
            {
                var newAFValues = new AFValues(vals, timeStamps, statuses, nullUOM)
                {
                    PIPoint = pt,
                };
                newValues.Add(newAFValues);
            }

            if (newValues.Count == 0)
            {
                return;
            }

            // Send PI events
            foreach (AFValues values in newValues)
            {
                AFErrors <AFValue> errors = PIServer.UpdateValues(values.ToList(), AFUpdateOption.NoReplace);
                if (errors != null)
                {
                    throw errors.Errors.First().Value;
                }
            }
        }
        public void Run()
        {
            PIServers piServers = new PIServers();
            PIServer piServer = piServers["<PISERVER>"];

            IList<PIPoint> points = PIPoint.FindPIPoints(piServer, new[] { "sinusoid", "sinusoidu", "cdt158", "cdm158" });

            // Create an PIPointList object in order to make the bulk call later.
            PIPointList pointList = new PIPointList(points);

            if (pointList == null) return;

            // MAKE A BULK CALL TO THE PI DATA ARCHIVE
            AFListResults<PIPoint,AFValue> values = pointList.CurrentValue(); // Requires AF SDK 2.7+

            foreach (AFValue val in values)
            {
                Console.WriteLine("Point: {0}, Timestamp: {1}, Value: {2}", val.PIPoint, val.Timestamp, val.Value.ToString());
            }
        }
Пример #17
0
        public void GetPIData(string piDataArchiveName, string piPointName1, string piPointName2, string piPointName3, string startTime, string endTime, string interval)
        {
            IEnumerable <string> piPointNames = new List <string> {
                piPointName1, piPointName2, piPointName3
            };
            PIServer piServer = new PIServers()[piDataArchiveName];

            if (piServer == null)
            {
                return;
            }
            IList <PIPoint> points    = PIPoint.FindPIPoints(piServer, piPointNames);
            PIPointList     pointList = new PIPointList(points);
            AFTimeRange     timeRange = new AFTimeRange(new AFTime(startTime), new AFTime(endTime));
            AFTimeSpan      timeSpan;
            bool            result = AFTimeSpan.TryParse(interval, out timeSpan);

            if (result == false)
            {
                AFTimeSpan.TryParse("1h", out timeSpan);
            }
            IEnumerable <AFValues> valuesList = pointList.InterpolatedValues(timeRange, timeSpan, string.Empty, false, new PIPagingConfiguration(PIPageType.TagCount, 100));

            foreach (AFValues values in valuesList)
            {
                if (values.PIPoint.Name == piPointName1)
                {
                    values1 = values.Where(m => m.ValueTypeCode == TypeCode.Single || m.ValueTypeCode == TypeCode.Double).Select(m => m.ValueAsDouble()).ToArray();
                }
                else if (values.PIPoint.Name == piPointName2)
                {
                    values2 = values.Where(m => m.ValueTypeCode == TypeCode.Single || m.ValueTypeCode == TypeCode.Double).Select(m => m.ValueAsDouble()).ToArray();
                }
                else if (values.PIPoint.Name == piPointName3)
                {
                    values3 = values.Where(m => m.ValueTypeCode == TypeCode.Single || m.ValueTypeCode == TypeCode.Double).Select(m => m.ValueAsDouble()).ToArray();
                }
            }
        }
Пример #18
0
            private IEnumerable<AFValue> ReadData(AFTime startTime, AFTime endTime, PIPointList points)
            {
                try
                {
                    return new TimeSortedValueScanner
                    {
                        Points = points,
                        StartTime = startTime,
                        EndTime = endTime
                        //DataReadExceptionHandler = ex => OnProcessException(MessageLevel.Warning, ex)
                    }
                    .Read();
                }
                catch
                {
                    // Removed cached data source on read failure
                    if (DataSources.TryRemove(KeyName, out _))
                        MetadataIDToPIPoint.Clear();

                    throw;
                }
            }
Пример #19
0
        private void btnGetData_Click(object sender, EventArgs e)
        {
            _dt.Rows.Clear();

            PIPointList piPointList = new PIPointList();

            piPointList.AddRange(piPointTagSearchPage1.PIPoints);

            AFValues afValues = new AFValues();

            foreach (var piPoint in piPointList)
            {
                afValues.AddRange(piPoint.RecordedValues(new AFTimeRange(new AFTime(DateTime.SpecifyKind(dthInicio.Value, DateTimeKind.Local)), new AFTime(DateTime.SpecifyKind(dthFim.Value, DateTimeKind.Local))), AFBoundaryType.Inside, string.Empty, false));
            }

            foreach (var afValue in afValues)
            {
                _dt.Rows.Add(afValue.PIPoint.Name, (DateTime)afValue.Timestamp.LocalTime, afValue.Value, afValue.PIPoint.GetAttribute(PICommonPointAttributes.EngineeringUnits), afValue.GetAnnotation(), false, string.Empty);
            }

            dataGrid.DataSource = _dt;
        }
        public void PIDataPipeExample()
        {
            // Create point list containing our lab point and two known sinusoid points
            PIPointList pointList = new PIPointList();
            pointList.Add(PIPoint.FindPIPoint(myPIServer, "sinusoid"));
            pointList.Add(PIPoint.FindPIPoint(myPIServer, "sinusoidu"));
            _eventPipe = new PIDataPipe(AFDataPipeType.Snapshot);
            _eventPipe.AddSignups(pointList);
            // Configure a timer to read the pipe every five seconds for updates
            Timer eventPipeTimer = new Timer(new TimerCallback(ReadPipe), null, 0, 100);

            // Block until user wants to exit
            Console.WriteLine("Press Enter to terminate");
            Console.ReadLine();
            // Disable timer
            eventPipeTimer.Dispose();

            // Dispose of event pipe
            lock (_eventPipe)
            {
                _eventPipe.Dispose();
            }
        }
Пример #21
0
        public override void Run()
        {
            try
            {
                PiConnectionMgr piConnectionMgr = new PiConnectionMgr(Server);
                piConnectionMgr.Connect();

                PIServer pi = piConnectionMgr.GetPiServer();

                PIPointList pointList = new PIPointList(PIPoint.FindPIPoints(pi, TagMask));

                AFListResults <PIPoint, AFValue> values = pointList.CurrentValue();

                foreach (AFValue val in values)
                {
                    Logger.InfoFormat("The current value for PI Point {0} is : {1} - {2}", val.PIPoint, val.Timestamp, val.Value);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }
Пример #22
0
        public void Run()
        {
            PIServers piServers = new PIServers();
            PIServer  piServer  = piServers["<PISERVER>"];

            IList <PIPoint> points = PIPoint.FindPIPoints(piServer, new[] { "sinusoid", "sinusoidu", "cdt158", "cdm158" });

            // Create an PIPointList object in order to make the bulk call later.
            PIPointList pointList = new PIPointList(points);

            if (pointList == null)
            {
                return;
            }

            // MAKE A BULK CALL TO THE PI DATA ARCHIVE
            AFListResults <PIPoint, AFValue> values = pointList.CurrentValue(); // Requires AF SDK 2.7+

            foreach (AFValue val in values)
            {
                Console.WriteLine("Point: {0}, Timestamp: {1}, Value: {2}", val.PIPoint, val.Timestamp, val.Value.ToString());
            }
        }
Пример #23
0
        }//Initialize

        public static ErrorTypes LoadPIPointsFromFile()
        {
            //This method loads all PI points from configuration file into memory
            PIPoints_from_File = File.ReadAllLines(ConfigurationParameters.PIPointsFile);

            AFKeyedResults <string, PIPoint> loadedPoints_Source      = LoadPIPointsFromServer(ServerType.Source);
            AFKeyedResults <string, PIPoint> loadedPoints_Destination = LoadPIPointsFromServer(ServerType.Destination);

            if (loadedPoints_Source.Count == 0)
            {
                Logger.Log(Errors[ErrorTypes.NoPIPointsLoaded_Source], System.Diagnostics.EventLogEntryType.Error);
                return(ErrorTypes.NoPIPointsLoaded_Source);
            }

            if (loadedPoints_Destination.Count == 0)
            {
                Logger.Log(Errors[ErrorTypes.NoPIPointsLoaded_Destination], System.Diagnostics.EventLogEntryType.Error);
                return(ErrorTypes.NoPIPointsLoaded_Destination);
            }

            //Create the list of PIPoint objects from the actually loaded PI points
            CurrentPIPoints_Destination = loadedPoints_Destination.Select(p => p).ToList();
            CurrentPIPoints_Source      = loadedPoints_Source.Select(p => p).ToList();

            //Populate the rest of the PIPoints properties
            Count = CurrentPIPoints_Destination.Count;
            CurrentPIPoints_Source_PIPointList      = new PIPointList(CurrentPIPoints_Source);
            CurrentPIPoints_Destination_PIPointList = new PIPointList(CurrentPIPoints_Destination);

            //Create the point mapping dictionary
            //TODO: There has to be a more efficient way to do this
            Parallel.ForEach(CurrentPIPoints_Destination_PIPointList, point => CurrentPIPoints_Dictionary.Add(point.Name, point));

            //TODO: Add source server check
            Logger.Log("The application successfully loaded " + Count + " PI points.", System.Diagnostics.EventLogEntryType.Information);
            return(ErrorTypes.None);
        }//LoadPIPointsFromFile
Пример #24
0
        // TODO: Updated code for handling piped-events in AF-SDK
        //private void PipeOnOnNewValue()
        //{
        //    List<IMeasurement> measurements = new List<IMeasurement>();

        //    m_connection.Execute(server =>
        //    {
        //        PIEventObject eventobject;
        //        PointValue pointvalue;

        //        for (int i = 0; i < m_pipe.Count; i++)
        //        {
        //            eventobject = m_pipe.Take();

        //            // we will publish measurements for every action except deleted (possible dupes on updates)
        //            if (eventobject.Action != EventActionConstants.eaDelete)
        //            {
        //                try
        //                {
        //                    pointvalue = (PointValue)eventobject.EventData;

        //                    double value = Convert.ToDouble(pointvalue.PIValue.Value);
        //                    MeasurementKey key = m_tagKeyMap[pointvalue.PIPoint.Name];

        //                    Measurement measurement = new Measurement();
        //                    measurement.Key = key;
        //                    measurement.Timestamp = pointvalue.PIValue.TimeStamp.LocalDate.ToUniversalTime();
        //                    measurement.Value = value;
        //                    measurement.StateFlags = MeasurementStateFlags.Normal;

        //                    if (measurement.Timestamp > m_lastReceivedTimestamp.Ticks)
        //                        m_lastReceivedTimestamp = measurement.Timestamp;

        //                    measurements.Add(measurement);
        //                }
        //                catch
        //                {
        //                    /* squelch any errors on digital state data that can't be converted to a double */
        //                }
        //            }
        //        }
        //    });

        //    if (measurements.Any())
        //    {
        //        OnNewMeasurements(measurements);
        //        m_processedMeasurements += measurements.Count;
        //    }
        //}

        /// <summary>
        /// Disposes members for garbage collection
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (m_tagKeyMap != null)
            {
                m_tagKeyMap.Clear();
            }
            m_tagKeyMap = null;

            if ((object)m_connection != null)
            {
                m_connection.Dispose();
            }

            m_connection = null;
            m_points     = null;
            m_pipe       = null;

            m_measurements.Clear();
            m_measurements = null;

            if (m_dataThread != null)
            {
                m_dataThread.Abort();
                m_dataThread = null;
            }

            if (m_publishTimer != null)
            {
                m_publishTimer.Stop();
                m_publishTimer.Elapsed -= m_publishTimer_Tick;
                m_publishTimer.Dispose();
                m_publishTimer = null;
            }
        }
        public override void Run()
        {
            try
            {
                PiConnectionHelper piConnectionHelper = new PiConnectionHelper(Server);
                piConnectionHelper.Connect();

                PIServer pi = piConnectionHelper.GetPiServer();

                PIPointList pointList = new PIPointList(PIPoint.FindPIPoints(pi, TagMask));

                AFListResults<PIPoint, AFValue> values = pointList.CurrentValue();

                foreach (AFValue val in values)
                {
                    Logger.InfoFormat("The current value for PI Point {0} is : {1} - {2}", val.PIPoint, val.Timestamp, val.Value);
                }

            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }
Пример #26
0
        private void StopGettingData()
        {
            try
            {
                if (m_publishTimer != null)
                {
                    m_publishTimer.Elapsed -= m_publishTimer_Tick;
                    m_publishTimer.Stop();
                    m_publishTimer.Dispose();
                }
                m_publishTimer = null;


                if (m_dataThread != null)
                    m_dataThread.Abort();

                m_dataThread = null;

                m_points = null;
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception ex)
            {
                OnProcessException(ex);
            }
        }
Пример #27
0
        /// <summary>
        /// Starts threads and timers to poll the PI server for data
        /// </summary>
        /// <param name="state">Filter string which will get the desired points from PI</param>
        private void StartGettingData(object state)
        {
            try
            {
                string tagFilter = state.ToString();

                m_points = new PIPointList(PIPoint.FindPIPoints(m_connection.Server, tagFilter, true));

                m_dataThread = new Thread(QueryData);
                m_dataThread.IsBackground = true;
                m_dataThread.Start();

                m_publishTimer = new System.Timers.Timer();
                m_publishTimer.Interval = ProcessingInterval > 0 ? ProcessingInterval : 33;
                m_publishTimer.Elapsed += m_publishTimer_Tick;
                m_publishTimer.Start();
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception e)
            {
                OnProcessException(e);
            }
        }
Пример #28
0
        private void getSnapshot(object obj)
        {
            List <PIPoint> p = obj as List <PIPoint>;

            SetDataGridCallback _dataGridCallback = new SetDataGridCallback(SetDataTable);

            PIDataPipe pipe = new PIDataPipe(AFDataPipeType.Archive);

            pipe.AddSignups(p);

            //_dt.Rows.Clear();
            _dt = new DataTable();

            _dt.Columns.Add("Tag", typeof(string));
            _dt.Columns.Add("Timestamp", typeof(DateTime));
            _dt.Columns.Add("Value", typeof(object));
            _dt.Columns.Add("UOM", typeof(string));
            _dt.Columns.Add("Annotation", typeof(string));
            _dt.Columns.Add("CheckBox", typeof(bool));
            _dt.Columns.Add("Message", typeof(string));

            PIPointList piPointList = new PIPointList();

            piPointList.AddRange(p);

            AFValues afValues = new AFValues();

            foreach (var piPoint in piPointList)
            {
                afValues.Add(piPoint.CurrentValue());
            }


            foreach (var afValue in afValues)
            {
                _dt.Rows.Add(afValue.PIPoint.Name, (DateTime)afValue.Timestamp.LocalTime, afValue.Value, afValue.PIPoint.GetAttribute(PICommonPointAttributes.EngineeringUnits), afValue.GetAnnotation(), false, string.Empty);
            }


            this.Invoke(_dataGridCallback, _dt);


            while (chkShowSnapshot.Checked == true)
            {
                AFListResults <PIPoint, AFDataPipeEvent> pipeConstants = pipe.GetUpdateEvents(5000);

                foreach (AFDataPipeEvent pipeEvent in pipeConstants)
                {
                    foreach (DataRow row in _dt.Rows)
                    {
                        if (row["Tag"] == pipeEvent.Value.PIPoint.Name)
                        {
                            row["Timestamp"]  = pipeEvent.Value.Timestamp.LocalTime;
                            row["Value"]      = pipeEvent.Value.Value;
                            row["UOM"]        = pipeEvent.Value.PIPoint.GetAttribute(PICommonPointAttributes.EngineeringUnits);
                            row["Annotation"] = pipeEvent.Value.GetAnnotation();
                        }
                    }
                }

                if (this.dataGrid.InvokeRequired)
                {
                    this.Invoke(_dataGridCallback, _dt);
                }
                else
                {
                    dataGrid.DataSource = _dt;
                    dataGrid.Refresh();
                }
            }
            ;
            pipe.Close();
            pipe.Dispose();
        }
Пример #29
0
        // Kick start read process for historian
        private void StartDataReader(object state)
        {
            try
            {
                if (SupportsTemporalProcessing)
                {
                    if ((object)RequestedOutputMeasurementKeys != null)
                        OnStatusMessage(MessageLevel.Info, $"Replaying for requested output keys: {RequestedOutputMeasurementKeys.Length:N0} defined measurements");
                    else
                        OnStatusMessage(MessageLevel.Warning, "No measurements have been requested for playback - make sure \"; connectOnDemand=true\" is defined in the connection string for the reader.");
                }

                MeasurementKey[] requestedKeys = SupportsTemporalProcessing ? RequestedOutputMeasurementKeys : OutputMeasurements.MeasurementKeys().ToArray();

                if (Enabled && (object)m_connection != null && (object)requestedKeys != null && requestedKeys.Length > 0)
                {
                    HashSet<string> tagList = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

                    var query = from row in DataSource.Tables["ActiveMeasurements"].AsEnumerable()
                                from key in requestedKeys
                                where row["ID"].ToString() == key.ToString()
                                select new
                                {
                                    Key = key,
                                    AlternateTag = row["AlternateTag"].ToString(),
                                    PointTag = row["PointTag"].ToString()
                                };

                    string tagName;
                    m_points = new PIPointList();
                    PIPoint point;

                    foreach (var result in query)
                    {
                        tagName = result.PointTag;

                        if (!string.IsNullOrWhiteSpace(result.AlternateTag))
                            tagName = result.AlternateTag;

                        if (tagList.Add(tagName) && PIPoint.TryFindPIPoint(m_connection.Server, tagName, out point))
                        {
                            m_tagKeyMap[point.ID] = result.Key;
                            m_points.Add(point);
                        }
                    }

                    m_publicationTime = 0;

                    // Start data read from historian
                    lock (m_readTimer)
                    {
                        m_startTime = base.StartTimeConstraint < DateTime.MinValue ? DateTime.MinValue : base.StartTimeConstraint > DateTime.MaxValue ? DateTime.MaxValue : base.StartTimeConstraint;
                        m_stopTime = base.StopTimeConstraint < DateTime.MinValue ? DateTime.MinValue : base.StopTimeConstraint > DateTime.MaxValue ? DateTime.MaxValue : base.StopTimeConstraint;

                        m_dataReader = ReadData(m_startTime, m_stopTime).GetEnumerator();

                        m_readTimer.Enabled = m_dataReader.MoveNext();

                        if (m_readTimer.Enabled)
                        {
                            OnStatusMessage(MessageLevel.Info, "Starting historical data read...");
                        }
                        else
                        {
                            OnStatusMessage(MessageLevel.Info, "No historical data was available to read for given time frame.");
                            OnProcessingComplete();
                        }
                    }
                }
                else
                {
                    m_readTimer.Enabled = false;
                    OnStatusMessage(MessageLevel.Info, "No measurement keys have been requested for reading, historian reader is idle.");
                    OnProcessingComplete();
                }
            }
            catch (Exception ex)
            {
                OnProcessException(MessageLevel.Warning, new InvalidOperationException($"Could not start historical data read due to exception: {ex.Message}", ex));
            }
        }
        public void PIDataPipeTimeSeriesTest(PIPointType piPointType, object[] eventValues)
        {
            Contract.Requires(eventValues != null);

            const string PointName = "PIDataPipeTests_PIPoint";

            AFDatabase db         = AFFixture.AFDatabase;
            PIServer   piServer   = PIFixture.PIServer;
            var        piDataPipe = new PIDataPipe(AFDataPipeType.TimeSeries);

            var piPointList = new PIPointList();
            var now         = AFTime.NowInWholeSeconds;

            try
            {
                Output.WriteLine("Create the Future PI Points with Zero Compression and specified PI Point type.");
                PIFixture.DeletePIPoints(PointName + "*", Output);
                var testPIPoints = PIFixture.CreatePIPoints(PointName + "###", eventValues.Length, new Dictionary <string, object>
                {
                    { PICommonPointAttributes.PointType, piPointType },
                    { PICommonPointAttributes.ExceptionDeviation, 0 },
                    { PICommonPointAttributes.ExceptionMaximum, 0 },
                    { PICommonPointAttributes.Compressing, 0 },
                    { PICommonPointAttributes.DigitalSetName, "Phases" },
                    { PICommonPointAttributes.Future, true },
                });
                Assert.True(testPIPoints.Count() == eventValues.Length, $"Unable to create all the test PI Points.");
                piPointList.AddRange(testPIPoints);

                // Add the PI Point as sign up to the PIDataPipe.
                Output.WriteLine($"Sign up all PI Points with PIDataPipe.");
                var afErrors           = piDataPipe.AddSignups(piPointList);
                var prefixErrorMessage = "Adding sign ups to the PIDataPipe was unsuccessful.";
                Assert.True(afErrors == null,
                            userMessage: afErrors?.Errors.Aggregate(prefixErrorMessage, (msg, error) => msg += $" PI Point: [{error.Key.Name}] Error: [{error.Value.Message}] "));

                // Write one data value to each PI Point.
                var expectedAFValues = new AFValues();
                for (int i = 0; i < eventValues.Length; i++)
                {
                    AFValue afValue   = null;
                    var     timestamp = now + TimeSpan.FromMinutes(i - eventValues.Length);

                    // Special Handling of Input Data for Digital and Timestamp
                    switch (piPointType)
                    {
                    case PIPointType.Digital:
                        afValue = new AFValue(new AFEnumerationValue("Phases", (int)eventValues[i]), timestamp);
                        break;

                    case PIPointType.Timestamp:
                        afValue = new AFValue(new AFTime(eventValues[i], now), timestamp);
                        break;

                    default:
                        afValue = new AFValue(eventValues[i], timestamp);
                        break;
                    }

                    Output.WriteLine($"Writing Value [{eventValues[i]}] with Timestamp [{timestamp}] to PI Point [{piPointList[i].Name}].");
                    piPointList[i].UpdateValue(afValue, AFUpdateOption.InsertNoCompression);

                    // If writing digital states, we need to save the corresponding value for verification.
                    // Since we are using Phases, 0 ~ Phase1, 1 ~ Phase2, etc.
                    if (piPointType == PIPointType.Digital)
                    {
                        int input = (int)eventValues[i];
                        afValue = new AFValue(new AFEnumerationValue($"Phase{input + 1}", input), timestamp);
                    }

                    afValue.PIPoint = piPointList[i];
                    expectedAFValues.Add(afValue);
                }

                // Retry assert to retrieve expected Update Events from the PIDataPipe
                var actualAFValues = new AFValues();
                Output.WriteLine($"Reading Events from the PI DataPipe.");
                AssertEventually.True(() =>
                {
                    var updateEvents = piDataPipe.GetUpdateEvents(eventValues.Length);

                    prefixErrorMessage = "Retrieving Update Events from the PIDataPipe was unsuccessful.";
                    Assert.False(updateEvents.HasErrors,
                                 userMessage: updateEvents.Errors?.Aggregate(prefixErrorMessage, (msg, error) => msg += $" PI Point: [{error.Key.Name}] Error: [{error.Value.Message}] "));

                    actualAFValues.AddRange(updateEvents.Results.Select(update => update.Value));
                    if (actualAFValues.Count >= expectedAFValues.Count)
                    {
                        // Verify that all expected update events are received from the PIDataPipe
                        Assert.True(expectedAFValues.Count == actualAFValues.Count, "PIDataPipe returned more events than expected. " +
                                    $"Expected Count: {expectedAFValues.Count}, Actual Count: {actualAFValues.Count}.");
                        return(true);
                    }

                    return(false);
                },
                                      TimeSpan.FromSeconds(5),
                                      TimeSpan.FromSeconds(0.5),
                                      "Unable to retrieve events within the time frame.");

                // Verify all received events.
                Output.WriteLine($"Verifying all {actualAFValues.Count} events from the PI DataPipe.");
                for (int i = 0; i < actualAFValues.Count; i++)
                {
                    // Special handling of Output events for Timestamp
                    if (piPointType == PIPointType.Timestamp)
                    {
                        actualAFValues[i].Value = new AFTime(actualAFValues[i].Value, now);
                    }

                    AFFixture.CheckAFValue(actualAFValues[i], expectedAFValues[i]);
                    Assert.True(object.Equals(actualAFValues[i].PIPoint, expectedAFValues[i].PIPoint),
                                $"Unexpected PI Point Association. Expected: [{expectedAFValues[i].PIPoint}], Actual: [{actualAFValues[i].PIPoint}].");
                }

                // Remove all sign ups from the PIDataPipe
                Output.WriteLine($"Remove all PI Point sign ups from PIDataPipe.");
                afErrors           = piDataPipe.RemoveSignups(piPointList);
                prefixErrorMessage = "Removing sign ups to the PIDataPipe was unsuccessful.";
                Assert.True(afErrors == null,
                            userMessage: afErrors?.Errors.Aggregate(prefixErrorMessage, (msg, error) => msg += $" PI Point: [{error.Key.Name}] Error: [{error.Value.Message}] "));

                // Write dummy values to the PI Points and confirm PI DataPipe receives none.
                Output.WriteLine($"Write dummy values to the PI Points.");
                for (int i = 0; i < eventValues.Length; i++)
                {
                    piPointList[i].UpdateValue(new AFValue(eventValues[i], now), AFUpdateOption.InsertNoCompression);
                }

                Output.WriteLine($"Verify no events are received by the PIDataPipe.");
                var noEvents = piDataPipe.GetUpdateEvents(eventValues.Length);
                prefixErrorMessage = "Retrieving Update Events from the PIDataPipe was unsuccessful.";
                Assert.False(noEvents.HasErrors,
                             userMessage: noEvents.Errors?.Aggregate(prefixErrorMessage, (msg, error) => msg += $" PI Point: [{error.Key.Name}] Error: [{error.Value.Message}] "));

                Assert.True(noEvents.Count == 0, "PIDataPipe received events even after removing all sign ups.");
            }
            finally
            {
                piDataPipe.RemoveSignups(piPointList);
                piDataPipe.Dispose();
                PIFixture.DeletePIPoints(PointName + "*", Output);
            }
        }
Пример #31
0
        /// <summary>
        /// This method splits a point list into severall smaller lists and perform bulk calls on each list
        /// In parallel.
        /// </summary>
        private static void RecordedBulkParallel(
            IEnumerable <PIPoint> PiPoints,
            AFTimeRange timeRange,
            int maxDegOfParallel,
            int bulkParallelChunkSize,
            int bulkPageSize,
            bool insertNoData,
            Action <List <AFValue> > insertData,
            CancellationToken cancelToken)
        {
            _logger.WarnFormat("QUERY (BULK-P) # - PERIOD: {3} to {4} - MAX DEG. PAR. {0}, TAG_CHUNK_SIZE {1}, TAG_PAGE_SIZE {2},", maxDegOfParallel, bulkParallelChunkSize, bulkPageSize, timeRange.StartTime, timeRange.EndTime);

            // PARALLEL bulk
            var pointListList = PiPoints.ToList().ChunkBy(bulkParallelChunkSize);

            Parallel.ForEach(pointListList, new ParallelOptions {
                MaxDegreeOfParallelism = maxDegOfParallel, CancellationToken = cancelToken
            },
                             (pts, state, index) =>
            {
                PIPagingConfiguration pagingConfiguration = new PIPagingConfiguration(PIPageType.TagCount, bulkPageSize);
                PIPointList pointList = new PIPointList(pts);

                try
                {
                    // _logger.InfoFormat("Bulk query");
                    IEnumerable <AFValues> data = pointList.RecordedValues(timeRange,
                                                                           AFBoundaryType.Inside, String.Empty, false, pagingConfiguration).ToList();


                    _logger.InfoFormat("READ Recorded values between {0:G} and {1:G}. {2} values found", timeRange.StartTime.LocalTime, timeRange.EndTime.LocalTime, data.Sum(x => x.Count));

                    List <AFValue> singleListData = new List <AFValue>();


                    // inserting no data when backfilling if no data is found in the period
                    if (insertNoData)
                    {
                        foreach (var valuesInPoint in data)
                        {
                            if (valuesInPoint.Count == 0)
                            {
                                var value     = AFValue.CreateSystemStateValue(AFSystemStateCode.NoData, timeRange.EndTime);
                                value.PIPoint = valuesInPoint.PIPoint;
                                singleListData.Add(value);
                            }
                        }
                    }


                    singleListData.AddRange(data.SelectMany(x => x).ToList());

                    if (singleListData.Count == 0)
                    {
                        return;
                    }

                    insertData(singleListData);

                    _logger.DebugFormat("returned {0} values to be written", singleListData.Count);
                }
                catch (OperationCanceledException ex)
                {
                    _logger.Error(ex);
                    _logger.Error(pagingConfiguration.Error);
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
            });
        }
Пример #32
0
        private static void RecordedBulk(
            IEnumerable <PIPoint> PiPoints,
            AFTimeRange timeRange,
            int bulkPageSize,
            bool insertNoData,
            Action <List <AFValue> > insertData)
        {
            _logger.WarnFormat("QUERY (BULK) # - PERIOD: {1} to {2}, TAG_PAGE_SIZE {0},", bulkPageSize, timeRange.StartTime, timeRange.EndTime);


            PIPagingConfiguration pagingConfiguration = new PIPagingConfiguration(PIPageType.TagCount, bulkPageSize);
            PIPointList           pointList           = new PIPointList(PiPoints);

            try
            {
                // _logger.InfoFormat("Bulk query");
                IEnumerable <AFValues> data = pointList.RecordedValues(timeRange,
                                                                       AFBoundaryType.Inside, String.Empty, false, pagingConfiguration).ToList();


                _logger.InfoFormat("READ Recorded values between {0:G} and {1:G}. {2} values found", timeRange.StartTime.LocalTime, timeRange.EndTime.LocalTime, data.Sum(x => x.Count));

                List <AFValue> singleListData = new List <AFValue>();


                // inserting no data when backfilling if no data is found in the period
                if (insertNoData)
                {
                    foreach (var valuesInPoint in data)
                    {
                        if (valuesInPoint.Count == 0)
                        {
                            var value = AFValue.CreateSystemStateValue(AFSystemStateCode.NoData, timeRange.EndTime);
                            value.PIPoint = valuesInPoint.PIPoint;
                            singleListData.Add(value);
                        }
                    }
                }


                singleListData.AddRange(data.SelectMany(x => x).ToList());

                if (singleListData.Count == 0)
                {
                    return;
                }

                insertData(singleListData);

                _logger.DebugFormat("returned {0} values to be written", singleListData.Count);
            }
            catch (OperationCanceledException ex)
            {
                _logger.Error(ex);
                _logger.Error(pagingConfiguration.Error);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
            }
        }
Пример #33
0
        // Kick start read process for historian
        private void StartDataReader(object state)
        {
            try
            {
                if (SupportsTemporalProcessing)
                {
                    if ((object)RequestedOutputMeasurementKeys != null)
                    {
                        OnStatusMessage(MessageLevel.Info, $"Replaying for requested output keys: {RequestedOutputMeasurementKeys.Length:N0} defined measurements");
                    }
                    else
                    {
                        OnStatusMessage(MessageLevel.Warning, "No measurements have been requested for playback - make sure \"; connectOnDemand=true\" is defined in the connection string for the reader.");
                    }
                }

                MeasurementKey[] requestedKeys = SupportsTemporalProcessing ? RequestedOutputMeasurementKeys : OutputMeasurements.MeasurementKeys().ToArray();

                if (Enabled && (object)m_connection != null && (object)requestedKeys != null && requestedKeys.Length > 0)
                {
                    HashSet <string> tagList = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

                    var query = from row in DataSource.Tables["ActiveMeasurements"].AsEnumerable()
                                from key in requestedKeys
                                where row["ID"].ToString() == key.ToString()
                                select new
                    {
                        Key          = key,
                        AlternateTag = row["AlternateTag"].ToString(),
                        PointTag     = row["PointTag"].ToString()
                    };

                    string tagName;
                    m_points = new PIPointList();
                    PIPoint point;

                    foreach (var result in query)
                    {
                        tagName = result.PointTag;

                        if (!string.IsNullOrWhiteSpace(result.AlternateTag))
                        {
                            tagName = result.AlternateTag;
                        }

                        if (tagList.Add(tagName) && PIPoint.TryFindPIPoint(m_connection.Server, tagName, out point))
                        {
                            m_tagKeyMap[point.ID] = result.Key;
                            m_points.Add(point);
                        }
                    }

                    m_publicationTime = 0;

                    // Start data read from historian
                    lock (m_readTimer)
                    {
                        m_startTime = base.StartTimeConstraint <DateTime.MinValue?DateTime.MinValue : base.StartTimeConstraint> DateTime.MaxValue ? DateTime.MaxValue : base.StartTimeConstraint;
                        m_stopTime  = base.StopTimeConstraint <DateTime.MinValue?DateTime.MinValue : base.StopTimeConstraint> DateTime.MaxValue ? DateTime.MaxValue : base.StopTimeConstraint;

                        m_dataReader = ReadData(m_startTime, m_stopTime).GetEnumerator();

                        m_readTimer.Enabled = m_dataReader.MoveNext();

                        if (m_readTimer.Enabled)
                        {
                            OnStatusMessage(MessageLevel.Info, "Starting historical data read...");
                        }
                        else
                        {
                            OnStatusMessage(MessageLevel.Info, "No historical data was available to read for given time frame.");
                            OnProcessingComplete();
                        }
                    }
                }
                else
                {
                    m_readTimer.Enabled = false;
                    OnStatusMessage(MessageLevel.Info, "No measurement keys have been requested for reading, historian reader is idle.");
                    OnProcessingComplete();
                }
            }
            catch (Exception ex)
            {
                OnProcessException(MessageLevel.Warning, new InvalidOperationException($"Could not start historical data read due to exception: {ex.Message}", ex));
            }
        }
Пример #34
0
        internal void Execute(string command, PIPointList pointsList, AFTime st, AFTime et,
                              AFTimeSpan summaryDuration, string[] times, string addlparam1, PIServer myServer)
        {
            try
            {
                Console.WriteLine();
                switch (command)
                {
                case "snap":
                {
                    var sb = new StringBuilder();
                    sb.AppendLine($"Point Name(Point Id), Timestamp, Current Value");
                    sb.AppendLine(new string('-', 45));
                    AFListResults <PIPoint, AFValue> results = pointsList.EndOfStream();
                    if (results.HasErrors)
                    {
                        foreach (var e in results.Errors)
                        {
                            sb.AppendLine($"{e.Key}: {e.Value}");
                        }
                    }
                    foreach (var v in results.Results)
                    {
                        if (!results.Errors.ContainsKey(v.PIPoint))
                        {
                            sb.AppendLine($"{string.Concat($"{v.PIPoint.Name} ({v.PIPoint.ID})"),-15}," +
                                          $" {v.Timestamp}, {v.Value}");
                        }
                    }
                    sb.AppendLine();
                    Console.Write(sb.ToString());
                    break;
                }

                case "arclist":
                {
                    AFTimeRange timeRange = new AFTimeRange(st, et);
                    if (!Int32.TryParse(addlparam1, out int maxcount))
                    {
                        maxcount = 0;
                    }

                    // Holds the results keyed on the associated point
                    var resultsMap   = new Dictionary <PIPoint, AFValues>();
                    var pagingConfig = new PIPagingConfiguration(PIPageType.TagCount, GlobalConfig.PageSize);
                    IEnumerable <AFValues> listResults = pointsList.RecordedValues(timeRange: timeRange,
                                                                                   boundaryType: AFBoundaryType.Inside,
                                                                                   filterExpression: null,
                                                                                   includeFilteredValues: false,
                                                                                   pagingConfig: pagingConfig,
                                                                                   maxCount: maxcount
                                                                                   );
                    foreach (var pointResults in listResults)
                    {
                        resultsMap[pointResults.PIPoint] = pointResults;
                    }
                    foreach (var pointValues in resultsMap)
                    {
                        var sb = new StringBuilder();
                        sb.AppendLine($"Point: {pointValues.Key} Archive Values " +
                                      $"Count: {pointValues.Value.Count}");
                        sb.AppendLine(new string('-', 45));
                        pointValues.Value.ForEach(v => sb.AppendLine($"{v.Timestamp}, {v.Value}"));
                        sb.AppendLine();
                        Console.Write(sb.ToString());
                    }
                    break;
                }

                case "plot":
                {
                    AFTimeRange timeRange = new AFTimeRange(st, et);
                    if (!Int32.TryParse(addlparam1, out int intervals))
                    {
                        intervals = 640;         //horizontal pixels in the trend
                    }
                    var resultsMap   = new Dictionary <PIPoint, AFValues>();
                    var pagingConfig = new PIPagingConfiguration(PIPageType.TagCount, GlobalConfig.PageSize);
                    IEnumerable <AFValues> listResults = pointsList.PlotValues(timeRange: timeRange,
                                                                               intervals: intervals,
                                                                               pagingConfig: pagingConfig
                                                                               );
                    foreach (var pointResults in listResults)
                    {
                        resultsMap[pointResults.PIPoint] = pointResults;
                    }
                    foreach (var pointValues in resultsMap)
                    {
                        var sb = new StringBuilder();
                        sb.AppendLine($"Point: {pointValues.Key} Plot Values Interval: {intervals}" +
                                      $" Count: {pointValues.Value.Count}");
                        sb.AppendLine(new string('-', 45));
                        pointValues.Value.ForEach(v => sb.AppendLine($"{v.Timestamp}, {v.Value}"));
                        sb.AppendLine();
                        Console.Write(sb.ToString());
                    }
                    break;
                }

                case "interp":
                {
                    AFTimeRange timeRange    = new AFTimeRange(st, et);
                    var         resultsMap   = new Dictionary <PIPoint, AFValues>();
                    var         pagingConfig = new PIPagingConfiguration(PIPageType.TagCount, GlobalConfig.PageSize);

                    if (addlparam1.StartsWith("c="))
                    {
                        if (!Int32.TryParse(addlparam1.Substring(2), out int count))
                        {
                            count = 10;         //default count
                        }
                        IEnumerable <AFValues> listResults = pointsList.InterpolatedValuesByCount(timeRange: timeRange,
                                                                                                  numberOfValues: count,
                                                                                                  filterExpression: null,
                                                                                                  includeFilteredValues: false,
                                                                                                  pagingConfig: pagingConfig
                                                                                                  );
                        foreach (var pointResults in listResults)
                        {
                            resultsMap[pointResults.PIPoint] = pointResults;
                        }
                        foreach (var pointValues in resultsMap)
                        {
                            var sb = new StringBuilder();
                            sb.AppendLine($"Point: {pointValues.Key} Interpolated Values " +
                                          $"Count: {pointValues.Value.Count}");
                            sb.AppendLine(new string('-', 45));
                            pointValues.Value.ForEach(v => sb.AppendLine($"{v.Timestamp}, {v.Value}"));
                            sb.AppendLine();
                            Console.Write(sb.ToString());
                        }
                    }
                    else
                    {
                        if (!AFTimeSpan.TryParse(addlparam1, out AFTimeSpan interval) || interval == new AFTimeSpan(0))
                        {
                            interval = summaryDuration;
                        }

                        IEnumerable <AFValues> listResults = pointsList.InterpolatedValues(timeRange: timeRange,
                                                                                           interval: interval,
                                                                                           filterExpression: null,
                                                                                           includeFilteredValues: false,
                                                                                           pagingConfig: pagingConfig
                                                                                           );
                        foreach (var pointResults in listResults)
                        {
                            resultsMap[pointResults.PIPoint] = pointResults;
                        }
                        foreach (var pointValues in resultsMap)
                        {
                            var sb = new StringBuilder();
                            sb.AppendLine($"Point: {pointValues.Key} Interpolated Values " +
                                          $"Interval: {interval.ToString()}");
                            sb.AppendLine(new string('-', 45));
                            pointValues.Value.ForEach(v => sb.AppendLine($"{v.Timestamp}, {v.Value}"));
                            sb.AppendLine();
                            Console.Write(sb.ToString());
                        }
                    }
                    break;
                }

                case "summaries":
                {
                    var resultsMap   = new Dictionary <PIPoint, AFValues>();
                    var pagingConfig = new PIPagingConfiguration(PIPageType.TagCount, GlobalConfig.PageSize);
                    if (st > et)         //summaries cannot handle reversed times
                    {
                        var temp = st;
                        st = et;
                        et = temp;
                    }
                    AFTimeRange        timeRange           = new AFTimeRange(st, et);
                    var                intervalDefinitions = new AFTimeIntervalDefinition(timeRange, 1);
                    AFCalculationBasis calculationBasis    = AFCalculationBasis.EventWeighted;
                    if (addlparam1 == "t")
                    {
                        calculationBasis = AFCalculationBasis.TimeWeighted;
                    }

                    foreach (var pt in pointsList)
                    {
                        var summaryType = AFSummaryTypes.All;
                        if (pt.PointType == PIPointType.Digital ||
                            pt.PointType == PIPointType.Timestamp ||
                            pt.PointType == PIPointType.Blob ||
                            pt.PointType == PIPointType.String ||
                            pt.PointType == PIPointType.Null)
                        {
                            summaryType = AFSummaryTypes.AllForNonNumeric;
                        }
                        IDictionary <AFSummaryTypes, AFValues> summaries = pt.Summaries(new List <AFTimeIntervalDefinition>()
                            {
                                intervalDefinitions
                            },
                                                                                        reverseTime: false,
                                                                                        summaryType: summaryType,
                                                                                        calcBasis: calculationBasis,
                                                                                        timeType: AFTimestampCalculation.Auto
                                                                                        );
                        var sb = new StringBuilder();
                        sb.AppendLine($"Point: {pt.Name} {calculationBasis} Summary");
                        sb.AppendLine(new string('-', 45));
                        foreach (var s in summaries)
                        {
                            AFValues vals = s.Value;
                            foreach (var v in vals)
                            {
                                if (v.Value.GetType() != typeof(PIException))
                                {
                                    if (string.Compare(s.Key.ToString(), "Minimum", true) == 0 ||
                                        string.Compare(s.Key.ToString(), "Maximum", true) == 0)
                                    {
                                        sb.AppendLine($"{s.Key,-16}: {v.Value,-20} {v.Timestamp}");
                                    }
                                    else
                                    {
                                        sb.AppendLine($"{s.Key,-16}: {v.Value}");
                                    }
                                }
                                else
                                {
                                    sb.AppendLine($"{s.Key,-16}: {v}");
                                }
                            }
                        }
                        sb.AppendLine();
                        Console.Write(sb.ToString());
                    }

                    /*
                     * Non numeric tags in pointsList requires splitting of queries so the above is preferred.
                     * The below implementation works when there are no non-numeric types or one particular summary needs to be run
                     */
                    //var listResults = pointsList.Summaries(new List<AFTimeIntervalDefinition>() {
                    //                                                               intervalDefinitions },
                    //                                                               reverseTime: false,
                    //                                                               summaryTypes: AFSummaryTypes.All,
                    //                                                               calculationBasis: calculationBasis,
                    //                                                               timeType: AFTimestampCalculation.Auto,
                    //                                                               pagingConfig: pagingConfig
                    //                                                               );
                    //foreach (IDictionary<AFSummaryTypes, AFValues> summaries in listResults)
                    //{
                    //     foreach (IDictionary<AFSummaryTypes, AFValues> pointResults in listResults)
                    //    {
                    //            AFValues pointValues = pointResults[AFSummaryTypes.Average];
                    //            PIPoint point = pointValues.PIPoint;
                    //           //Map the results back to the point
                    //           resultsMap[point] = pointValues;
                    //     }
                    //}
                    break;
                }

                case "update":
                case "annotate":
                {
                    string         addlparam2   = string.Empty;
                    AFUpdateOption updateOption = AFUpdateOption.Replace;
                    AFBufferOption bufOption    = AFBufferOption.BufferIfPossible;
                    AFValue        val;
                    if (times.Length > 0)
                    {
                        addlparam1 = times[0];
                        if (times.Length > 1)
                        {
                            addlparam2 = times[1];
                        }
                    }
                    switch (addlparam1)
                    {
                    case "i":
                        updateOption = AFUpdateOption.Insert;
                        break;

                    case "nr":
                        updateOption = AFUpdateOption.NoReplace;
                        break;

                    case "ro":
                        updateOption = AFUpdateOption.ReplaceOnly;
                        break;

                    case "inc":
                        updateOption = AFUpdateOption.InsertNoCompression;
                        break;

                    case "rm":
                        updateOption = AFUpdateOption.Remove;
                        break;
                    }
                    switch (addlparam2)
                    {
                    case "dnb":
                        bufOption = AFBufferOption.DoNotBuffer;
                        break;

                    case "buf":
                        bufOption = AFBufferOption.Buffer;
                        break;
                    }
                    foreach (var pt in pointsList)
                    {
                        Console.WriteLine($"Point: {pt.Name} {command} ({updateOption} {bufOption})");
                        Console.WriteLine(new string('-', 45));
                        Console.Write("Enter timestamp: ");
                        var time = Console.ReadLine();

                        if (!AFTime.TryParse(time, out AFTime ts))
                        {
                            ParseArgs.PrintHelp("Invalid Timestamp");
                            break;
                        }
                        if (command == "update" ||
                            !(pt.RecordedValuesAtTimes(new List <AFTime>()
                            {
                                ts
                            }, AFRetrievalMode.Exact)[0].IsGood))
                        {
                            Console.Write("Enter new value: ");
                            var data = Console.ReadLine();
                            if (!Double.TryParse(data, out var value))
                            {
                                ParseArgs.PrintHelp("Invalid data");
                                break;
                            }
                            val = new AFValue(value, ts);
                        }
                        else
                        {
                            val = pt.RecordedValuesAtTimes(new List <AFTime>()
                                {
                                    ts
                                }, AFRetrievalMode.Exact)[0];
                        }
                        if (command == "annotate")
                        {
                            Console.Write("Enter annotation: ");
                            var ann = Console.ReadLine();
                            pt.SetAnnotation(val, ann);
                        }
                        pt.UpdateValue(value: val, option: updateOption, bufferOption: bufOption);
                        Console.WriteLine($"Successfully {command}d");
                    }
                    Console.WriteLine();
                    break;
                }

                case "delete":
                {
                    AFTimeRange timeRange = new AFTimeRange(st, et);

                    if (myServer.Supports(PIServerFeature.DeleteRange))
                    {
                        foreach (var pt in pointsList)
                        {
                            int delcount            = 0;
                            var sb                  = new StringBuilder();
                            var intervalDefinitions = new AFTimeIntervalDefinition(timeRange, 1);
                            //getting the count of events - optional
                            IDictionary <AFSummaryTypes, AFValues> summaries = pt.Summaries(new List <AFTimeIntervalDefinition>()
                                {
                                    intervalDefinitions
                                },
                                                                                            reverseTime: false,
                                                                                            summaryType: AFSummaryTypes.Count,
                                                                                            calcBasis: AFCalculationBasis.EventWeighted,
                                                                                            timeType: AFTimestampCalculation.Auto
                                                                                            );
                            foreach (var s in summaries)
                            {
                                AFValues vals = s.Value;
                                vals = s.Value;
                                foreach (var v in vals)
                                {
                                    if (v.Value.GetType() != typeof(PIException))
                                    {
                                        delcount = v.ValueAsInt32();         //count
                                    }
                                }
                            }
                            if (delcount > 0)
                            {
                                var errs = pt.ReplaceValues(timeRange, new List <AFValue>()
                                    {
                                    });
                                if (errs != null)
                                {
                                    foreach (var e in errs.Errors)
                                    {
                                        sb.AppendLine($"{e.Key}: {e.Value}");
                                        delcount--;
                                    }
                                }
                            }
                            sb.AppendLine($"Point: {pt.Name} Deleted {delcount} events");
                            sb.AppendLine(new string('-', 45));
                            sb.AppendLine();
                            Console.Write(sb.ToString());
                        }
                    }
                    else
                    {
                        foreach (var pt in pointsList)
                        {
                            int      delcount = 0;
                            var      sb       = new StringBuilder();
                            AFValues vals     = pt.RecordedValues(timeRange: timeRange,
                                                                  boundaryType: AFBoundaryType.Inside,
                                                                  filterExpression: null,
                                                                  includeFilteredValues: false,
                                                                  maxCount: 0
                                                                  );
                            delcount = vals.Count;
                            if (delcount > 0)
                            {
                                var errs = pt.UpdateValues(values: vals,
                                                           updateOption: AFUpdateOption.Remove,
                                                           bufferOption: AFBufferOption.BufferIfPossible);
                                if (errs != null)
                                {
                                    foreach (var e in errs.Errors)
                                    {
                                        sb.AppendLine($"{e.Key}: {e.Value}");
                                        delcount--;
                                    }
                                }
                            }
                            sb.AppendLine($"Point: {pt.Name} Deleted {delcount} events");
                            sb.AppendLine(new string('-', 45));
                            sb.AppendLine();
                            Console.Write(sb.ToString());
                        }
                    }
                    break;
                }

                case "sign,t":
                {
                    Dictionary <PIPoint, int> errPoints = pointsList.ToDictionary(key => key, value => 0);
                    //if (Int32.TryParse(myServer.ServerVersion.Substring(4, 3), out int srvbuild) && srvbuild >= 395);
                    if (myServer.Supports(PIServerFeature.TimeSeriesDataPipe))
                    {
                        PIDataPipe timeSeriesDatapipe = new PIDataPipe(AFDataPipeType.TimeSeries);
                        Console.WriteLine("Signing up for TimeSeries events");
                        var errs = timeSeriesDatapipe.AddSignups(pointsList);
                        if (errs != null)
                        {
                            foreach (var e in errs.Errors)
                            {
                                Console.WriteLine($"Failed timeseries signup: {e.Key}, {e.Value.Message}");
                                errPoints[e.Key]++;
                            }
                            foreach (var ep in errPoints)
                            {
                                if (ep.Value >= 1)
                                {
                                    pointsList.Remove(ep.Key);
                                }
                            }
                            if (pointsList.Count == 0)
                            {
                                ParseArgs.PrintHelp("No valid PI Points");
                                if (timeSeriesDatapipe != null)
                                {
                                    timeSeriesDatapipe.Close();
                                    timeSeriesDatapipe.Dispose();
                                }
                                return;
                            }
                        }
                        timeSeriesDatapipe.Subscribe(new DataPipeObserver("TimeSeries"));
                        Console.WriteLine("Subscribed Points (current value): ");
                        AFListResults <PIPoint, AFValue> results = pointsList.EndOfStream();
                        if (results.HasErrors)
                        {
                            foreach (var e in results.Errors)
                            {
                                Console.WriteLine($"{e.Key}: {e.Value}");
                            }
                        }
                        foreach (var v in results.Results)
                        {
                            if (!results.Errors.ContainsKey(v.PIPoint))
                            {
                                Console.WriteLine($"{v.PIPoint.Name,-12}, {v.Timestamp}, {v.Value}");
                            }
                        }
                        Console.WriteLine(new string('-', 45));

                        //Fetch timeseries events till user termination
                        while (!GlobalConfig.CancelSignups)
                        {
                            timeSeriesDatapipe.GetObserverEvents(GlobalConfig.PipeMaxEvtCount, out bool hasMoreEvents);
                            Thread.Sleep(GlobalConfig.PipeCheckFreq);
                        }
                        Console.WriteLine("Cancelling signups ...");
                        if (timeSeriesDatapipe != null)
                        {
                            timeSeriesDatapipe.Close();
                            timeSeriesDatapipe.Dispose();
                        }
                    }
                    else
                    {
                        ParseArgs.PrintHelp($"Time series not supported in Archive version {myServer.ServerVersion}");
                    }
                    break;
                }

                case "sign,as":
                case "sign,sa":
                case "sign,a":
                case "sign,s":
                {
                    bool       snapSubscribe            = false;
                    bool       archSubscribe            = false;
                    PIDataPipe snapDatapipe             = null;
                    PIDataPipe archDatapipe             = null;
                    Dictionary <PIPoint, int> errPoints = pointsList.ToDictionary(key => key, value => 0);
                    if (command.Substring(5).Contains("s"))
                    {
                        snapSubscribe = true;
                        snapDatapipe  = new PIDataPipe(AFDataPipeType.Snapshot);

                        Console.WriteLine("Signing up for Snapshot events");
                        var errs = snapDatapipe.AddSignups(pointsList);
                        snapDatapipe.Subscribe(new DataPipeObserver("Snapshot"));
                        if (errs != null)
                        {
                            foreach (var e in errs.Errors)
                            {
                                Console.WriteLine($"Failed snapshot signup: {e.Key}, {e.Value.Message}");
                                errPoints[e.Key]++;
                            }
                        }
                    }
                    if (command.Substring(5).Contains("a"))
                    {
                        archSubscribe = true;
                        archDatapipe  = new PIDataPipe(AFDataPipeType.Archive);
                        Console.WriteLine("Signing up for Archive events");
                        var errs = archDatapipe.AddSignups(pointsList);
                        if (errs != null)
                        {
                            foreach (var e in errs.Errors)
                            {
                                Console.WriteLine($"Failed archive signup: {e.Key}, {e.Value.Message}");
                                errPoints[e.Key]++;
                            }
                        }
                        archDatapipe.Subscribe(new DataPipeObserver("Archive "));
                    }

                    //remove unsubscribable points
                    int errorLimit = snapSubscribe ? 1 : 0;
                    if (archSubscribe)
                    {
                        errorLimit++;
                    }
                    foreach (var ep in errPoints)
                    {
                        if (ep.Value >= errorLimit)
                        {
                            pointsList.Remove(ep.Key);
                        }
                    }
                    if (pointsList.Count == 0)
                    {
                        ParseArgs.PrintHelp("No valid PI Points");
                        if (snapDatapipe != null)
                        {
                            snapDatapipe.Close();
                            snapDatapipe.Dispose();
                        }
                        if (archDatapipe != null)
                        {
                            archDatapipe.Close();
                            archDatapipe.Dispose();
                        }
                        return;
                    }
                    Console.WriteLine("Subscribed Points (current value): ");
                    //foreach (var p in pointsList)
                    //{
                    //    Console.WriteLine($"{p.Name,-12}, {p.EndOfStream().Timestamp}, {p.EndOfStream()}");
                    //}
                    AFListResults <PIPoint, AFValue> results = pointsList.EndOfStream();
                    if (results.HasErrors)
                    {
                        foreach (var e in results.Errors)
                        {
                            Console.WriteLine($"{e.Key}: {e.Value}");
                        }
                    }
                    foreach (var v in results.Results)
                    {
                        if (!results.Errors.ContainsKey(v.PIPoint))
                        {
                            Console.WriteLine($"{v.PIPoint.Name,-12}, {v.Timestamp}, {v.Value}");
                        }
                    }
                    Console.WriteLine(new string('-', 45));

                    //Fetch events from the data pipes
                    while (!GlobalConfig.CancelSignups)
                    {
                        if (snapSubscribe)
                        {
                            snapDatapipe.GetObserverEvents(GlobalConfig.PipeMaxEvtCount, out bool hasMoreEvents1);
                        }
                        if (archSubscribe)
                        {
                            archDatapipe.GetObserverEvents(GlobalConfig.PipeMaxEvtCount, out bool hasMoreEvents2);
                        }
                        Thread.Sleep(GlobalConfig.PipeCheckFreq);
                    }
                    Console.WriteLine("Cancelling signups ...");
                    if (snapDatapipe != null)
                    {
                        snapDatapipe.Close();
                        snapDatapipe.Dispose();
                    }
                    if (archDatapipe != null)
                    {
                        archDatapipe.Close();
                        archDatapipe.Dispose();
                    }
                }
                break;
                }
                Console.WriteLine(new string('~', 45));
            }
            catch (Exception ex)
            {
                ParseArgs.PrintHelp(ex.Message);
                if (myServer != null)
                {
                    myServer.Disconnect();
                    if (GlobalConfig.Debug)
                    {
                        Console.WriteLine($"Disconnecting from {myServer.Name}");
                    }
                }
            }
        }
Пример #35
0
        private void HandleNewMeasurementsRequest(MeasurementKey[] Keys)
        {
            OnStatusMessage("Received request for {0} keys...", new object[] { Keys.Count() });

            if (!IsConnected)
            {
                AttemptConnection();
            }

            var query = from row in DataSource.Tables["ActiveMeasurements"].AsEnumerable()
                        from key in Keys
                        where row["ID"].ToString().Split(':')[1] == key.ID.ToString()
                        select new
            {
                Key          = key,
                AlternateTag = row["ALTERNATETAG"].ToString(),
                PointTag     = row["POINTTAG"].ToString()
            };

            StringBuilder tagFilter = new StringBuilder();

            foreach (var row in query)
            {
                string tagname = row.PointTag;
                if (!String.IsNullOrWhiteSpace(row.AlternateTag))
                {
                    tagname = row.AlternateTag;
                }

                if (!m_tagKeyMap.ContainsKey(tagname))
                {
                    m_tagKeyMap.AddOrUpdate(tagname, row.Key, (k, v) => row.Key);
                }

                if (tagFilter.Length > 0)
                {
                    tagFilter.Append(" OR ");
                }

                tagFilter.Append(string.Format("tag='{0}'", tagname));
            }

            m_points = new PIPointList(PIPoint.FindPIPoints(m_connection.Server, tagFilter.ToString(), true));

            // TODO: Re-enable event pipe functionality in AF-SDK
            //bool useEventPipes;

            //// event pipes are only applicable if enabled in connection string and this is a real time session, not playback
            //useEventPipes = m_useEventPipes && StartTimeConstraint == DateTime.MinValue && StopTimeConstraint == DateTime.MaxValue;

            //if (useEventPipes)
            //{
            //    try
            //    {
            //        if (m_pipe != null)
            //            ((_DEventPipeEvents_Event)m_pipe).OnNewValue -= (_DEventPipeEvents_OnNewValueEventHandler)PipeOnOnNewValue;

            //        m_connection.Execute(server => m_pipe = m_points.Data.EventPipe);

            //        ((_DEventPipeEvents_Event)m_pipe).OnNewValue += (_DEventPipeEvents_OnNewValueEventHandler)PipeOnOnNewValue;
            //    }
            //    catch (ThreadAbortException)
            //    {
            //        throw;
            //    }
            //    catch (Exception e)
            //    {
            //        useEventPipes = false; // try to run with polling instead of event pipes;
            //        OnProcessException(e);
            //    }
            //}

            //if (!useEventPipes)
            //{
            // warn that we are going to use a different configuration here...
            if (m_useEventPipes)
            {
                OnStatusMessage("WARNING: PI adapter switching from event pipes to polling due to error or start/stop time constraints.");
            }

            // set up a new thread to do some long calls to PI and set up threads, timers, etc for polling
            StopGettingData();
            ThreadPool.QueueUserWorkItem(StartGettingData, tagFilter);
            //}

            //m_useEventPipes = useEventPipes;
        }
Пример #36
0
        static void Main(string[] args)
        {
            Console.WriteLine(new string('~', 45));
            if (GlobalConfig.Debug)
            {
                Console.WriteLine($"Main thread: {Thread.CurrentThread.ManagedThreadId}");
            }
            if (GlobalConfig.Debug)
            {
                Console.WriteLine($"Args length: {args.Length}");
            }

            var commandsList = new List <string>()
            {
                "snap",
                "sign,a",
                "sign,s",
                "sign,sa",
                "sign,as",
                "sign,t",
                "arclist",
                "interp",
                "plot",
                "summaries",
                "update",
                "annotate",
                "delete"
            };
            var      pointsList      = new PIPointList();
            var      command         = String.Empty;
            var      startTime       = String.Empty;
            var      endTime         = String.Empty;
            var      serverName      = String.Empty;
            var      addlparam1      = string.Empty;
            var      tagMasks        = new string[] { };
            var      times           = new string[] { };
            var      summaryDuration = new AFTimeSpan(TimeSpan.FromMinutes(10));
            var      st = new AFTime();
            var      et = new AFTime();
            PIServer myServer;

            try
            {
                var AppplicationArgs = new ParseArgs(args);
                if (!AppplicationArgs.CheckHelpVersionOrEmpty())
                {
                    return;
                }
                if (!AppplicationArgs.CheckCommandExists(commandsList, out command))
                {
                    return;
                }
                if (!AppplicationArgs.GetTagNames(out tagMasks))
                {
                    return;
                }
                if (!AppplicationArgs.GetAddlParams(command, ref times, ref startTime, ref endTime, ref addlparam1, ref serverName))
                {
                    return;
                }
            }
            catch (Exception ex)
            {
                ParseArgs.PrintHelp(ex.Message);
                return;
            }

            #region Connect Server, Verify Times and Points
            if (!String.IsNullOrEmpty(startTime) && !String.IsNullOrEmpty(endTime))
            {
                if (!AFTime.TryParse(startTime, out st))
                {
                    ParseArgs.PrintHelp($"Invalid start time {startTime}");
                    return;
                }
                if (!AFTime.TryParse(endTime, out et))
                {
                    ParseArgs.PrintHelp($"Invalid end time {endTime}");
                    return;
                }
                if (st == et) //same time or min case (from initialization)
                {
                    ParseArgs.PrintHelp("Incorrect or same time interval specified");
                    return;
                }
            }

            try
            {
                PIServers myServers = new PIServers();
                if (string.IsNullOrEmpty(serverName))
                {
                    if (GlobalConfig.Debug)
                    {
                        Console.WriteLine("Attempting connection to default server ...");
                    }
                    myServer = myServers.DefaultPIServer;
                }
                else if (myServers.Contains(serverName))
                {
                    if (GlobalConfig.Debug)
                    {
                        Console.WriteLine($"Attempting connection to {serverName} server ...");
                    }
                    myServer = myServers[serverName];
                }
                else
                {
                    ParseArgs.PrintHelp($"Server {serverName} not found in KST");
                    return;
                }
                if (myServer != null)
                {
                    myServer.ConnectionInfo.Preference = AFConnectionPreference.Any;
                    myServer.Connect();
                    Console.WriteLine($"Connected to {myServer.Name} as {myServer.CurrentUserIdentityString}");
                }
            }
            catch (Exception ex)
            {
                ParseArgs.PrintHelp("Server Connection error: " + ex.Message);
                return;
            }

            try
            {
                //foreach (var n in tagMasks)
                //{
                //    if (PIPoint.TryFindPIPoint(myServer, n, out PIPoint p))
                //    {
                //        if (!pointsList.Contains(p)) pointsList.Add(p);
                //        else Console.WriteLine($"Duplicate point {p.Name}");
                //    }
                //    else
                //    {
                //        Console.WriteLine($"Point {n} not found");
                //    }
                //}
                pointsList.AddRange(PIPoint.FindPIPoints(myServer, new List <string>(tagMasks), null));
                if (pointsList.Count == 0)
                {
                    ParseArgs.PrintHelp("No valid PI Points");
                    myServer.Disconnect();
                    return;
                }
            }
            catch (Exception ex)
            {
                ParseArgs.PrintHelp("Tagmask error " + ex.Message);
                return;
            }
            #endregion

            //Handle KeyPress event from the user
            Console.CancelKeyPress += (sender, eventArgs) =>
            {
                if (GlobalConfig.Debug)
                {
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                }
                Console.WriteLine();
                Console.WriteLine("Program termination received from user ...");
                if (command == "sign,s" || command == "sign,as" || command == "sign,sa" || command == "sign,a" || command == "sign,t")
                {
                    GlobalConfig.CancelSignups = true;
                    Thread.Sleep(Convert.ToInt32(GlobalConfig.PipeCheckFreq * 1.2));
                }
                else
                {
                    if (myServer != null)
                    {
                        myServer.Disconnect();
                    }
                    Console.WriteLine(new string('~', 45));
                }
            };

            var Exec = new ExecuteCommand();
            if (GlobalConfig.Debug)
            {
                Console.WriteLine($"Command executing: {command}");
            }
            Exec.Execute(command, pointsList, st, et, summaryDuration, times, addlparam1, myServer);
            bool isexec = true;

            if (myServer != null)
            {
                myServer.Disconnect();
                if (GlobalConfig.Debug)
                {
                    Console.WriteLine($"Disconnecting from {myServer.Name}");
                }
            }
            if (!isexec)
            {
                Console.WriteLine(new string('~', 45));
            }
        }
Пример #37
0
        private void HandleNewMeasurementsRequest(MeasurementKey[] Keys)
        {
            OnStatusMessage("Received request for {0} keys...", new object[] { Keys.Count() });

            if (!IsConnected)
                AttemptConnection();

            var query = from row in DataSource.Tables["ActiveMeasurements"].AsEnumerable()
                        from key in Keys
                        where row["ID"].ToString().Split(':')[1] == key.ID.ToString()
                        select new
                        {
                            Key = key,
                            AlternateTag = row["ALTERNATETAG"].ToString(),
                            PointTag = row["POINTTAG"].ToString()
                        };

            StringBuilder tagFilter = new StringBuilder();
            foreach (var row in query)
            {
                string tagname = row.PointTag;
                if (!String.IsNullOrWhiteSpace(row.AlternateTag))
                    tagname = row.AlternateTag;

                if (!m_tagKeyMap.ContainsKey(tagname))
                {
                    m_tagKeyMap.AddOrUpdate(tagname, row.Key, (k, v) => row.Key);
                }

                if (tagFilter.Length > 0)
                    tagFilter.Append(" OR ");

                tagFilter.Append(string.Format("tag='{0}'", tagname));
            }

            m_points = new PIPointList(PIPoint.FindPIPoints(m_connection.Server, tagFilter.ToString(), true));

            // TODO: Re-enable event pipe functionality in AF-SDK
            //bool useEventPipes;

            //// event pipes are only applicable if enabled in connection string and this is a real time session, not playback
            //useEventPipes = m_useEventPipes && StartTimeConstraint == DateTime.MinValue && StopTimeConstraint == DateTime.MaxValue;

            //if (useEventPipes)
            //{
            //    try
            //    {
            //        if (m_pipe != null)
            //            ((_DEventPipeEvents_Event)m_pipe).OnNewValue -= (_DEventPipeEvents_OnNewValueEventHandler)PipeOnOnNewValue;

            //        m_connection.Execute(server => m_pipe = m_points.Data.EventPipe);

            //        ((_DEventPipeEvents_Event)m_pipe).OnNewValue += (_DEventPipeEvents_OnNewValueEventHandler)PipeOnOnNewValue;
            //    }
            //    catch (ThreadAbortException)
            //    {
            //        throw;
            //    }
            //    catch (Exception e)
            //    {
            //        useEventPipes = false; // try to run with polling instead of event pipes;
            //        OnProcessException(e);
            //    }
            //}

            //if (!useEventPipes)
            //{
            // warn that we are going to use a different configuration here...
            if (m_useEventPipes)
                OnStatusMessage("WARNING: PI adapter switching from event pipes to polling due to error or start/stop time constraints.");

            // TODO: Poll method needs some work...
            // set up a new thread to do some long calls to PI and set up threads, timers, etc for polling
            StopGettingData();
            ThreadPool.QueueUserWorkItem(StartGettingData, tagFilter);
            //}

            //m_useEventPipes = useEventPipes;
        }
Пример #38
0
        /// <summary>
        /// This method deletes the data stored in specified tags of the PI Data Archive
        /// To delete data, it is required to first read the values that you want to delete, and then
        /// Call the update values method with the AFUpdateOption.Remove option
        /// <remarks>
        /// </remarks>
        /// </summary>
        private void DeleteData()
        {
            try
            {
                ValidateParameters();

                piConnectionMgr = new PiConnectionMgr(Server);
                piConnectionMgr.Connect();
                PIServer server = piConnectionMgr.GetPiServer();

                var timer = Stopwatch.StartNew();

                // Gets the tags and creates a point list with the tags, to prepare for bulk read call
                var points = PIPoint.FindPIPoints(server, TagList);
                var pointList = new PIPointList(points);
                Logger.InfoFormat("Initialized PI Points for deletion: {0}", string.Join(", ", points.Select(p => p.Name)));

                // converts strings to AFTime objects this will throw an error if invalid
                var startTime = new AFTime(StartTime);
                var endTime = new AFTime(EndTime);

                if (startTime > endTime)
                    throw new PIDeleteUtilInvalidParameterException("Start Time must be smaller than End Time");

                // defines the data eraser task that will work in parallel as the data querying task
                dataEraser = new DataProcessor(EraseData);
                var eraseTask = Task.Run(() => dataEraser.Run());

                // splits iterates the period, over
                foreach (var period in Library.Helpers.EachNDay(startTime, endTime, Days))
                {
                    Logger.InfoFormat("Getting tags information for period {0} to {1} ({2} Days chunk)", startTime, endTime,
                        Days);

                    // makes the first data call
                    var data = pointList.RecordedValues(period, AFBoundaryType.Inside, null, false,
                        new PIPagingConfiguration(PIPageType.TagCount, 100));

                    Logger.InfoFormat("Adding the data to the queue for deletion. ({0} to {1})", startTime, endTime);
                    // we push this data into the data processor queue so we can continue to query for the rest of the data.
                    dataEraser.DataQueue.Add(data);
                }

                dataEraser.DataQueue.CompleteAdding();
                    // // this will tell the data eraser that no more data will be added and allow it to complete

                eraseTask.Wait(); // waiting for the data processor to complete

                Logger.InfoFormat(
                    "Deletion process completed in {0} seconds.  With {1} events deleted (assuming there was no errors).",
                    Math.Round(timer.Elapsed.TotalSeconds, 0), dataEraser.TotalEventProcessed);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }
Пример #39
0
        // TODO: Update code to properly handle piped-events in AF-SDK
        //private void PipeOnOnNewValue()
        //{
        //    List<IMeasurement> measurements = new List<IMeasurement>();

        //    m_connection.Execute(server =>
        //    {
        //        PIEventObject eventobject;
        //        PointValue pointvalue;

        //        for (int i = 0; i < m_pipe.Count; i++)
        //        {
        //            eventobject = m_pipe.Take();

        //            // we will publish measurements for every action except deleted (possible dupes on updates)
        //            if (eventobject.Action != EventActionConstants.eaDelete)
        //            {
        //                try
        //                {
        //                    pointvalue = (PointValue)eventobject.EventData;

        //                    double value = Convert.ToDouble(pointvalue.PIValue.Value);
        //                    MeasurementKey key = m_tagKeyMap[pointvalue.PIPoint.Name];

        //                    Measurement measurement = new Measurement();
        //                    measurement.Key = key;
        //                    measurement.Timestamp = pointvalue.PIValue.TimeStamp.LocalDate.ToUniversalTime();
        //                    measurement.Value = value;
        //                    measurement.StateFlags = MeasurementStateFlags.Normal;

        //                    if (measurement.Timestamp > m_lastReceivedTimestamp.Ticks)
        //                        m_lastReceivedTimestamp = measurement.Timestamp;

        //                    measurements.Add(measurement);
        //                }
        //                catch
        //                {
        //                    /* squelch any errors on digital state data that can't be converted to a double */
        //                }
        //            }
        //        }
        //    });

        //    if (measurements.Any())
        //    {
        //        OnNewMeasurements(measurements);
        //        m_processedMeasurements += measurements.Count;
        //    }
        //}

        /// <summary>
        /// Disposes members for garbage collection
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (m_tagKeyMap != null)
                m_tagKeyMap.Clear();
            m_tagKeyMap = null;

            if ((object)m_connection != null)
                m_connection.Dispose();

            m_connection = null;
            m_points = null;
            //m_pipe = null;

            m_measurements.Clear();
            m_measurements = null;

            if (m_dataThread != null)
            {
                m_dataThread.Abort();
                m_dataThread = null;
            }

            if (m_publishTimer != null)
            {
                m_publishTimer.Stop();
                m_publishTimer.Elapsed -= m_publishTimer_Tick;
                m_publishTimer.Dispose();
                m_publishTimer = null;
            }
        }