6 Replies Latest reply on Jan 20, 2016 9:52 AM by Suganya_Ganesan

    How to get the attribute value for a list of AF Elements in one go.

    Suganya_Ganesan

      How to get the attribute value for a list of AF Elements in one go.

      I need to fetch a particular attribute value for 1000s of AF Elements.

      Currently, I am using AFSDK function for each element, but it takes more time.

       

      Code Snippet:

      foreach (AFElement objMeter in MeterElements)

      {

            string strEncoder = objMeter.Attributes["Encoder"].GetValue().Value.ToString();

            dictMeterEncoder.Add(objMeter.Name, strEncoder);

      }                    

        • Re: How to get the attribute value for a list of AF Elements in one go.
          Roger Palmen

          Assuming these are PI Points, you should be able to build a PointList collection and retrieve the values in one call. E.g.: PIPointList.RecordedValues Method

          Find an excellent whitepaper here: PI AF SDK guidelines

            • Re: How to get the attribute value for a list of AF Elements in one go.
              Suganya_Ganesan

              Hi Roger,

               

              Thanks for the reply.

              But the data reference is not a PI Point.

                • Re: How to get the attribute value for a list of AF Elements in one go.
                  redabakr

                  Hi Suganya,

                  You could use AfAttributeList :

                  add  extension method for AF Attribute to get string value from dic

                   static public string GetAttrValueString(this AFAttribute afAttr, Dictionary<Guid, object> DicValues)
                          {
                              try
                              {
                                  return DicValues[afAttr.ID].ToString();
                              }
                              catch
                              {
                                  return "";
                              }
                          }
                  

                   

                   

                  AFAttributeList AttrList = new AFAttributeList();
                  foreach (AFElement objMeter in MeterElements)
                  {
                     AttrList.Add(objMeter.Attributes["Encoder"]);
                  }
                  AFValues afValues = AttrList.GetValue();
                  Dictionary<Guid, object> AtrrValuestDic = new Dictionary<Guid, object>();
                  AtrrValuestDic = afValues.Distinct().ToDictionary(pair => pair.Attribute.ID, pair => pair.IsGood?pair.Value:"");          
                  foreach (AFElement objMeter in MeterElements)
                  {
                     string strEncoder = objMeter.Attributes["Encoder"].GetAttrValueString(AtrrValuestDic);
                     dictMeterEncoder.Add(objMeter.Name, strEncoder);
                  }
                  
                  
                  

                   

                  Kind regards,

                  1 of 1 people found this helpful
                  • Re: How to get the attribute value for a list of AF Elements in one go.
                    bshang

                    What kind of data reference is it? If it is a custom data reference, it likely does not implement a bulk call, in which case the static AFListData methods will just resort back to the single attribute calls.

                • Re: How to get the attribute value for a list of AF Elements in one go.
                  Rick Davin

                  You could do a bulk call but it would be bulk call on an AFAttributeList, not a list of elements.

                   

                  Modifying your original code ever so slightly:

                   

                  private void Example1(IDictionary<string, string> dictMeterEncoder, IList<AFElement> meterElements)
                  {
                      foreach (AFElement objMeter in meterElements)
                      {
                          string strEncoder = objMeter.Attributes["Encoder"].GetValue().Value.ToString();
                          dictMeterEncoder.Add(objMeter.Name, strEncoder);
                      }
                  }
                  

                   

                  Could get a performance benefit from a bulk call like:

                   

                  private void Example2(IDictionary<string, string> dictMeterEncoder, IList<AFElement> meterElements)
                  {
                      var attributes = new AFAttributeList();
                  
                  
                      foreach (AFElement objMeter in meterElements)
                      {
                          var attribute = objMeter.Attributes["Encoder"];
                          if (attribute != null) attributes.Add(attribute);
                      }
                  
                  
                      // Issue one bulk call for all current values.
                      var bulkValues = attributes.GetValue();
                  
                  
                      foreach (var pv in bulkValues)
                      {
                          var key = pv.Attribute.Element.Name;
                          var value = pv.Value.ToString();
                          dictMeterEncoder.Add(key, value);
                      }
                  }
                  

                   

                  And there's more to decide.  For example, if you are using element templates, then you could take advantage of the AFElement.LoadAttributes method.

                  2 of 2 people found this helpful
                    • Re: How to get the attribute value for a list of AF Elements in one go.
                      Suganya_Ganesan

                      Thank you everyone for the reply.

                      It works with AFAttributeList !!

                       

                      In the same way, I have a list of Elements name, can I get all the AFElements in one go?

                       

                      Code Snippet:

                      List<string> objMeterList=new List<string> ();

                      foreach (string strMeterElement in objMeterList)

                      {

                                         var MeterElement = AFElement.FindElements(obj_AFDatabase, null, strMeterElement, AFSearchField.Name, true, AFSortField.Name, AFSortOrder.Ascending, 100);

                                          if (MeterElement.Count > 0)

                                              MeterElements.Add(MeterElement[0]);

                      }