hanyong

Write Value to Multiple Tags or Attributes

Blog Post created by hanyong Employee on Jan 24, 2013

In PI SDK, there are PIData.UpdateValue and PIData.UpdateValues, which writes 1 value or multiple values to a specific tag respectively. However, very often I get questions from customers about how they can write values to multiple tags in a single function call. Something new in AF SDK 2012 are methods that allows us to write data to multiple tags or attributes being implemented. Hence this allows us to write values to multiple tags or attributes more effectively.

 

The 2 methods to do this are:

  • AFListData.UpdateValues (for writing to multiple attributes)
  • PIServer.UpdateValues (for writing to multiple PI tags)

Here’s simple code samples that do this:

 

For AFListData.UpdateValues:

 
public static void WriteValuesToAttributes()
{
    Random rand = new Random();
    PISystems afsdk = new PISystems();
    PISystem afserver = afsdk["Name of AF Server"];
  
    try
    {
        afserver.Connect();
          AFDatabase afdb = afserver.Databases["Name of AF Database"];
          AFElementTemplate template = afdb.ElementTemplates["Name of Element Template"];
          if (template != null && template.InstanceType == typeof(AFElement))
          {
               // find attributes from elements based on the template
               AFAttributeList attrlist = AFAttribute.FindElementAttributes(afdb, null, "", null, template, AFElementType.Any, "Energy - Current", null, TypeCode.Double, true, AFSortField.ID, AFSortOrder.Ascending, 100000);
               AFValues newvalues = new AFValues();
 
               // generate data for all the tags
               foreach (AFAttribute a in attrlist)
               {
                    AFValue newvalue = new AFValue(a, rand.NextDouble() * 100, new AFTime(DateTime.Now));
                    newvalues.Add(newvalue);
               }
                
               // write data using AFListData.UpdateValues
               AFErrors<AFValue> errors = AFListData.UpdateValues(newvalues, AFUpdateOption.Insert);
                
               if (errors != null && errors.HasErrors)
               {
                    Console.WriteLine("\nErrors returned from AFListData.UpdateValues:");
                
                    // Display Value errors
                    if (errors.Errors != null && errors.Errors.Count gt 0)
                    {
                         foreach (var item in errors.Errors)
                         {
                              Console.WriteLine(" AFValue '{0}': {1}", item.Key, item.Value);
                         }
                    }
                
               // Display PI Server error
               if (errors.PIServerErrors != null && errors.PIServerErrors.Count > 0)
               {
                    foreach (var item in errors.PIServerErrors)
                    {
                         Console.WriteLine(" AFValue '{0}': {1}", item.Key, item.Value);
                    }
               }
                
               // Display PI System errors
               if (errors.PISystemErrors != null && errors.PISystemErrors.Count > 0)
               {
                    foreach (var item in errors.PISystemErrors)
                    {
                         Console.WriteLine(" AFValue '{0}': {1}", item.Key, item.Value);
                    }
               }
          }
     }
     catch (Exception ex)
     {
          Console.WriteLine(ex.Message);
     }
}

 

 

For PIServer.UpdateValues:

 
public static void WriteValuesToPIPoint()
{
    Random rand = new Random();
    PIServers pisdk = new PIServers();
    PIServer piserver = pisdk["Name of PI Server"];
 
    try
    {
        piserver.Connect();
 
          // searching for tags based on a tagname filter
          PIPointQuery searchfilter = new PIPointQuery("tag", OSIsoft.AF.Search.AFSearchOperator.Equal, "CAP*");
        List<PIPointQuery> conditions = new List<PIPointQuery>();
        conditions.Add(searchfilter);

        PIPointList ptlist = new PIPointList(PIPoint.FindPIPoints(piserver, conditions, null));
 
        AFValues newvalues = new AFValues();
 
        // generate data for all the tags
        foreach (PIPoint p in ptlist)
        {
            AFValue newvalue = new AFValue(rand.NextDouble() * 100, new AFTime(DateTime.Now));
            newvalue.PIPoint = p;
            newvalues.Add(newvalue);
        }
 
        // write data using AFListData.UpdateValues
        AFErrors<AFValues> errors = piserver.UpdateValues(newvalues, AFUpdateOption.Insert);
 
        if (errors != null && errors.HasErrors)
        {
            Console.WriteLine("\nErrors returned from PIServer.UpdateValues:");
 
            // Display Value errors
            if (errors.Errors != null && errors.Errors.Count > 0)
            {
                foreach (var item in errors.Errors)
                {
                    Console.WriteLine("  AFValue '{0}': {1}", item.Key, item.Value);
                }
            }
 
            // Display PI Server error
            if (errors.PIServerErrors != null && errors.PIServerErrors.Count > 0)
            {
                foreach (var item in errors.PIServerErrors)
                {
                    Console.WriteLine("  AFValue '{0}': {1}", item.Key, item.Value);
                }
            }
 
            // Display PI System errors
            if (errors.PISystemErrors != null && errors.PISystemErrors.Count > 0)
            {
                foreach (var item in errors.PISystemErrors)
                {
                    Console.WriteLine("  AFValue '{0}': {1}", item.Key, item.Value);
                }
            }
 
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

 

 

As you would imagine, if you are writing to AF Attribute, this will only work if the underlying data reference supports it, like PI Point Data Reference. There are also limitations when using this method like no buffering mechanism. No support for writing to a PI Collective (unless you implement it yourself). If these limitations doesn't bother you, these new methods is probably something useful for you.

Outcomes