public void CreateFitnessElement(string userName, string elementName, AFElementTemplate template) { _db.Refresh(); AFElement userElement = _db.Elements[userName]; if (userElement == null) { PIFitnessLog.Write(TraceEventType.Information, 0, string.Format("Could not find AF element for user {0}", userName)); return; } //lock(_db) //{ AFElement fitnessElement = userElement.Elements[elementName]; if (fitnessElement == null) { fitnessElement = userElement.Elements.Add(elementName, template); AFDataReference.CreateConfig(fitnessElement, false, null); _db.CheckIn(AFCheckedOutMode.ObjectsCheckedOutThisThread); PIFitnessLog.Write(TraceEventType.Information, 0, string.Format("Created fitness element {0} for user {1}", elementName, userName)); } //} }
// Add additional methods as necessary public static IList<AFElement> LoadElements(AFElementTemplate elementTemplate, IEnumerable<string> attributesToLoad) { List<AFElement> results = new List<AFElement>(); // Your code here return results; }
public UserSyncProcessor(ITableReader<UserEntry> reader, IAFAccess afAccess, AFElementTemplate userTemplate) { _reader = reader; _afAccess = afAccess; _template = userTemplate; }
public static string GetBaseTemplateName(AFElementTemplate elmTemplate) { if (elmTemplate == null) return String.Empty; AFElementTemplate currElementTemplate = elmTemplate; while (currElementTemplate.BaseTemplate != null) { currElementTemplate = currElementTemplate.BaseTemplate; } return currElementTemplate.Name; }
public ElementContainer(AFElementTemplate elementTemplate, AFElement containerElement, Boolean isLeaf) { ElementTemplate = elementTemplate; ContainerElement = containerElement; _isLeaf = isLeaf; if (!isLeaf) { foreach (var item in ContainerElement.Elements) { _elements.Add(item.Name, item); } } }
public GPXProcessor(ITableReader<GPXEntry> reader, IGPXRowProcessor rowProcessor, IAFAccess afAccess, ITableWriter<GPXEntry> writer, [Named("GpxElement")] AFElementTemplate gpxTemplate, [Named("GpxEventFrame")] AFElementTemplate efTemplate) { _reader = reader; _rowProcessor = rowProcessor; _afAccess = afAccess; _writer = writer; _template = gpxTemplate; _efTemplate = efTemplate; }
public void CreateEventFrameTemplate() { _eventFrameTemplate = _database.ElementTemplates.Add("Daily Usage"); _eventFrameTemplate.InstanceType = typeof(AFEventFrame); _eventFrameTemplate.NamingPattern = @"%TEMPLATE%-%ELEMENT%-%STARTTIME:yyyy-MM-dd%*"; AFAttributeTemplate usage = _eventFrameTemplate.AttributeTemplates.Add("Average Energy Usage"); usage.Type = typeof(double); usage.DataReferencePlugIn = AFDataReference.GetPIPointDataReference(); usage.ConfigString = @".\Elements[.]|Energy Usage;TimeRangeMethod=Average"; usage.DefaultUOM = _database.PISystem.UOMDatabase.UOMs["kilowatt hour"]; _database.CheckIn(); }
public void CreateUserElement(string userName, string id, AFElementTemplate template) { _db.Refresh(); AFElement userElement = _db.Elements[userName]; if (userElement == null) { userElement = _db.Elements.Add(userName, template); userElement.ExtendedProperties.Add("Guid", id); AFDataReference.CreateConfig(userElement, false, null); _db.CheckIn(AFCheckedOutMode.ObjectsCheckedOutThisThread); PIFitnessLog.Write(TraceEventType.Information, 0, string.Format("Created AF element for user {0}", userName)); } }
public bool CheckEventFrameExists(AFElement element, string name, AFElementTemplate efTemplate) { AFNamedCollectionList<AFEventFrame> listEF = element.GetEventFrames(new AFTime("*"), 0, 1, AFEventFrameSearchMode.BackwardFromStartTime, name, null, efTemplate); if (listEF.Count > 0) { PIFitnessLog.Write(TraceEventType.Information, 0, string.Format("Event frame already exists: {0}", name)); return true; } else { return false; } }
public static IList<AFElement> LoadElements(AFElementTemplate elementTemplate, IEnumerable<string> attributesToLoad) { int totalCount; int startIndex = 0; int pageSize = 1000; List<AFElement> results = new List<AFElement>(); // Paging pattern do { var baseElements = elementTemplate.FindInstantiatedElements( includeDerived: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: startIndex, maxCount: pageSize, totalCount: out totalCount); // If there are no elements, break the process if (baseElements.Count == 0) break; IEnumerable<AFElement> elements = baseElements.OfType<AFElement>(); IEnumerable<IGrouping<AFElementTemplate, AFElement>> elementGroupings = elements.GroupBy(elm => elm.Template); foreach (var item in elementGroupings) { // The passed in attribute template name may belong to a base element template. // GetLastAttributeTemplateOverride searches upwards the template inheritance chain // until it finds the desired attribute template. List<AFAttributeTemplate> attrTemplates = attributesToLoad .Select(atr => GetLastAttributeTemplateOverride(item.Key, atr)) .Where(atr => atr != null) .ToList(); List<AFElement> elementsToLoad = item.ToList(); AFElement.LoadAttributes(elementsToLoad, attrTemplates); results.AddRange(elementsToLoad); } startIndex += baseElements.Count; } while (startIndex < totalCount); return results; }
private static AFAttributeTemplate GetLastAttributeTemplateOverride(AFElementTemplate elmTemplate, string attributeName) { if (elmTemplate == null) throw new ArgumentNullException("elmTemplate"); AFElementTemplate currElementTemplate = elmTemplate; do { var attrTemplate = currElementTemplate.AttributeTemplates[attributeName]; if (attrTemplate != null) return attrTemplate; else currElementTemplate = currElementTemplate.BaseTemplate; } while (currElementTemplate != null); return null; }
public static void CreateAttributeTemplate(string name, AFElementTemplate elementTemplate, Type attributeType, UOM attributeUOM) { AFAttributeTemplate myAttributeTemplate = elementTemplate.AttributeTemplates[name]; if (myAttributeTemplate == null) { myAttributeTemplate = elementTemplate.AttributeTemplates.Add(name); } myAttributeTemplate.DataReferencePlugIn = myPISystem.DataReferencePlugIns["PI Point"]; myAttributeTemplate.Type = attributeType; myAttributeTemplate.DefaultUOM = attributeUOM; if (myAttributeTemplate.DefaultUOM == null) { myAttributeTemplate.ConfigString = @"\\" + PIServerName + @"\%Element%_%Attribute%;"; } else { myAttributeTemplate.ConfigString = @"\\" + PIServerName + @"\%Element%_%Attribute%;UOM=" + myAttributeTemplate.DefaultUOM.Abbreviation; } }
public FitbitProcessor( IAFAccess afAccess, ITableReader<UserEntry> reader, IFitbitUserFactory fitbitUserFactory, Dictionary<string, FitbitUser> fitbitUserCache, FitbitStreams fitbitStreams, FitbitValuesConverter fitbitConverter, AFElementTemplate elementTemplate) { _afAccess = afAccess; _reader = reader; _fitbitUserFactory = fitbitUserFactory; _fitbitUserCache = fitbitUserCache; _template = elementTemplate; _fitbitStreams = fitbitStreams; _fitbitConverter = fitbitConverter; _count = 0; }
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; } }
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(); }
/// <summary> /// Loads Elements from an AF Database in a manner that is not blocking the application /// and is more efficient with big databases /// </summary> /// <param name="database">The AFdatabase that contains the elements to load</param> /// <param name="template"> the Element Template associated with the elements to load</param> /// <param name="elementsConcurrentQueue">Concurrent queue in which the elements will be loaded</param> public static void LoadElementsByTemplate(AFDatabase database, AFElementTemplate template, ConcurrentQueue<AFElement> elementsConcurrentQueue) { // set variables const int chunkSize = 10000; int index = 0; int total; do { // loads elements by chunk of 10K values var elements = template.FindInstantiatedElements(true, AFSortField.Name, AFSortOrder.Ascending, index, chunkSize, out total); var elementCount = elements.Count; if (elementCount == 0) break; // Convert a list of AFBaseElement to a list of AFElement List<AFElement> elementsList = elements.Select(e => (AFElement)e).ToList(); // forces full load of elements AFElement.LoadElementsToDepth(elementsList,true,5,1000000); // if you'd like to filter the elements by attributes... // however this would be sub-optimal, it would be better to filter directly on the FindInstanciated Elements query. //i.e. elementsList = elementsList.Where(e => (bool)e.Attributes["attribute to filter"].GetValue().Value == true).ToList(); foreach (var afElement in elementsList) { elementsConcurrentQueue.Enqueue(afElement); } _logger.InfoFormat(" Load Elements by Template | StartIndex = {1} | Found a chunk of {2} elements", DateTime.Now, index, elementCount); index += chunkSize; } while (index < total); // the findElements call we are using returns a paged collection to lower the memory foortprint }
public bool CreateBikeStationTemplate() { if (afDb.ElementTemplates[bikeStationElementTemplateName] == null) { log.Debug("Creating BikeStationTemplate.."); AFElementTemplate template = afDb.ElementTemplates.Add(bikeStationElementTemplateName); UOM degree = piSystem.UOMDatabase.UOMClasses["Plane Angle"].UOMs["degree"]; AddAttributeTemplate(template, "Latitude", typeof(double), false, degree, string.Empty); AddAttributeTemplate(template, "Longitude", typeof(double), false, degree, string.Empty); AddAttributeTemplate(template, "Id", typeof(string), false, null, string.Empty); AddAttributeTemplate(template, "StationNumber", typeof(int), false, null, string.Empty); AddAttributeTemplate(template, "Free Bikes", typeof(int), true, null, string.Empty); AddAttributeTemplate(template, "Empty Slots", typeof(int), true, null, string.Empty); AddAttributeTemplate(template, "Source", typeof(string), false, null, string.Empty); template.AttributeTemplates["Source"].SetValue("https://api.citybik.es/v2/", null); return(true); } else { log.Debug("BikeStationTemplate is already created."); return(false); } }
static AFElementTemplate CreateEventFrameTemplate(AFDatabase database) { AFElementTemplate eventframetemplate = null; if (database.ElementTemplates.Contains("Daily Usage")) { return(database.ElementTemplates["Daily Usage"]); } eventframetemplate = database.ElementTemplates.Add("Daily Usage"); eventframetemplate.InstanceType = typeof(AFEventFrame); eventframetemplate.NamingPattern = @"%TEMPLATE%-%ELEMENT%-%STARTTIME:yyyy-MM-dd%-EF*"; AFAttributeTemplate usage = eventframetemplate.AttributeTemplates.Add("Average Energy Usage"); usage.Type = typeof(double); usage.DataReferencePlugIn = AFDataReference.GetPIPointDataReference(); usage.ConfigString = @".\Elements[.]|Energy Usage;TimeRangeMethod=Average"; usage.DefaultUOM = database.PISystem.UOMDatabase.UOMs["kilowatt hour"]; database.CheckIn(); return(eventframetemplate); }
public bool CreateCityTemplate() { if (afDb.ElementTemplates[cityElementTemplateName] == null) { log.Debug("Creating CityTemplate..."); AFElementTemplate cityTemplate = afDb.ElementTemplates.Add(cityElementTemplateName); UOM degree = piSystem.UOMDatabase.UOMClasses["Plane Angle"].UOMs["degree"]; AddAttributeTemplate(cityTemplate, "Company", typeof(string), false, null, string.Empty); AddAttributeTemplate(cityTemplate, "Url", typeof(string), false, null, string.Empty); AddAttributeTemplate(cityTemplate, "Id", typeof(string), false, null, string.Empty); AddAttributeTemplate(cityTemplate, "CityNumber", typeof(int), false, null, string.Empty); AddAttributeTemplate(cityTemplate, "Latitude", typeof(double), false, degree, string.Empty); AddAttributeTemplate(cityTemplate, "Longitude", typeof(double), false, degree, string.Empty); AddAttributeTemplate(cityTemplate, "City", typeof(string), false, null, string.Empty); AddAttributeTemplate(cityTemplate, "Country", typeof(string), false, null, string.Empty); return(true); } else { log.Debug("CityTemplate is already created."); return(false); } }
static void CreateFeederElements(AFDatabase database, String FeederName) { Console.WriteLine("Creating new element using feeder template.."); AFElementTemplate template = database.ElementTemplates["Feeders"]; AFElement feeder = database.Elements["Feeders"]; if (template == null || feeder == null) { Console.WriteLine("Feeder template and parent missing"); return; } if (feeder.Elements.Contains(FeederName)) { return; } AFElement feeder01 = feeder.Elements.Add(FeederName, template); AFAttribute city = feeder01.Attributes["City"]; if (city != null) { city.SetValue(new AFValue("London")); } AFAttribute power = feeder01.Attributes["Power"]; power.ConfigString = @"\\PU-PIDARCDEV01\SINUSOID"; if (database.IsDirty) { database.CheckIn(); } }
/// <summary> /// Find elements implementing a given AF Element Template and load a list of attributes from these elements /// </summary> private List<AFElement> FindElements(AFElementTemplate elementTemplate, IEnumerable<string> attributesToLoad) { int totalCount; int startIndex = 0; var results = new List<AFElement>(); do { var baseElements = elementTemplate.FindInstantiatedElements( includeDerived: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: startIndex, maxCount: ChunkSize, totalCount: out totalCount); // if there is no new leaf elements, break the process if (baseElements.Count() == 0) break; var elements = baseElements.Select(elm => (AFElement)elm).ToList(); var elementGroupings = elements.GroupBy(elm => elm.Template); foreach (var item in elementGroupings) { List<AFAttributeTemplate> attrTemplates = attributesToLoad.Select(atr => AFHelper.GetLastAttributeTemplateOverride(item.Key, atr)).ToList(); AFElement.LoadAttributes(item.ToList(), attrTemplates); } results.AddRange(elements); startIndex += baseElements.Count(); } while (startIndex < totalCount); return results; }
public void CreateAttributeTemplateTest() { PIAttributeTemplate attributeTemplate = new PIAttributeTemplate() { Name = "TableAttributeTemplate", Description = "2008 Water Use", Type = "Int32", TypeQualifier = "", DefaultValue = 0, DataReferencePlugIn = "Table Lookup", ConfigString = "SELECT [Water Use] FROM [Energy Use 2008] WHERE [Asset ID] = '%Element%'", IsConfigurationItem = false, IsExcluded = false, IsHidden = false, IsManualDataEntry = false, }; string path = Constants.AF_ELEMENT_TEMPLATE_PATH; instance.CreateAttributeTemplate(webId, attributeTemplate); AFElementTemplate myTemplate = AFObject.FindObject(path) as AFElementTemplate; myTemplate.Refresh(); Assert.IsNotNull(myTemplate.AttributeTemplates[attributeTemplate.Name]); }
static void translateAttribute(AFElementTemplate elem, AFAttributeTemplate attr, DataTable dt) { AFVariableMappingData variableMapping = null; AFAnalysisTemplate analysisTargetingAttribute = null; foreach (AFAnalysisTemplate analysis in elem.AnalysisTemplates) { analysis.AnalysisRule.VariableMap.TryGetMapping(attr.Name, out variableMapping); if (variableMapping != null) { analysisTargetingAttribute = analysis; break; } } attr.Name = translate(dt, attr.Name, "Japanese"); attr.Description = translate(dt, attr.Description, "Japanese"); elem.CheckIn(); if (analysisTargetingAttribute != null) { //analysisTargetingAttribute.AnalysisRule.VariableMap.SetMapping(attr.Name, variableMapping); analysisTargetingAttribute.AnalysisRule.VariableMap.RefreshMappings(elem); } }
static public void CaptureValues(AFDatabase database, AFElementTemplate 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.FindEventFrames()) { item.CaptureValues(); if ((count++ % 500) == 0) { database.CheckIn(); } } if (database.IsDirty) { database.CheckIn(); } } }
private void GetEventFrames_Click(object sender, EventArgs e) { if (afTreeView1.AFSelectedPath == afTreeView1.AFRootPath) { MessageBox.Show("Please Select Element from ElementTree"); } else { //Clear ListBoxes EFListView.Items.Clear(); EFAttrView.Items.Clear(); myElement = myAFDatabase.Elements[afTreeView1.AFSelectedPath]; AFAttributes myAFAttributes = myElement.Attributes; if (myAFAttributes.Count == 0) { //MessageBox.Show("No Attribute Found"); } else { AFNamedCollectionList<AFEventFrame> EFs; String SearchString = "ElementName:"+myElement.Name; //Use EventFrameTemplate for searching myElementTemplate = myAFDatabase.ElementTemplates[EventFrameTemplateComboBox.SelectedItem.ToString()]; EFs = myElement.GetEventFrames(AFSearchMode.Overlapped,StartTimeTextBox.Text,EndTimeTextBox.Text,"",null,myElementTemplate,AFSortField.StartTime,AFSortOrder.Descending,0,1000); foreach (AFEventFrame EF in EFs) { string[] displayvalues = new string[5]; displayvalues[0] = EF.Name; TimeSpan EFDuration = EF.EndTime - EF.StartTime; //Not ending eventframe returns 9999 year. if (EFDuration.TotalSeconds < 5000000) { displayvalues[1] = EFDuration.TotalSeconds.ToString(); } else { displayvalues[1] = "-"; } displayvalues[2] = EF.StartTime.LocalTime.ToString(); displayvalues[3] = EF.EndTime.LocalTime.ToString(); displayvalues[4] = EF.UniqueID; ListViewItem lvi = new ListViewItem(displayvalues); EFListView.Items.Add(lvi); } } } }
public static void CreateMeterAdvancedTemplate(AFElementTemplate meterBasicTemplate) { // Your code here }
private static void CreateTemplates(AFDatabase database) { if (database == null) { return; } UOM uom = database.PISystem.UOMDatabase.UOMs["kilowatt hour"]; AFCategory mEnergyE = database.ElementCategories["Measures Energy"]; AFCategory sStatusE = database.ElementCategories["Shows Status"]; AFCategory bInfoA = database.AttributeCategories["Building Info"]; AFCategory locationA = database.AttributeCategories["Location"]; AFCategory tsDataA = database.AttributeCategories["Time-Series Data"]; AFEnumerationSet bTypeNum = database.EnumerationSets["Building Type"]; AFEnumerationSet mStatusEnum = database.EnumerationSets["Meter Status"]; // Create MeterBasic Element Template AFElementTemplate meterBasicTemplate; if (!database.ElementTemplates.Contains("MeterBasic")) { meterBasicTemplate = database.ElementTemplates.Add("MeterBasic"); meterBasicTemplate.Categories.Add(mEnergyE); AFAttributeTemplate substationAttrTemp = meterBasicTemplate.AttributeTemplates.Add("Substation"); substationAttrTemp.Type = typeof(string); AFAttributeTemplate usageLimitAttrTemp = meterBasicTemplate.AttributeTemplates.Add("Usage Limit"); usageLimitAttrTemp.Type = typeof(string); usageLimitAttrTemp.DefaultUOM = uom; AFAttributeTemplate buildingAttrTemp = meterBasicTemplate.AttributeTemplates.Add("Building"); buildingAttrTemp.Type = typeof(string); buildingAttrTemp.Categories.Add(bInfoA); AFAttributeTemplate bTypeAttrTemp = meterBasicTemplate.AttributeTemplates.Add("Building Type"); bTypeAttrTemp.TypeQualifier = bTypeNum; bTypeAttrTemp.Categories.Add(bInfoA); AFAttributeTemplate districtAttrTemp = meterBasicTemplate.AttributeTemplates.Add("District"); districtAttrTemp.Type = typeof(string); districtAttrTemp.Categories.Add(locationA); AFAttributeTemplate energyUsageAttrTemp = meterBasicTemplate.AttributeTemplates.Add("Energy Usage"); energyUsageAttrTemp.Type = typeof(double); energyUsageAttrTemp.Categories.Add(tsDataA); energyUsageAttrTemp.DefaultUOM = uom; energyUsageAttrTemp.DataReferencePlugIn = database.PISystem.DataReferencePlugIns["PI Point"]; energyUsageAttrTemp.ConfigString = @"\\%Server%\%Element%.%Attribute%;UOM=kWh"; } else { meterBasicTemplate = database.ElementTemplates["MeterBasic"]; } // Create MeterAdvanced Element Template if (!database.ElementTemplates.Contains("MeterAdvanced")) { AFElementTemplate meterAdvancedTemplate = database.ElementTemplates.Add("MeterAdvanced"); meterAdvancedTemplate.BaseTemplate = meterBasicTemplate; AFAttributeTemplate statusAttrTemp = meterAdvancedTemplate.AttributeTemplates.Add("Status"); statusAttrTemp.TypeQualifier = mStatusEnum; statusAttrTemp.Categories.Add(tsDataA); statusAttrTemp.DataReferencePlugIn = database.PISystem.DataReferencePlugIns["PI Point"]; statusAttrTemp.ConfigString = @"\\%Server%\%Element%.%Attribute%"; // Create District Element Template AFElementTemplate districtTemplate = database.ElementTemplates.Add("District"); AFAttributeTemplate districtEnergyUsageAttrTemp = districtTemplate.AttributeTemplates.Add("Energy Usage"); districtEnergyUsageAttrTemp.Type = typeof(double); districtEnergyUsageAttrTemp.DefaultUOM = uom; districtEnergyUsageAttrTemp.DataReferencePlugIn = database.PISystem.DataReferencePlugIns["PI Point"]; districtEnergyUsageAttrTemp.ConfigString = @"\\%Server%\%Element%.%Attribute%"; } // Do a checkin at the end instead of one-by-one. database.CheckIn(); }
static AFEventFrameCriteria queryToCriteria(OSIsoft.AF.Search.AFEventFrameSearch query) { AFEventFrameCriteria criteria = new AFEventFrameCriteria(); criteria.Database = query.Database; IList <AFSearchToken> starts; query.TryFindSearchTokens(OSIsoft.AF.Search.AFSearchFilter.Start, out starts); IList <AFSearchToken> ends; query.TryFindSearchTokens(OSIsoft.AF.Search.AFSearchFilter.End, out ends); AFSearchToken templatename; query.TryFindSearchToken(OSIsoft.AF.Search.AFSearchFilter.Template, out templatename); IList <AFSearchToken> values; query.TryFindSearchTokens(OSIsoft.AF.Search.AFSearchFilter.Value, out values); if (values.Count != 0) { AFAttributeValueQuery[] queries = new AFAttributeValueQuery[values.Count]; criteria.AttributeValueQueries = new AFAttributeValueQuery[values.Count]; criteria.TemplateName = templatename.Value; for (int i = 0; i < values.Count; i++) { AFSearchToken value = values[i]; string attributeName = value.Path.TrimStart(new char[] { '|' }); AFElementTemplate template = query.Database.ElementTemplates[templatename.Value]; AFAttributeTemplate templateAttribute = template.AttributeTemplates[attributeName]; queries[i] = new AFAttributeValueQuery(templateAttribute, value.Operator, value.Value, templateAttribute.DefaultUOM); criteria.AttributeValueQueries[i] = new AFAttributeValueQuery(templateAttribute, value.Operator, value.Value, templateAttribute.DefaultUOM); } //criteria.AttributeValueQueries = queries; //criteria.ValueQueryString = value.ToString(); //criteria. } if (ends.Count == 2) { criteria.SearchType = OSIsoft.AF.UI.Search.AFBaseEventFrameCriteria.EventFrameSearchType.EndingBetween; criteria.StartTime = ends[0].Value; criteria.EndTime = ends[1].Value; } else if (starts.Count == 2) { criteria.SearchType = OSIsoft.AF.UI.Search.AFBaseEventFrameCriteria.EventFrameSearchType.StartingBetween; criteria.StartTime = starts[0].Value; criteria.EndTime = starts[1].Value; } else if (starts.Count == 1 && ends.Count == 1) { AFSearchToken start = starts[0]; AFSearchToken end = ends[0]; if (start.Operator == AFSearchOperator.LessThanOrEqual && end.Operator == AFSearchOperator.GreaterThanOrEqual) { criteria.SearchType = OSIsoft.AF.UI.Search.AFBaseEventFrameCriteria.EventFrameSearchType.ActiveBetween; criteria.StartTime = end.Value; criteria.EndTime = start.Value; } else if (start.Operator == AFSearchOperator.GreaterThanOrEqual && end.Operator == AFSearchOperator.LessThanOrEqual) { criteria.SearchType = OSIsoft.AF.UI.Search.AFBaseEventFrameCriteria.EventFrameSearchType.EntirelyBetween; criteria.StartTime = start.Value; criteria.EndTime = end.Value; } } else if (starts.Count == 1) { AFSearchToken start = starts[0]; if (start.Operator == AFSearchOperator.GreaterThanOrEqual) { criteria.SearchType = OSIsoft.AF.UI.Search.AFBaseEventFrameCriteria.EventFrameSearchType.StartingAfter; } else { criteria.SearchType = OSIsoft.AF.UI.Search.AFBaseEventFrameCriteria.EventFrameSearchType.StartingBefore; } criteria.AFStartTimeString = start.Value; } else if (ends.Count == 1) { AFSearchToken end = ends[0]; if (end.Operator == AFSearchOperator.GreaterThanOrEqual) { criteria.SearchType = OSIsoft.AF.UI.Search.AFBaseEventFrameCriteria.EventFrameSearchType.EndingAfter; } else { criteria.SearchType = OSIsoft.AF.UI.Search.AFBaseEventFrameCriteria.EventFrameSearchType.EndingBefore; } criteria.AFStartTimeString = end.Value; } criteria.LastFullSearchString = stripTokens(query); return(criteria); }
public static string GetTimeSeriesName(this AFElementTemplate template, int id, Resolution resolution, ValueType valueType) => $"{template.GetElementName(id)}.{GetAttributeName(resolution, valueType)}";
public static void AddElement(this AFElementTemplate template, int id) => template.Database.Elements.Add(template.GetElementName(id), template).CheckIn();
public AttrLookupDRConfig(AttrLookupDR dataReference, bool bReadOnly) { InitializeComponent(); fDataReference = dataReference; if (dataReference.Attribute != null) { AFElement elem = dataReference.Attribute.Element as AFElement; if (elem != null) { ProcessAttributes(elem.Attributes, "", Extensions.IsStringVal, txtAttribute); } } else if (dataReference.Template != null) { AFElementTemplate templ = dataReference.Template.ElementTemplate as AFElementTemplate; if (templ != null) { ProcessAttributes(templ.AttributeTemplates, "", Extensions.IsStringVal, txtAttribute); } } if (dataReference.Attribute != null) { AFElement elem = dataReference.Attribute.Element as AFElement; if (elem != null) { ProcessAttributes(elem.Attributes, "", Extensions.IsDateTimeVal, cmbTSAttr); } } else if (dataReference.Template != null) { AFElementTemplate templ = dataReference.Template.ElementTemplate as AFElementTemplate; if (templ != null) { ProcessAttributes(templ.AttributeTemplates, "", Extensions.IsDateTimeVal, cmbTSAttr); } } if (bReadOnly) { txtAttribute.Enabled = false; btnOK.Visible = false; btnOK.Enabled = false; btnCancel.Left = (btnOK.Left + btnCancel.Left) / 2; btnCancel.Text = "Close"; base.AcceptButton = btnCancel; } if (!string.IsNullOrEmpty(dataReference.AttributeName)) { txtAttribute.Text = dataReference.AttributeName; } if (dataReference.TimestampType == "Attribute") { cmbTSAttr.Text = dataReference.TimestampSource; radAttribute.Checked = true; } else { radNone.Checked = true; } cmbMethod.SelectedIndex = (int)dataReference.MethodType; }
static void CreateEventFrames(AFDatabase database, AFElementTemplate eventFrameTemplate) { // Your code here }
static public void CaptureValues(AFDatabase database, AFElementTemplate eventFrameTemplate) { // Your code here }
private void CreateElementfromTemplate(string ElementName, object ElementTemplate) { try { AFElement myCreateElement; if (ElementTemplate == null) { //Not use ElementTemplate if (afTreeView1.AFSelectedPath == afTreeView1.AFRootPath) { myAFDatabase.Elements.Add(ElementName); } else { myCreateElement = myAFDatabase.Elements[afTreeView1.AFSelectedPath]; myCreateElement.Elements.Add(ElementName); } } else { //Use ElementTemplate myElementTemplate = myAFDatabase.ElementTemplates[ElementTemplate.ToString()]; if (afTreeView1.AFSelectedPath == afTreeView1.AFRootPath) { myAFDatabase.Elements.Add(ElementName,myElementTemplate); } else { myCreateElement = myAFDatabase.Elements[afTreeView1.AFSelectedPath]; myCreateElement.Elements.Add(ElementName,myElementTemplate); } } myAFDatabase.CheckIn(); } catch (Exception ex) { MessageBox.Show("Exception: " + ex.Message); } }
static void PrintReport(AFDatabase database, AFElementTemplate eventFrameTemplate) { // Your code here }
public void OMFTest() { // Use ticks as a unique id mask to avoid naming collisions with other PI Points var idTicks = $"{DateTime.UtcNow.Ticks}"; string typeId = $"TankMeasurement{idTicks}"; string containerId = $"Tank1Measurements{idTicks}"; PISystem omfAFServer = null; AFDatabase omfDatabase = null; PIServer omfPIServer = null; List <PIPoint> omfPIPoints = null; AFElementTemplate omfTypeAsTemplate = null; var jsonType = @"[ { ""id"": """ + typeId + @""", ""version"": ""1.0.0.0"", ""type"": ""object"", ""classification"": ""dynamic"", ""properties"": { ""Time"": { ""format"": ""date-time"", ""type"": ""string"", ""isindex"": true }, ""Pressure"": { ""type"": ""number"", ""name"": ""Tank Pressure"" }, ""Temperature"": { ""type"": ""number"", ""name"": ""Tank Temperature"" } } } ]"; var jsonContainer = @"[{ ""id"": """ + containerId + @""", ""typeid"": """ + typeId + @""", ""typeVersion"": ""1.0.0.0"", ""indexes"": [""Pressure""] }]"; var jsonData = @"[{ ""containerid"": """ + containerId + @""", ""values"": [{ ""Time"": ""2017-01-11T22:24:23.430Z"", ""Pressure"": 11.5, ""Temperature"": 101 }] }]"; var coll = new NameValueCollection { { "messagetype", "type" }, { "messageformat", "json" }, { "omfversion", "1.1" }, { "action", "create" }, }; try { // Create the type object var omfUrl = $"{Fixture.HomePageUrl}/omf"; Fixture.Client.Headers.Add(coll); Output.WriteLine($"Create OMF type through Web API using Url [{omfUrl}] and JSON [{jsonType}]."); var createTypeResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonType)); Assert.True(createTypeResponse["OperationId"] != null, $"OperationId not returned in OMF response."); // Create a container for the created type Fixture.Client.Headers["messagetype"] = "container"; Output.WriteLine($"Create OMF container through Web API using Url [{omfUrl}] and JSON [{jsonContainer}]."); var createContainerResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonContainer)); Assert.True(createContainerResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Add data to the container Fixture.Client.Headers["messagetype"] = "data"; Output.WriteLine($"Add data to the OMF container through Web API using Url [{omfUrl}] and JSON [{jsonData}]."); var createDataResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonData)); Assert.True(createDataResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Verify objects were created correctly in AF and PI var instanceConfigUrl = $"{Fixture.HomePageUrl}/system/instanceconfiguration"; var config = JObject.Parse(Fixture.Client.DownloadString(instanceConfigUrl)); Output.WriteLine($"Verify OMF objects were create in AF and PI through Web API using Url [{instanceConfigUrl}]."); omfAFServer = new PISystems()[(string)config["OmfAssetServerName"]]; omfDatabase = omfAFServer.Databases[(string)config["OmfAssetDatabaseName"]]; omfPIServer = PIServers.GetPIServers()[(string)config["OmfDataArchiveName"]]; if (omfPIServer.ConnectionInfo == null) { omfPIServer.Connect(); } var typeInAF = omfDatabase.ElementTemplates[typeId]; Assert.True(typeInAF != null, $"The OMF Type [{typeId}] should exist as an ElementTemplate in [{omfDatabase}] on [{omfAFServer}]."); var pointFound = PIPoint.TryFindPIPoint(omfPIServer, $"{containerId}.Pressure", out var piPointPressure); Assert.True(pointFound, $"PI Point [{containerId}.Pressure] not found in [{omfPIServer.Name}]."); Assert.True(piPointPressure.CurrentValue().ValueAsSingle() == 11.5, $"Value for PI Point [{containerId}.Pressure] incorrect. Expected: [11.5], Actual: [{piPointPressure.CurrentValue().ValueAsSingle()}]."); pointFound = PIPoint.TryFindPIPoint(omfPIServer, $"{containerId}.Temperature", out var piPointTemperature); Assert.True(pointFound, $"PI Point [{containerId}.Temperature] not found in [{omfPIServer.Name}]."); Assert.True(piPointTemperature.CurrentValue().ValueAsInt32() == 101, $"Value for PI Point [{containerId}.Temperature] incorrect. Expected: [101], Actual: [{piPointTemperature.CurrentValue().ValueAsInt32()}]."); // Delete the data Output.WriteLine("Delete OMF data."); Fixture.Client.Headers["action"] = "delete"; var deleteDataResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonData)); Assert.True(deleteDataResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Delete the container Fixture.Client.Headers["messagetype"] = "container"; var deleteContainerResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonContainer)); Assert.True(deleteContainerResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Delete the type Fixture.Client.Headers["messagetype"] = "type"; var deleteTypeResponse = JObject.Parse(Fixture.Client.UploadString(omfUrl, "POST", jsonType)); Assert.True(deleteTypeResponse["OperationId"] != null, "OperationId not returned in OMF response."); // Verify objects were deleted. Remove objects that were not deleted before Assert to ensure cleanup omfPIPoints = PIPoint.FindPIPoints(omfPIServer, $"{containerId}*", null, null).ToList(); omfDatabase.ElementTemplates.Refresh(); omfTypeAsTemplate = omfDatabase.ElementTemplates[typeId]; Assert.True(omfPIPoints.Count == 0, "PIPoints were not deleted by the DELETE CONTAINER request to OMF."); Assert.True(omfTypeAsTemplate == null, $"The OMF Type [{typeId}] was not deleted by the DELETE TYPE request to OMF."); } catch (WebException ex) { var httpResponse = (HttpWebResponse)ex.Response; var statusCode = string.Empty; if (httpResponse.StatusCode != HttpStatusCode.OK && httpResponse.StatusCode != HttpStatusCode.Accepted && httpResponse.StatusCode != HttpStatusCode.NoContent) { statusCode = $"{httpResponse.StatusCode}: {httpResponse.StatusDescription}"; } // For troubleshooting error response codes returned by PI Web API using (var reader = new StreamReader(ex.Response.GetResponseStream())) { var response = JObject.Parse(reader.ReadToEnd())["Messages"]?[0]["Events"]?[0]["Message"]?.ToString(); if (!string.IsNullOrEmpty(response)) { Assert.True(false, $"Error returned from OMF: {response}. {statusCode}."); } else { throw; } } } finally { // Clean up any existing OMF objects if not deleted by OMF if (omfPIServer != null) { if (omfPIServer.ConnectionInfo == null) { omfPIServer.Connect(); } omfPIPoints = PIPoint.FindPIPoints(omfPIServer, $"{containerId}*", null, null).ToList(); bool pointsDeleted = omfPIPoints.Count == 0; if (!pointsDeleted) { omfPIServer.DeletePIPoints(omfPIPoints.Select(p => p.Name).ToList()); } } if (omfAFServer != null && omfDatabase != null) { omfTypeAsTemplate = omfDatabase.ElementTemplates[typeId]; bool typeDeleted = omfTypeAsTemplate == null; if (!typeDeleted) { AFElementTemplate.DeleteElementTemplates(omfAFServer, new List <Guid> { omfTypeAsTemplate.ID }); } } } }
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(); }
private void TryCreateFitnessElement(string userName, string elementName, AFElementTemplate template) { _afAccess.TryCreateFitnessElement(userName, elementName, template); }
/// <summary> /// Create the AF Database, Element Templates, and Attribute Templates. /// </summary> private void CreateAFTemplates() { // Check if PI System exists. PISystem targetPISystem = new PISystems()[_conf.AFServerName]; if (targetPISystem == null) { Console.WriteLine("AF server does not exist"); Environment.Exit(0); } // Check if AF Database exists. If so, delete it and recreate it to start anew. _afContext = new AFContext(); _afContext.Database = targetPISystem.Databases[_conf.AFDatabaseName]; if (_afContext.Database != null) { Console.Write(string.Format(@"AF Database {0} already exists. " + @"Press Y to remove and recreate the database, " + @"N to quit the program and specify a different database name : ", _conf.AFDatabaseName)); while (true) { ConsoleKeyInfo result = Console.ReadKey(); Console.WriteLine("\n"); if ((result.KeyChar == 'Y') || (result.KeyChar == 'y')) { targetPISystem.Databases.Remove(_afContext.Database); break; } else if ((result.KeyChar == 'N') || (result.KeyChar == 'n')) { Environment.Exit(0); } Console.Write("Invalid input, try again (Y/N) : "); } } _afContext.Database = targetPISystem.Databases.Add(_conf.AFDatabaseName); // Create the Enumeration Set. AFEnumerationSet modes = _afContext.Database.EnumerationSets.Add("Modes"); modes.Add("Manual", 0); modes.Add("Auto", 1); modes.Add("Cascade", 2); modes.Add("Program", 3); modes.Add("Prog-Auto", 4); // Create element templates for SubTree and Branch elements. AFElementTemplate subTree_ElemTmp = _afContext.Database.ElementTemplates.Add(Constants.SUBTREE); AFElementTemplate branch_ElemTmp = _afContext.Database.ElementTemplates.Add(Constants.BRANCH); AFAttributeTemplate subtree_Rollup_AttrTmp = subTree_ElemTmp.AttributeTemplates.Add(Constants.ROLLUP_SUM_ATTRIBUTE); AFAttributeTemplate branch_Rollup_AttrTmp = branch_ElemTmp.AttributeTemplates.Add(Constants.ROLLUP_SUM_ATTRIBUTE); AFAttributeTemplate threshold_AttrTmp = branch_ElemTmp.AttributeTemplates.Add(Constants.THRESHOLD_ATTRIBUTE); subtree_Rollup_AttrTmp.Type = typeof(float); branch_Rollup_AttrTmp.Type = typeof(float); threshold_AttrTmp.Type = typeof(int); AFPlugIn _piPointDR = AFDataReference.GetPIPointDataReference(targetPISystem); subtree_Rollup_AttrTmp.DataReferencePlugIn = _piPointDR; branch_Rollup_AttrTmp.DataReferencePlugIn = _piPointDR; string serverPath = @"\\" + _conf.PIServerName + @"\"; subtree_Rollup_AttrTmp.ConfigString = serverPath + @"HighAsset_%Element%_Total"; branch_Rollup_AttrTmp.ConfigString = serverPath + @"HighAsset_%Element%_Total"; threshold_AttrTmp.SetValue(_conf.ThresholdValue, null); // Create element templates for Leaf elements. _afContext.BaseLeafTemplate = _afContext.Database.ElementTemplates.Add(Constants.LEAF); _afContext.SinusoidLeafTemplate = _afContext.Database.ElementTemplates.Add(Constants.LEAF_SIN); _afContext.RandomLeafTemplate = _afContext.Database.ElementTemplates.Add(Constants.LEAF_RAND); _afContext.SinusoidLeafTemplate.BaseTemplate = _afContext.BaseLeafTemplate; _afContext.RandomLeafTemplate.BaseTemplate = _afContext.BaseLeafTemplate; // Add attribute templates for base leaf Element Templates. AFAttributeTemplate subtree_AttrTmp = _afContext.BaseLeafTemplate.AttributeTemplates.Add(Constants.SUBTREE); AFAttributeTemplate branch_AttrTmp = _afContext.BaseLeafTemplate.AttributeTemplates.Add(Constants.BRANCH); AFAttributeTemplate ID_AttrTmp = _afContext.BaseLeafTemplate.AttributeTemplates.Add(Constants.LEAF_ID); AFAttributeTemplate value_AttrTmp = _afContext.BaseLeafTemplate.AttributeTemplates.Add("Value"); AFAttributeTemplate mode_AttrTmp = _afContext.BaseLeafTemplate.AttributeTemplates.Add("Mode"); subtree_AttrTmp.Type = typeof(string); branch_AttrTmp.Type = typeof(string); ID_AttrTmp.Type = typeof(string); value_AttrTmp.Type = typeof(float); value_AttrTmp.DataReferencePlugIn = _piPointDR; mode_AttrTmp.DataReferencePlugIn = _piPointDR; mode_AttrTmp.TypeQualifier = modes; mode_AttrTmp.SetValue(modes["Manual"], null); mode_AttrTmp.ConfigString = serverPath + @"HighAsset_%Element%_Mode; ptclassname=classic; pointtype=digital; digitalset=modes; pointsource=R; location1=0; location4=3; location5=1"; // Add attribute templates for sinusoid leaf Element Templates. AFAttributeTemplate value_sinusoid_AttrTmp = _afContext.SinusoidLeafTemplate.AttributeTemplates.Add("Value"); value_sinusoid_AttrTmp.Type = typeof(double); value_sinusoid_AttrTmp.DataReferencePlugIn = _piPointDR; value_sinusoid_AttrTmp.ConfigString = serverPath + @"HighAsset_%Element%_Sinusoid; ptclassname=classic; pointtype=float32; pointsource=R; location1=0; location4=3; location5=0"; // Add attribute templates for random leaf Element Templates. AFAttributeTemplate value_random_AttrTmp = _afContext.RandomLeafTemplate.AttributeTemplates.Add("Value"); value_random_AttrTmp.Type = typeof(double); value_random_AttrTmp.DataReferencePlugIn = _piPointDR; value_random_AttrTmp.ConfigString = serverPath + @"HighAsset_%Element%_Random; ptclassname=classic; pointtype=float32; pointsource=R; location1=0; location4=3; location5=1"; // Create container element under which all leaf elements will be stored. _afContext.Database.Elements.Add("LeafElements"); // Do a bulk checkin of all changes made so far. _afContext.Database.CheckIn(AFCheckedOutMode.ObjectsCheckedOutThisThread); }
public void Run() { PISystems piSystems = new PISystems(); PISystem piSystem = piSystems["<AFSERVER>"]; AFDatabase afDatabase = piSystem.Databases["NuGreen"]; AFElementTemplate boilerTemplate = afDatabase.ElementTemplates["Boiler"]; const int pageSize = 1000; int startIndex = 0; int totalCount; do { // Find a collection of elements instantiated from the Boiler tempplate. // Only the Elements' header information (Name, Description, Template, Type, etc.) // are loaded from the AF Server by this call. AFNamedCollection <AFElement> elements = AFElement.FindElements( database: afDatabase, searchRoot: null, query: "Boiler", field: AFSearchField.Template, searchFullHierarchy: true, sortField: AFSortField.Name, sortOrder: AFSortOrder.Ascending, startIndex: startIndex, maxCount: pageSize, totalCount: out totalCount); if (elements == null) { break; } // Partially load the element by retrieving information only for the Water Flow attribute. AFElement.LoadAttributes(elements, new[] { boilerTemplate.AttributeTemplates["Water Flow"] }); Console.WriteLine("Found {0} Elements.", elements.Count); AFAttributeList attrList = new AFAttributeList(); // Because we are retrieving the Water Flow attribute which was previously loaded, // no additional server calls are made. // If LoadAttributes had not been called previously, then a server call would have been made for each element // in the loop below. foreach (AFElement item in elements) { attrList.Add(item.Attributes["Water Flow"]); } AFValues values = attrList.GetValue(); Console.WriteLine(" Water Flow values"); foreach (AFValue val in values) { Console.WriteLine(" Element: {0}, Timestamp: {1}, Value: {2}", val.Attribute.Element, val.Timestamp, val.Value.ToString()); } startIndex += pageSize; } while (startIndex < totalCount); }
private static string GetElementName(this AFElementTemplate template, int id) => $"{template.Name}{id}";
private static IEnumerable <AFAttributeTemplate> GetAllAttributeTemplatesAndChildren(this AFElementTemplate elementTemplate) { return(GetAllAttributeTemplatesAndChildren(elementTemplate.GetAllAttributeTemplates())); }
/// <summary> /// Returns a flattened <see cref="IEnumerable<AFAttributeTemplate>"/> collection of all generations of all attribute templates belonging to the specified <see cref="AFElementTemplate"/>. /// </summary> /// <param name="template"></param> /// <returns></returns> public static IEnumerable <AFAttributeTemplate> GetAllAttributeTemplateGenerations(this AFElementTemplate template) => GetAllAttributeTemplateGenerations(template.AttributeTemplates);
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); } }