public static void ConfirmValuesAtRangeEndpoints(this AFValues values, AFAttribute Attribute, AFTimeRange TimeRange) { AFTime StartTime = TimeRange.StartTime.ToPIPrecision(); AFTime EndTime = TimeRange.EndTime.ToPIPrecision(); // Don't merely add a StartTime and EndTime. // First you must check to make sure they aren't already there. // Corner case: where EndTime == StartTime. if (values.Count == 0) { values.Add(CreateBadValue(Attribute, StartTime)); } else if (values[0].Timestamp > StartTime) { // This will probably never happen but in extremely rare // case that it does, set a dummy value. values.Insert(0, CreateBadValue(Attribute, StartTime)); } var last = values[values.Count - 1]; if (last.Timestamp < EndTime) { // Carry the last value to the end of the range, including its status, etc. AFValue val = new AFValue(last); // Except we want to change its Timestamp val.Timestamp = EndTime; values.Add(val); } }
public PIValues GetInterpolatedValues(int i, string starttime, string endtime, string interval) { AFTime startTime = new AFTime(starttime); AFTime endTime = new AFTime(endtime); AFTimeRange timeRange = new AFTimeRange(startTime, endTime); AFTimeSpan timeSpan = AFTimeSpan.Parse(interval); AFValues myAFValues; if (i == 1) { myAFValues = MyAtrbTag1.Data.InterpolatedValues(timeRange, timeSpan, null, null, false); } else if (i == 2) { myAFValues = MyAtrbTag2.Data.InterpolatedValues(timeRange, timeSpan, null, null, false); } else if (i == 3) { myAFValues = MyAtrbTag3.Data.InterpolatedValues(timeRange, timeSpan, null, null, false); } else if (i == 4) { myAFValues = MyAtrbTag4.Data.InterpolatedValues(timeRange, timeSpan, null, null, false); } else { myAFValues = MyAtrbTag5.Data.InterpolatedValues(timeRange, timeSpan, null, null, false); } return(ConvertToPIValues(myAFValues)); }
public void PrintReportEx5() { using (StringWriter sw = new StringWriter()) { Console.SetOut(sw); var eventFrameTemplate = Ex5WorkingWithEventFramesSln.Program5.CreateEventFrameTemplate(Database); Assert.NotNull(eventFrameTemplate); Ex5WorkingWithEventFramesSln.Program5.CreateEventFrames(Database, eventFrameTemplate); AFTime startTime = DateTime.Today.AddDays(-7); string queryString = $"template:\"{eventFrameTemplate.Name}\""; using (AFEventFrameSearch eventFrameSearch = new AFEventFrameSearch(Database, "EventFrame Captures", AFEventFrameSearchMode.ForwardFromStartTime, startTime, queryString)) { eventFrameSearch.CacheTimeout = TimeSpan.FromMinutes(5); var resp = eventFrameSearch.FindObjects(); Assert.True(resp.Any()); } Ex5WorkingWithEventFramesSln.Program5.CaptureValues(Database, eventFrameTemplate); Ex5WorkingWithEventFramesSln.Program5.PrintReport(Database, eventFrameTemplate); var actual = sw.ToString(); Assert.Contains("Daily Usage-Meter", actual); Assert.Contains(", Meter003,", actual); } }
static void PrintInterpolated(AFDatabase database, string meterName, string startTime, string endTime, TimeSpan timeSpan) { Console.WriteLine(string.Format("Print Interpolated Values - Meter: {0}, Start: {1}, End: {2}", meterName, startTime, endTime)); AFAttribute attr = AFAttribute.FindAttribute(@"\Meters\" + meterName + @"|Energy Usage", database); AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); AFTimeSpan interval = new AFTimeSpan(timeSpan); AFValues vals = attr.Data.InterpolatedValues( timeRange: timeRange, interval: interval, desiredUOM: null, filterExpression: null, includeFilteredValues: false); foreach (AFValue val in vals) { Console.WriteLine("Timestamp (Local): {0}, Value: {1:0.00} {2}", val.Timestamp.LocalTime, val.Value, val?.UOM.Abbreviation); } Console.WriteLine(); }
public static void PrintReport(AFDatabase database, AFElementTemplate eventFrameTemplate) { if (database == null) { throw new ArgumentNullException(nameof(database)); } if (eventFrameTemplate == null) { throw new ArgumentNullException(nameof(eventFrameTemplate)); } AFTime startTime = DateTime.Today.AddDays(-7); AFTime endTime = startTime.LocalTime.AddDays(+8); // Or DateTime.Today.AddDays(1); string queryString = $"template:'{eventFrameTemplate.Name}' ElementName:Meter003"; using (AFEventFrameSearch eventFrameSearch = new AFEventFrameSearch(database, "EventFrame Captures", AFSearchMode.StartInclusive, startTime, endTime, queryString)) { eventFrameSearch.CacheTimeout = TimeSpan.FromMinutes(5); foreach (AFEventFrame ef in eventFrameSearch.FindObjects()) { Console.WriteLine("{0}, {1}, {2}", ef.Name, ef.PrimaryReferencedElement.Name, ef.Attributes["Average Energy Usage"].GetValue().Value); } } }
public static void CaptureValues(AFDatabase database, AFElementTemplate eventFrameTemplate) { if (database == null) { throw new ArgumentNullException(nameof(database)); } if (eventFrameTemplate == null) { throw new ArgumentNullException(nameof(eventFrameTemplate)); } // Formulate search constraints on time and template AFTime startTime = DateTime.Today.AddDays(-7); string queryString = $"template:\"{eventFrameTemplate.Name}\""; using (AFEventFrameSearch eventFrameSearch = new AFEventFrameSearch(database, "EventFrame Captures", AFEventFrameSearchMode.ForwardFromStartTime, startTime, queryString)) { eventFrameSearch.CacheTimeout = TimeSpan.FromMinutes(5); int count = 0; foreach (AFEventFrame item in eventFrameSearch.FindObjects()) { item.CaptureValues(); if ((count++ % 500) == 0) { database.CheckIn(); } } if (database.IsDirty) { database.CheckIn(); } } }
public bool CheckAFTimeValues(string afTimeString) { AFTime afTime; var valid = AFTime.TryParse(afTimeString, out afTime); return(valid); }
public static void PrintHistorical(AFDatabase database, string meterName, string startTime, string endTime) { if (database == null) { throw new ArgumentNullException(nameof(database)); } Console.WriteLine(string.Format("Print Historical Values - Meter: {0}, Start: {1}, End: {2}", meterName, startTime, endTime)); AFAttribute attr = AFAttribute.FindAttribute(@"\Meters\" + meterName + @"|Energy Usage", database); AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); AFValues vals = attr.Data.RecordedValues( timeRange: timeRange, boundaryType: AFBoundaryType.Inside, desiredUOM: database.PISystem.UOMDatabase.UOMs["kilojoule"], filterExpression: null, includeFilteredValues: false); foreach (AFValue val in vals) { Console.WriteLine("Timestamp (UTC): {0}, Value (kJ): {1}", val.Timestamp.UtcTime, val.Value); } Console.WriteLine(); }
public static void DeleteValues(PIPoint piPoint, AFTime st, AFTime et, bool forceUpdateValuesMethod = false) { var timerange = new AFTimeRange(st, et); if (piPoint.Server.Supports(PIServerFeature.DeleteRange) && forceUpdateValuesMethod == false) { var errors = piPoint.ReplaceValues(timerange, new List <AFValue>()); if (errors != null && errors.HasErrors) { _logger.Error(errors.Errors); _logger.Error(errors.PIServerErrors); } } else { // fallback on the old fashion way of doing the delete // if code goes here this may be much slower to delete the values. _logger.Warn("The ReplaceValues method is not implemented on the target PI DataArchive or the forceUpdateValuesMethod flag was used, falling back to the previous longer method ( read and remove)"); var dataToDelete = piPoint.RecordedValues(timerange, AFBoundaryType.Inside, string.Empty, false); if (dataToDelete.Count > 0) { piPoint.UpdateValues(dataToDelete, AFUpdateOption.Remove); } } }
public void Run() { PIServers piServers = new PIServers(); PIServer piServer = piServers["<PISERVER>"]; IList<PIPoint> points = PIPoint.FindPIPoints(piServer, new[] { "sample_floatpoint", "sample_digitalpoint" }); PIPoint floatingPIPoint = points[0]; PIPoint digitalPIPoint = points[1]; AFEnumerationSet digSet = piServer.StateSets["Modes"]; IList<AFValue> valuesToWrite = new List<AFValue>(); for (int i = 0; i < 10; i++) { AFTime time = new AFTime(new DateTime(2015, 1, 1, i, 0, 0, DateTimeKind.Local)); AFValue afValueFloat = new AFValue(i, time); // Associate the AFValue to a PI Point so we know where to write to. afValueFloat.PIPoint = floatingPIPoint; AFEnumerationValue digSetValue = i % 2 == 0 ? digSet["Auto"] : digSet["Manual"]; AFValue afValueDigital = new AFValue(digSetValue, time); afValueDigital.PIPoint = digitalPIPoint; valuesToWrite.Add(afValueFloat); valuesToWrite.Add(afValueDigital); } // Perform a bulk write. Use a single local call to PI Buffer Subsystem if possible. // Otherwise, make a single call to the PI Data Archive. // We use no compression just so we can check all the values are written. piServer.UpdateValues(valuesToWrite, AFUpdateOption.InsertNoCompression, AFBufferOption.BufferIfPossible); }
public void WindowsIdMappingTest() { Utils.CheckTimeDrift(Fixture, Output); // Disconnect from the PISERVER Output.WriteLine($"Disconnect from PI Server [{Fixture.PIServer}]."); Fixture.PIServer.Disconnect(); AFTime startTime = AFTime.Now.ToPIPrecision(); string startTimePI = PIDAUtilities.ToPiTimeString(startTime.LocalTime); // Connect again to check for the logs for identity used to get into PISERVER Output.WriteLine($"Reconnect to PI Server [{Fixture.PIServer}]."); Fixture.PIServer.Connect(); // window of time to check for logged messages AFTime endTime = startTime + TimeSpan.FromMinutes(5); string endTimePI = PIDAUtilities.ToPiTimeString(endTime.LocalTime); int expectedMsgID = 7082; Output.WriteLine($"Check if user is logged in through Windows Login."); AssertEventually.True(() => { // Checks for windows login five times return(PIDAUtilities.FindMessagesInLog(Fixture, startTimePI, endTimePI, expectedMsgID, "*Method: Windows Login*")); }, TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(3), "Windows login not found."); }
static void CreateEventFrames(AFDatabase database, AFElementTemplate eventFrameTemplate) { string queryString = "Template:MeterBasic"; { // This method returns the collection of AFBaseElement objects that were created with this template. using (AFElementSearch elementQuery = new AFElementSearch(database, "Meters", queryString)) { DateTime timeReference = DateTime.Today.AddDays(-7); int count = 0; foreach (AFElement meter in elementQuery.FindElements()) { foreach (int day in Enumerable.Range(1, 7)) { AFTime startTime = new AFTime(timeReference.AddDays(day - 1)); AFTime endTime = new AFTime(startTime.LocalTime.AddDays(1)); AFEventFrame ef = new AFEventFrame(database, "*", eventFrameTemplate); ef.SetStartTime(startTime); ef.SetEndTime(endTime); ef.PrimaryReferencedElement = meter; // It is good practice to periodically check in the database if (++count % 500 == 0) { database.CheckIn(); } } } } } if (database.IsDirty) { database.CheckIn(); } }
public void Run() { PIServers piServers = new PIServers(); PIServer piServer = piServers["<PISERVER>"]; IList <PIPoint> points = PIPoint.FindPIPoints(piServer, new[] { "sample_floatpoint", "sample_digitalpoint" }); PIPoint floatingPIPoint = points[0]; PIPoint digitalPIPoint = points[1]; AFEnumerationSet digSet = piServer.StateSets["Modes"]; IList <AFValue> valuesToWrite = new List <AFValue>(); for (int i = 0; i < 10; i++) { AFTime time = new AFTime(new DateTime(2015, 1, 1, i, 0, 0, DateTimeKind.Local)); AFValue afValueFloat = new AFValue(i, time); // Associate the AFValue to a PI Point so we know where to write to. afValueFloat.PIPoint = floatingPIPoint; AFEnumerationValue digSetValue = i % 2 == 0 ? digSet["Auto"] : digSet["Manual"]; AFValue afValueDigital = new AFValue(digSetValue, time); afValueDigital.PIPoint = digitalPIPoint; valuesToWrite.Add(afValueFloat); valuesToWrite.Add(afValueDigital); } // Perform a bulk write. Use a single local call to PI Buffer Subsystem if possible. // Otherwise, make a single call to the PI Data Archive. // We use no compression just so we can check all the values are written. piServer.UpdateValues(valuesToWrite, AFUpdateOption.InsertNoCompression, AFBufferOption.BufferIfPossible); }
public PIValues GetRecordedValues(int i, string starttime, string endtime) { AFTime startTime = new AFTime(starttime); AFTime endTime = new AFTime(endtime); AFTimeRange timeRange = new AFTimeRange(startTime, endTime); AFValues myAFValues; if (i == 1) { myAFValues = MyAtrbTag1.Data.RecordedValues(timeRange, AFBoundaryType.Inside, null, null, false); } else if (i == 2) { myAFValues = MyAtrbTag2.Data.RecordedValues(timeRange, AFBoundaryType.Inside, null, null, false); } else if (i == 3) { myAFValues = MyAtrbTag3.Data.RecordedValues(timeRange, AFBoundaryType.Inside, null, null, false); } else if (i == 4) { myAFValues = MyAtrbTag4.Data.RecordedValues(timeRange, AFBoundaryType.Inside, null, null, false); } else { myAFValues = MyAtrbTag5.Data.RecordedValues(timeRange, AFBoundaryType.Inside, null, null, false); } return(ConvertToPIValues(myAFValues)); }
static void PrintHourlyAverage(AFDatabase database, string meterName, string startTime, string endTime) { Console.WriteLine(string.Format("Print Hourly Average - Meter: {0}, Start: {1}, End: {2}", meterName, startTime, endTime)); AFAttribute attr = AFAttribute.FindAttribute(@"\Meters\" + meterName + @"|Energy Usage", database); AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); IDictionary <AFSummaryTypes, AFValues> vals = attr.Data.Summaries( timeRange: timeRange, summaryDuration: new AFTimeSpan(TimeSpan.FromHours(1)), summaryType: AFSummaryTypes.Average, calcBasis: AFCalculationBasis.TimeWeighted, timeType: AFTimestampCalculation.EarliestTime); foreach (AFValue val in vals[AFSummaryTypes.Average]) { Console.WriteLine("Timestamp (Local): {0:yyyy-MM-dd HH\\h}, Value: {1:0.00} {2}", val.Timestamp.LocalTime, val.Value, val?.UOM.Abbreviation); } Console.WriteLine(); }
public void CaptureValues() { const int pageSize = 1000; int startIndex = 0; AFTime startTime = new AFTime(new DateTime(2015, 12, 1, 0, 0, 0, DateTimeKind.Local)); AFNamedCollectionList<AFEventFrame> efs; do { efs = AFEventFrame.FindEventFrames( database: _database, searchRoot: null, startTime: startTime, startIndex: startIndex, maxCount: pageSize, searchMode: AFEventFrameSearchMode.ForwardFromStartTime, nameFilter: "*", referencedElementNameFilter: "*", eventFrameCategory: null, eventFrameTemplate: _eventFrameTemplate, referencedElementTemplate: null, searchFullHierarchy: true ); foreach (AFEventFrame ef in efs) { if (!ef.AreValuesCaptured) ef.CaptureValues(); } _database.CheckIn(); startIndex += pageSize; } while (efs != null && efs.Count > 0); }
private static IEnumerable <AFTimeRange> GetSubrangesForward(AFTimeRange timeRange, int count) { if (count == 1) { yield return(timeRange); } if (count < 2) { yield break; } var totalSeconds = timeRange.Span.TotalSeconds; var secondsPerSubrange = (totalSeconds / count) + 1; // to be safe var rangeStart = timeRange.StartTime; while (rangeStart <= timeRange.EndTime) { var rangeEnd = new AFTime(rangeStart.UtcSeconds + secondsPerSubrange); if (rangeEnd > timeRange.EndTime) { rangeEnd = timeRange.EndTime; } yield return(new AFTimeRange(rangeStart, rangeEnd)); rangeStart = rangeEnd.AddPITicks(1); } }
/// <summary> /// Returns an AFTimeRange based on the calendar date times from the form /// </summary> /// <returns> /// AFTimeRange from the date pickers /// </returns> private AFTimeRange GetTimeRangeFromDatePickers() { AFTime startTime = AFTime.Parse(dateStart.Value.ToShortDateString()); AFTime endTime = AFTime.Parse(dateEnd.Value.ToShortDateString()); return(new AFTimeRange(startTime, endTime)); }
public void ArchiveQueryTest(string pointMask, string startTime, string endTime, double minValue, double maxValue) { var now = AFTime.Now; var st = new AFTime(startTime, now); var et = new AFTime(endTime, now); Output.WriteLine($"Start to execute PI Data Archive queries on PI Points matching [{pointMask}] " + $"between [{st}] and [{et}]."); IList <IEnumerable <PIPointQuery> > queries = PIPointQuery.ParseQuery(Fixture.PIServer, pointMask); IEnumerable <PIPoint> pointList = PIPoint.FindPIPoints(Fixture.PIServer, queries).ToList(); IDictionary <string, AFValues> events = Fixture.ReadPIEvents(pointList, st, et); // Verify all event values are in the expected range foreach (var ptvaluespair in events) { foreach (var val in ptvaluespair.Value.Where(val => val.IsGood)) { var convertedValue = Convert.ToDouble(val.Value, CultureInfo.InvariantCulture); Assert.True(convertedValue >= minValue && convertedValue <= maxValue, $"[{ptvaluespair.Key}] has a value [{val.Value}] outside of expected data range of " + $"[{minValue} ~ {maxValue}]"); } } Output.WriteLine($"Found {events.Sum(kvp => kvp.Value.Count)} PI events."); }
private static IEnumerable <AFTimeRange> GetSubrangesBackward(AFTimeRange timeRange, int count) { if (count == 1) { yield return(timeRange); } if (count < 2) { yield break; } var totalSeconds = timeRange.Span.TotalSeconds; var secondsPerSubrange = (totalSeconds / count) + 1; // to be safe var rangeStart = timeRange.StartTime; // This differs from Forward in that we flip + for - and < for > while (rangeStart >= timeRange.EndTime) { var rangeEnd = new AFTime(rangeStart.UtcSeconds - secondsPerSubrange); if (rangeEnd < timeRange.EndTime) { rangeEnd = timeRange.EndTime; } yield return(new AFTimeRange(rangeStart, rangeEnd)); rangeStart = rangeEnd.AddPITicks(-1); } }
/// <summary> /// Indicates whether this instance of <see cref="AFTime"/> contains subseconds. /// </summary> public static bool HasSubseconds(this AFTime time) { var seconds = time.UtcSeconds; var wholeSeconds = (int)Math.Truncate(seconds); return(seconds > wholeSeconds); }
static void PrintInterpolated(AFDatabase database, string meterName, string startTime, string endTime, TimeSpan timeSpan) { Console.WriteLine(string.Format("Print Interpolated Values - Meter: {0}, Start: {1}, End: {2}", meterName, startTime, endTime)); AFAttribute attr = AFAttribute.FindAttribute(@"\Meters\" + meterName + @"|Energy Usage", database); AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); AFTimeSpan interval = new AFTimeSpan(timeSpan); AFValues vals = attr.Data.InterpolatedValues( timeRange: timeRange, interval: interval, desiredUOM: null, filterExpression: null, includeFilteredValues: false); foreach (AFValue val in vals) { Console.WriteLine("Timestamp (Local): {0}, Value (kWh): {1}", val.Timestamp.LocalTime, val.Value); } Console.WriteLine(); }
/// <summary> /// Retrieves the PI Point history data from the data archive for the specified time range /// </summary> /// <returns> the frame containts the history data generated for the points as matrix</returns> public Object[,] getArchiveValues_new() { List <PIPoint> ptList = new List <PIPoint>(); DateTime starttime = AFTime.Parse("t"); DateTime endtime = AFTime.Parse("t-2d"); AFTimeRange timeRange = AFTimeRange.Parse(starttime.ToString(), endtime.ToString()); var boundaryType = AFBoundaryType.Inside; List <OSIsoft.AF.Asset.AFValues> recordList = new List <OSIsoft.AF.Asset.AFValues>(); ptList.Add(PIPoint.FindPIPoint(piServer, "BA:TEMP.1")); ptList.Add(PIPoint.FindPIPoint(piServer, "BA:CONC.1")); ptList.Add(PIPoint.FindPIPoint(piServer, "BA:LEVEL.1")); ptList.Add(PIPoint.FindPIPoint(piServer, "BA:PHASE.1")); ptList.Add(PIPoint.FindPIPoint(piServer, "BA:ACTIVE.1")); foreach (PIPoint pt in ptList) { recordList.Add(pt.RecordedValues(timeRange, boundaryType, "", false)); } //multi array with mixed objects List <Int32> mxl = new List <Int32>(); mxl.Add(recordList[0].Count); mxl.Add(recordList[1].Count); mxl.Add(recordList[2].Count); mxl.Add(recordList[3].Count); mxl.Add(recordList[4].Count); int mxl_max = mxl.Max(); Object[,] frame = new Object[ptList.Count + 1, mxl_max]; int i = 1; foreach (OSIsoft.AF.Asset.AFValues vals in recordList) { int j = 0; foreach (OSIsoft.AF.Asset.AFValue afval in vals) { if (i < ptList.Count + 1 && j < mxl_max) { if (afval.Timestamp != null) { frame[0, j] = DateTime.Parse(afval.Timestamp.LocalTime.ToString()); } if (afval.Value != null) { frame[i, j] = afval.Value; } j += 1; } } i += 1; } return(frame); }
/// <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); } }
/// <summary> /// Calculates the median of the passed in values /// </summary> /// <param name="inputValues">Collection of AFValues that represent the child element attribute values to be rolled up</param> /// <param name="defaultUOM">The Unit of Measure of the owning AFAttribute</param> /// <returns>Double representing the calculated median</returns> public AFValue Median(AFValues inputValues, UOM defaultUOM) { AFTime time = new AFTime(); time = inputValues[0].Timestamp; try { double _median = 0; List <double> dValues = new List <double>(); foreach (AFValue inputVal in inputValues) { if (inputVal.IsGood && inputVal != null) { double dCurrVal; // make sure we do all operations in same UOM, if applicable if (inputVal.UOM != null && defaultUOM != null && inputVal.UOM != defaultUOM) { dCurrVal = defaultUOM.Convert(inputVal.Value, inputVal.UOM); } else { dCurrVal = Convert.ToDouble(inputVal.Value); } dValues.Add(dCurrVal); } } // Convert the list to an array and sort it double[] _sortedValues = dValues.ToArray(); Array.Sort(_sortedValues); // now find the median value int _count = _sortedValues.Length; if (_count == 0) { return(new AFValue(Double.NaN, (AFTime)DateTime.Now)); } else if (_count % 2 == 0) { // count is even, so we average the two middle elements double a = _sortedValues[_count / 2 - 1]; double b = _sortedValues[_count / 2]; _median = (a + b) / 2; } else { _median = _sortedValues[_count / 2]; } return(new AFValue(_median, time)); //return new AFValue(_median, (AFTime)DateTime.Now);; } catch { return(new AFValue(Double.NaN, (AFTime)DateTime.Now, null, AFValueStatus.Bad)); } }
public static List <AbstractRetrievePoints> LoadTagClassesRecorded( String inputFilePath, String outputDirectory, String timeResolution, int numYears, int pageSize, PIServer piServer, PISystem piSystem, int numParallelTasks, Logger logger) { var inputLines = LoadInputFile(inputFilePath); List <AbstractRetrievePoints> tagClasses = new List <AbstractRetrievePoints>(); Parallel.ForEach( inputLines, new ParallelOptions { MaxDegreeOfParallelism = numParallelTasks }, (String[] line) => { string tagName = line[0]; string startTimeString = line[1]; string endTimeString = line[2]; PIPoint tag; try { tag = PIPoint.FindPIPoint(piServer, tagName); AFTime startTime = new AFTime(startTimeString); AFTime endTime = new AFTime(endTimeString); AFTimeRange timeRange = new AFTimeRange(startTime, endTime); string startTimeStamp = startTime.UtcTime.ToString("yyyy/MM/dd HH:mm:ss"); string endTimeStamp = endTime.UtcTime.ToString("yyyy/MM/dd HH:mm:ss"); lock (logger) { logger.Log($"{startTimeStamp} : {endTimeStamp}, {tagName}"); } lock (tagClasses) { tagClasses.Add(new PIRecordedPointRetrievalClass( tag, timeRange, outputDirectory, PIRandomFunctionsUtil.ParseTimeResolutionString(timeResolution), numYears, pageSize, logger)); } } catch (Exception e) { logger.Log("Exception: could not FindPiPoint: " + e.ToString()); } }); return(tagClasses); }
internal static AFTime timeShift(AFValues values, AFTime startTime) { foreach (AFValue value in values) { value.Timestamp = startTime; startTime += interval; } return(startTime); }
private void btnQueue_Click(object sender, EventArgs e) { AFAnalysisService service = afDatabasePicker.PISystem.AnalysisService; AFTime startTime = new AFTime(tbStartTime.Text); AFTime endTime = new AFTime(tbEndTime.Text); AFTimeRange timeRange = new AFTimeRange(startTime, endTime); queueBackfill(service, timeRange); }
public void setTime(string AnyTime) { if (!AFTime.TryParse(AnyTime, out m_Time)) { System.Console.WriteLine("Bad input time value."); m_Time = new AFTime(); // Empty Time } }
public PIValuesList GetRecordedValues(string startTime, string endTime) { AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); IEnumerable <AFValues> valueResults = pointList.RecordedValues(timeRange, AFBoundaryType.Inside, string.Empty, false, new PIPagingConfiguration(PIPageType.TagCount, 100)); return(new PIValuesList(valueResults)); }
private AFValue Calculate(AFTime time, AFAttributeList inputAttributes, AFValues inputValues) { if (time == null) { throw new ArgumentException("No timestamp"); } if (inputAttributes == null || inputAttributes.Count == 0) { throw new ArgumentException("No input attributes"); } if (inputValues == null || inputValues.Count == 0) { throw new ArgumentException(Resources.ERR_NoInputValues); } AFValue inVal; if (inputAttributes.Count > 0) { inVal = inputAttributes[0].GetValue(time); if (inVal == null) { throw new ApplicationException("Input value is null"); } else { AFEnumerationValue enumValue = inVal.Value as AFEnumerationValue; if (enumValue != null && enumValue.Value == 248) { // Attempting to handle an error when the output value is 248 instead of the NoData state return(AFValue.CreateSystemStateValue(this.Attribute, AFSystemStateCode.NoData, time)); } else { double keyValue = (double)inVal.Value; double resultValue = GetCalibratedValue(keyValue); if (!double.IsNaN(resultValue)) { return(new AFValue(this.Attribute, resultValue, inVal.Timestamp, this.Attribute.DefaultUOM)); } else { return(AFValue.CreateSystemStateValue(this.Attribute, AFSystemStateCode.NoData, time)); } } } } else { throw new ApplicationException(string.Format("Input attribute not found (#{0}", 1)); } }
static void Main(string[] args) { if (args.Length < 4) { Console.WriteLine("Usage: RunAnalysis.exe <elementPath> <analysisName> <startTime> <endTime>"); Console.WriteLine("(e.g. RunAnalysis.exe" + @"\\afservername\dbname\elementName analysisName 'y' 't')"); return; } var elementPath = args[0]; var analysisName = args[1]; var st = args[2]; var et = args[3]; var element = AFObject.FindObject(elementPath) as AFElement; if (element == null) { Console.WriteLine("Failed to find element '{0}'", elementPath); return; } var analysis = element.Analyses[analysisName]; if (analysis == null) { Console.WriteLine("Failed to find analysis '{0}|{1}'", elementPath, analysisName); return; } AFTime startTime; if (!AFTime.TryParse(st, out startTime)) { Console.WriteLine("Invalid start time '{0}';", st); return; } AFTime endTime; if (!AFTime.TryParse(et, out endTime)) { Console.WriteLine("Invalid end time '{0}';", et); return; } Console.WriteLine("Evaluating {0}|{1} from {2} to {3}...", elementPath, analysisName, startTime, endTime); var executor = new AnalysisExecutor(analysis); executor.Run(new AFTimeRange(startTime, endTime)); if (Debugger.IsAttached) { Console.Read(); } }
static void PrintInterpolated(AFDatabase database, string meterName, string start, string end, TimeSpan interval) { AFTime startTime = new AFTime(start); AFTime endTime = new AFTime(end); AFTimeRange timeRange = new AFTimeRange(startTime, endTime); AFAttribute att = AFAttribute.FindAttribute(@"\Meters\" + meterName + @"|Energy Usage", database); AFTimeSpan intervalNew = new AFTimeSpan(interval); AFValues values = att.Data.InterpolatedValues(timeRange: timeRange, interval: intervalNew, desiredUOM: null, filterExpression: null, includeFilteredValues: false); }
public PIValuesList GetInterpolatedValues(string startTime, string endTime, string interval) { AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); AFTimeSpan timeSpan = AFTimeSpan.Parse(interval); IEnumerable <AFValues> valueResults = pointList.InterpolatedValues(timeRange, timeSpan, string.Empty, false, new PIPagingConfiguration(PIPageType.TagCount, 100)); return(new PIValuesList(valueResults)); }
public Orchestrator(string startTime, string endTime, TimeSpan interval, IDataReader dataReader) { // prepares dates to read var st = new AFTime(startTime); var et = new AFTime(endTime); _logger.InfoFormat("Getting time intervals: {0},{1},{2}", interval.TotalSeconds, st.LocalTime, et.LocalTime); _datesIntervals = TimeStampsGenerator.Get(interval, st, et); _logger.InfoFormat("Will work with {0} dates intervals", _datesIntervals.Count); _dataReader = dataReader; }
public void PrintHistorical(string meterName, string startTime, string endTime) { AFAttribute attr = AFAttribute.FindAttribute(@"\Meters\" + meterName + @"|Energy Usage", _database); AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); AFValues vals = attr.Data.RecordedValues( timeRange: timeRange, boundaryType: AFBoundaryType.Inside, desiredUOM: _database.PISystem.UOMDatabase.UOMs["kilojoule"], filterExpression: null, includeFilteredValues: false); foreach (AFValue val in vals) { Console.WriteLine("Timestamp (UTC): {0}, Value (kJ): {1}", val.Timestamp.UtcTime, val.Value); } }
/// <summary> /// Searches event frames that where ACTIVE at the specified time /// </summary> /// <remarks>There are a lot of ways to search event frames, this is just one way of doing it</remarks> /// <param name="afDatabase"></param> /// <param name="time"></param> /// Search mode is the key to understand how EFs are found, in this scenario we look for overlapped: /// <see cref="https://techsupport.osisoft.com/Documentation/PI-AF-SDK/html/T_OSIsoft_AF_Asset_AFSearchMode.htm"/> private void SearchEventFrames(AFDatabase afDatabase, string time) { try { var searchTime = new AFTime(time); Logger.InfoFormat("Searching for event frames in {0} database at time {1}",afDatabase.Name, searchTime); var eventFrames = AFEventFrame.FindEventFrames( database: afDatabase, searchRoot: null, searchMode: AFSearchMode.Overlapped, startTime: searchTime, endTime: searchTime, nameFilter: string.Empty, referencedElementNameFilter: string.Empty, eventFrameCategory: null, eventFrameTemplate: null, referencedElementTemplate: null, durationQuery: null, searchFullHierarchy: false, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: 0, maxCount: 1000 ); Logger.InfoFormat("Found {0} event frames: ", eventFrames.Count); foreach (var ef in eventFrames) { Logger.InfoFormat("{0}-ST:{1}-ET:{2}", ef.Name, ef.StartTime, ef.EndTime); } } catch (Exception ex) { Logger.Error(ex); } }
public void PrintHourlyAverage(string meterName, string startTime, string endTime) { AFAttribute attr = AFAttribute.FindAttribute(@"\Meters\" + meterName + @"|Energy Usage", _database); AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); IDictionary<AFSummaryTypes, AFValues> vals = attr.Data.Summaries( timeRange: timeRange, summaryDuration: new AFTimeSpan(TimeSpan.FromHours(1)), summaryType: AFSummaryTypes.Average, calcBasis: AFCalculationBasis.TimeWeighted, timeType: AFTimestampCalculation.EarliestTime); foreach (AFValue val in vals[AFSummaryTypes.Average]) { Console.WriteLine("Timestamp (Local): {0}, Value (kilowatt hour): {1}", val.Timestamp.LocalTime, val.Value); } }
public bool CreateEventFrame(string name, AFTime start, AFTime end, AFElement primaryReferencedElement, AFElementTemplate efTemplate) { try { AFEventFrame newEF = new AFEventFrame(_db, name, efTemplate); newEF.SetStartTime(start); newEF.SetEndTime(end); newEF.PrimaryReferencedElement = primaryReferencedElement; newEF.CheckIn(); _db.CheckIn(AFCheckedOutMode.ObjectsCheckedOutThisThread); _db.Refresh(); return true; } catch { return false; } }
public void Run() { PISystems piSystems = new PISystems(); PISystem piSystem = piSystems["<AFSERVER>"]; AFDatabase afDatabase = piSystem.Databases["Basic-AFSDK-Sample"]; AFElement boilerA = afDatabase.Elements["Region_0"].Elements["BoilerA"]; AFElementTemplate elementTemplate = afDatabase.ElementTemplates["BasicBoilerTemplate"]; AFAttributeTemplate temperatureAttrTemplate = elementTemplate.AttributeTemplates["Temperature"]; AFAttributeTemplate modeAttrTemplate = elementTemplate.AttributeTemplates["Mode"]; AFElement.LoadAttributes(new[] { boilerA }, new[] { temperatureAttrTemplate, modeAttrTemplate }); AFEnumerationSet digSet = afDatabase.EnumerationSets["Modes"]; IList<AFValue> valuesToWrite = new List<AFValue>(); for (int i = 0; i < 10; i++) { AFTime time = new AFTime(new DateTime(2015, 1, 1, i, 0, 0, DateTimeKind.Local)); AFValue afValueFloat = new AFValue(i, time); // Associate the AFValue to an attribute so we know where to write to. afValueFloat.Attribute = boilerA.Attributes["Temperature"]; AFEnumerationValue digSetValue = i % 2 == 0 ? digSet["Auto"] : digSet["Manual"]; AFValue afValueDigital = new AFValue(digSetValue, time); afValueDigital.Attribute = boilerA.Attributes["Mode"]; valuesToWrite.Add(afValueFloat); valuesToWrite.Add(afValueDigital); } // Perform a bulk write. Use a single local call to PI Buffer Subsystem if possible. // Otherwise, make a single call to the PI Data Archive. // We use no compression just so we can check all the values are written. // AFListData is the class that provides the bulk write method. AFListData.UpdateValues(valuesToWrite, AFUpdateOption.InsertNoCompression, AFBufferOption.BufferIfPossible); }
public void CreateEventFrames() { const int pageSize = 1000; int startIndex = 0; int totalCount; do { AFNamedCollectionList<AFBaseElement> results = _database.ElementTemplates["MeterBasic"].FindInstantiatedElements( includeDerived: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: startIndex, maxCount: pageSize, totalCount: out totalCount ); IList<AFElement> meters = results.Select(elm => (AFElement)elm).ToList(); foreach (AFElement meter in meters) { foreach (int day in Enumerable.Range(1, 31)) { DateTime start = new DateTime(2015, 12, day, 0, 0, 0, DateTimeKind.Local); AFTime startTime = new AFTime(start); AFTime endTime = new AFTime(start.AddDays(1)); AFEventFrame ef = new AFEventFrame(_database, "*", _eventFrameTemplate); ef.SetStartTime(startTime); ef.SetEndTime(endTime); ef.PrimaryReferencedElement = meter; } } _database.CheckIn(); startIndex += pageSize; } while (startIndex < totalCount); }
private void ValidateParameters() { // limit days intervalls to 30 days if (NumStart < 0 || NumEnd < 0) throw new PITestDataUtilInvalidParameterException("NumStart and NumEnd must be greater than 0"); if (NumStart > NumEnd) throw new PITestDataUtilInvalidParameterException("NumEnd must be greater than NumStart"); if (DataSt != null) { // AFTime will throw an error in case the string is not valid _dataStartTime = new AFTime(DataSt); _dataEndTime = DataEt != null ? new AFTime(DataEt) : new AFTime("*"); _interval = TimeSpan.FromSeconds(DataInterval); } }
static public void CaptureValues(AFDatabase database, AFElementTemplate eventFrameTemplate) { // Formulate search constraints on time and template DateTime timereference = DateTime.Now.AddDays(-7); AFTime startTime = new AFTime(new DateTime(timereference.Year, timereference.Month, timereference.Day, 0, 0, 0, DateTimeKind.Local)); string query = string.Format("template:\"{0}\"", eventFrameTemplate.Name); AFEventFrameSearch eventFrameSearch = new AFEventFrameSearch(database, "EventFrame Captures", AFEventFrameSearchMode.ForwardFromStartTime, startTime, query); int startIndex = 0; foreach (AFEventFrame item in eventFrameSearch.FindEventFrames()) { item.CaptureValues(); if ((startIndex++ % 512) == 0) database.CheckIn(); } database.CheckIn(); }
static void PrintReport(AFDatabase database, AFElementTemplate eventFrameTemplate) { DateTime timereference = DateTime.Now.AddDays(-7); AFTime startTime = new AFTime(new DateTime(timereference.Year, timereference.Month, timereference.Day, 0, 0, 0, DateTimeKind.Local)); AFTime endTime = startTime.LocalTime.AddDays(+8); string query = string.Format("template:\"{0}\" ElementName:\"{1}\"", eventFrameTemplate.Name, "Meter003"); AFEventFrameSearch eventFrameSearch = new AFEventFrameSearch(database, "EventFrame Captures", AFSearchMode.StartInclusive, startTime, endTime, query); foreach (AFEventFrame ef in eventFrameSearch.FindEventFrames()) { Console.WriteLine("{0}, {1}, {2}", ef.Name, ef.PrimaryReferencedElement.Name, ef.Attributes["Average Energy Usage"].GetValue().Value); } }
public void PrintEnergyUsageAtTime(string timeStamp) { AFAttributeList attrList = GetAttributes(); AFTime time = new AFTime(timeStamp); IList<AFValue> vals = attrList.Data.RecordedValue(time); foreach (AFValue val in vals) { Console.WriteLine("Meter name: {0}, Timestamp (Local): {1}, Value (kilowatt hour): {2}", val.Attribute.Element.Name, val.Timestamp.LocalTime, val.Value); } }
static void SwapValues(AFDatabase database, string meter1, string meter2, string startTime, string endTime) { Console.WriteLine(string.Format("Swap values for meters: {0}, {1} between {2} and {3}", meter1, meter2, startTime, endTime)); // NOTE: This method does not ensure that there is no data loss if there is failure. // Persist the data first in case you need to rollback. AFAttribute attr1 = AFAttribute.FindAttribute(@"\Meters\" + meter1 + @"|Energy Usage", database); AFAttribute attr2 = AFAttribute.FindAttribute(@"\Meters\" + meter2 + @"|Energy Usage", database); AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); // Get values to delete for meter1 AFValues valsToRemove1 = attr1.Data.RecordedValues( timeRange: timeRange, boundaryType: AFBoundaryType.Inside, desiredUOM: null, filterExpression: null, includeFilteredValues: false); // Get values to delete for meter2 AFValues valsToRemove2 = attr2.Data.RecordedValues( timeRange: timeRange, boundaryType: AFBoundaryType.Inside, desiredUOM: null, filterExpression: null, includeFilteredValues: false); List<AFValue> valsToRemove = valsToRemove1.ToList(); valsToRemove.AddRange(valsToRemove2.ToList()); // Remove the values AFListData.UpdateValues(valsToRemove, AFUpdateOption.Remove); // Create new AFValues from the other meter and assign them to this meter List<AFValue> valsToAdd1 = valsToRemove2.Select(v => new AFValue(attr1, v.Value, v.Timestamp)).ToList(); List<AFValue> valsToAdd2 = valsToRemove1.Select(v => new AFValue(attr2, v.Value, v.Timestamp)).ToList(); List<AFValue> valsCombined = valsToAdd1; valsCombined.AddRange(valsToAdd2); AFListData.UpdateValues(valsCombined, AFUpdateOption.Insert); Console.WriteLine(); }
private IEnumerable<AFValue> ReadData(AFTime startTime, AFTime endTime) { return new TimeSortedValueScanner { Points = m_points, StartTime = startTime, EndTime = endTime, DataReadExceptionHandler = ex => OnProcessException(MessageLevel.Warning, ex) } .Read(); }
private RouteInfo GetRouteInfo(AFElement element, List<TrackPoint> wayPoints, string activityName) { if (element == null) { PIFitnessLog.Write(TraceEventType.Warning, 0, "AF Element is null"); return null; } try { //update latitude, longitude, and elevation AFAttribute elevationAttribute = element.Elements["Routes"].Attributes["Elevation"]; AFAttribute latitudeAttribute = element.Elements["Routes"].Attributes["Latitude"]; AFAttribute longitudeAttribute = element.Elements["Routes"].Attributes["Longitude"]; AFValues listElevationValues = new AFValues(); AFValues listLatitudeValues = new AFValues(); AFValues listLongitudeValues = new AFValues(); foreach (TrackPoint point in wayPoints) { AFTime timestamp = new AFTime(point.Time); listElevationValues.Add(new AFValue(elevationAttribute, point.Elevation, timestamp)); listLatitudeValues.Add(new AFValue(latitudeAttribute, point.Latitude, timestamp)); listLongitudeValues.Add(new AFValue(longitudeAttribute, point.Longitude, timestamp)); } //now update the activity tag AFAttribute rkActivityAttribute = element.Elements["Routes"].Attributes["Activity"]; DateTime temp_time = (from pt in wayPoints orderby pt.Time ascending select pt.Time).FirstOrDefault(); AFValues listActivityValues = new AFValues(); listActivityValues.Add(new AFValue(rkActivityAttribute, activityName, temp_time)); temp_time = (from pt in wayPoints orderby pt.Time descending select pt.Time).FirstOrDefault(); temp_time = temp_time.AddSeconds((double)1.0); //increment by one second listActivityValues.Add(new AFValue(rkActivityAttribute, "Idle", temp_time)); //package all the results IList<AFValues> listAFValues = new List<AFValues>(); listAFValues.Add(listElevationValues); listAFValues.Add(listLatitudeValues); listAFValues.Add(listLongitudeValues); listAFValues.Add(listActivityValues); // get the EF info AFTime start = listLatitudeValues[0].Timestamp; AFTime end = listLatitudeValues[listLatitudeValues.Count - 1].Timestamp; string displayedTime = start.UtcTime.ToString(); string efName = string.Format("{0} - {1} - {2}", element.Name, activityName, displayedTime); return new RouteInfo { Element = element, Values = listAFValues, ActivityName = activityName, UniqueName = efName, UserName = element.Name, StartTime = start, EndTime = end }; } catch (Exception ex) { PIFitnessLog.Write(TraceEventType.Error, 0, ex); return null; } }
// Process next data read private void m_readTimer_Elapsed(object sender, ElapsedEventArgs e) { List<IMeasurement> measurements = new List<IMeasurement>(); if (Monitor.TryEnter(m_readTimer)) { try { AFValue currentPoint = m_dataReader.Current; long timestamp = currentPoint.Timestamp.UtcTime.Ticks; if (m_publicationTime == 0) m_publicationTime = timestamp; // Set next reasonable publication time while (m_publicationTime < timestamp) m_publicationTime += m_publicationInterval; do { try { // Add current measurement to the collection for publication measurements.Add(new Measurement { Metadata = m_tagKeyMap[currentPoint.PIPoint.ID].Metadata, Timestamp = m_simulateTimestamp ? DateTime.UtcNow.Ticks : timestamp, Value = Convert.ToDouble(currentPoint.Value), StateFlags = ConvertStatusFlags(currentPoint.Status) }); } catch (Exception ex) { OnProcessException(MessageLevel.Info, new InvalidOperationException("Failed to map AFValue to Measurement: " + ex.Message, ex)); } // Attempt to move to next record if (timestamp < m_stopTime.UtcTime.Ticks && m_dataReader.MoveNext()) { // Read record value currentPoint = m_dataReader.Current; timestamp = currentPoint.Timestamp.UtcTime.Ticks; } else { if (timestamp < m_stopTime.UtcTime.Ticks && m_startTime.UtcTime.Ticks < timestamp) { // Could be attempting read with a future end time - in these cases attempt to re-read current data // from now to end time in case any new data as been archived in the mean-time m_startTime = new AFTime(timestamp + Ticks.PerMillisecond); m_dataReader = ReadData(m_startTime, m_stopTime).GetEnumerator(); if (!m_dataReader.MoveNext()) { // Finished reading all available data m_readTimer.Enabled = false; if (m_autoRepeat) ThreadPool.QueueUserWorkItem(StartDataReader); else OnProcessingComplete(); } } else { // Finished reading all available data m_readTimer.Enabled = false; if (m_autoRepeat) ThreadPool.QueueUserWorkItem(StartDataReader); else OnProcessingComplete(); } break; } } while (timestamp <= m_publicationTime); } catch (InvalidOperationException) { // Pooled timer thread executed after last read, verify timer has stopped m_readTimer.Enabled = false; } finally { Monitor.Exit(m_readTimer); } } // Publish all measurements for this time interval if (measurements.Count > 0) OnNewMeasurements(measurements); }
// 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)); } }
static void CreateEventFrames(AFDatabase database, AFElementTemplate eventFrameTemplate) { const int pageSize = 1000; int startIndex = 0; int totalCount; do { AFNamedCollectionList<AFBaseElement> results = database.ElementTemplates["MeterBasic"].FindInstantiatedElements( includeDerived: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: startIndex, maxCount: pageSize, totalCount: out totalCount ); IList<AFElement> meters = results.Select(elm => (AFElement)elm).ToList(); DateTime timereference = DateTime.Now.AddDays(-7); //AFTime startTime = new AFTime(new DateTime(timereference.Year, timereference.Month, timereference.Day, 0, 0, 0, DateTimeKind.Local)); foreach (AFElement meter in meters) { foreach (int day in Enumerable.Range(1, 7)) { AFTime startTime = new AFTime(timereference.AddDays(day - 1)); AFTime endTime = new AFTime(startTime.LocalTime.AddDays(1)); AFEventFrame ef = new AFEventFrame(database, "*", eventFrameTemplate); ef.SetStartTime(startTime); ef.SetEndTime(endTime); ef.PrimaryReferencedElement = meter; } } database.CheckIn(); startIndex += pageSize; } while (startIndex < totalCount); database.CheckIn(); }
private static AFValues GenerateValueSequence(AFAttribute attribute, AFTime start, AFTime end, AFTimeSpan interval) { float zero = 100.0F; float span = 360.0F; AFValues values = new AFValues(); AFTime timestamp = start; Random rnd = new Random((int)DateTime.Now.Ticks % 86400); int idx = 1; while (timestamp <= end) { values.Add(new AFValue(attribute, zero + (float)rnd.NextDouble() * span, timestamp)); timestamp = interval.Multiply(start, idx++); } return values; }
static void PrintEnergyUsageAtTime(AFDatabase database, string timeStamp) { Console.WriteLine("Print Energy Usage at Time: {0}", timeStamp); AFAttributeList attrList = GetAttributes(database, "MeterBasic", "Energy Usage"); AFTime time = new AFTime(timeStamp); IList<AFValue> vals = attrList.Data.RecordedValue(time); foreach (AFValue val in vals) { Console.WriteLine("Meter: {0}, Timestamp (Local): {1}, Value (kWh): {2}", val.Attribute.Element.Name, val.Timestamp.LocalTime, val.Value); } Console.WriteLine(); }
/// <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); } }
static void PrintDailyAverageEnergyUsage(AFDatabase database, string startTime, string endTime) { Console.WriteLine(string.Format("Print Daily Energy Usage - Start: {0}, End: {1}", startTime, endTime)); AFAttributeList attrList = GetAttributes(database, "MeterBasic", "Energy Usage"); AFTime start = new AFTime(startTime); AFTime end = new AFTime(endTime); AFTimeRange timeRange = new AFTimeRange(start, end); // Ask for 100 PI Points at a time PIPagingConfiguration pagingConfig = new PIPagingConfiguration(PIPageType.TagCount, 100); IEnumerable<IDictionary<AFSummaryTypes, AFValues>> summaries = attrList.Data.Summaries( timeRange: timeRange, summaryDuration: new AFTimeSpan(TimeSpan.FromDays(1)), summaryTypes: AFSummaryTypes.Average, calculationBasis: AFCalculationBasis.TimeWeighted, timeType: AFTimestampCalculation.EarliestTime, pagingConfig: pagingConfig); // Loop through attributes foreach (IDictionary<AFSummaryTypes, AFValues> dict in summaries) { AFValues values = dict[AFSummaryTypes.Average]; Console.WriteLine("Averages for Meter: {0}", values.Attribute.Element.Name); // Loop through values per attribute foreach (AFValue val in dict[AFSummaryTypes.Average]) { Console.WriteLine("Timestamp (Local): {0}, Avg. Value (kWh): {1}", val.Timestamp.LocalTime, val.Value); } Console.WriteLine(); } Console.WriteLine(); }
private static AFValue GenerateValue(AFAttribute attribute, Random rnd, float zero, float span, AFTime timestamp) { return new AFValue(attribute, zero + (float)rnd.NextDouble() * span, timestamp); }
public void PrintReport() { const int pageSize = 1000; int startIndex = 0; AFTime startTime = new AFTime(new DateTime(2015, 12, 29, 0, 0, 0, DateTimeKind.Local)); AFTime endTime = new AFTime(new DateTime(2015, 12, 31, 0, 0, 0, DateTimeKind.Local)); AFNamedCollectionList<AFEventFrame> efs; do { efs = AFEventFrame.FindEventFrames( database: _database, searchRoot: null, searchMode: AFSearchMode.StartInclusive, startTime: startTime, endTime: endTime, startIndex: startIndex, maxCount: pageSize, nameFilter: "*", referencedElementNameFilter: "Meter003", eventFrameCategory: null, eventFrameTemplate: _eventFrameTemplate, referencedElementTemplate: null, durationQuery: null, searchFullHierarchy: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending ); AFEventFrame.LoadEventFrames(efs); foreach (AFEventFrame ef in efs) { Console.WriteLine("{0}, {1}, {2}", ef.Name, ef.PrimaryReferencedElement.Name, ef.Attributes["Average Energy Usage"].GetValue().Value); } startIndex += pageSize; } while (efs != null && efs.Count > 0); }
public WAFTime() { m_Time = new AFTime(DateTime.Now); }
public List<AFValue> GetRandomValues(PIPoint point, AFTime startTime, AFTime endTime, TimeSpan interval) { var newValues=new List<AFValue>(); var currentTime = startTime.LocalTime; while (currentTime <= endTime.LocalTime) { newValues.Add(new AFValue() { PIPoint = point, Timestamp = currentTime, Value = 1000*_random.NextDouble() }); currentTime = currentTime.Add(interval); } return newValues; }