benji7

Digital States change to numeric values

Discussion created by benji7 on Sep 20, 2012
Latest reply on Sep 21, 2012 by cmanhard

I've noticed an odd behavior when writing data to PI.  The digital states will change to the enumeration set numeric values in the AFValues collection that is written to PI. This only occurs when the AFValue Status is "Good".

 

Below is a demonstration of this behavior.  Example output is included at the bottom of the snippet.

 

AF 2.5.0.4851

 

 

 

using System;
using OSIsoft.AF;
using OSIsoft.AF.Asset;
using OSIsoft.AF.Data;
using OSIsoft.AF.Time;

namespace digitalStateGoodBadAFSDK
{
    class Program
    {
        /// 
        /// Demonstrates how digital states in an AFValues collection will change to numeric values 
        /// when written to the PI Server depending on whether the status is "good" or "bad". 
        /// 
        /// It appears that the "good" digital states are stored as the 
        /// numeric value for the digital state stored in the AFSystemStateCode Enumeration. 
        /// 
        /// 
        static void Main(string[] args)
        {
            PISystems piSystems = new PISystems();
            AFDatabase afDatabase = piSystems["dev"].Databases["test"];
            DateTime now = DateTime.UtcNow;

            // Digital state state AF Value (default of "Bad" for status)
            AFValue afDigitalBad01 = new AFValue(AFValue.CreateSystemStateValue(AFSystemStateCode.NoData, new AFTime("19-sep-2012 15:00")));
            AFValue afDigitalBad02 = new AFValue(AFValue.CreateSystemStateValue(AFSystemStateCode.NoData, new AFTime("19-sep-2012 16:00")));
            AFValue afDigitalBad03 = new AFValue(AFValue.CreateSystemStateValue(AFSystemStateCode.NoData, new AFTime("19-sep-2012 17:00")));

            // Digital state state AF Value (set to "Good" for status)
            AFValue afDigitalGood01 = new AFValue(AFValue.CreateSystemStateValue(AFSystemStateCode.NoData, new AFTime("19-sep-2012 11:00")));
            afDigitalGood01.Status = AFValueStatus.Good;
            AFValue afDigitalGood02 = new AFValue(AFValue.CreateSystemStateValue(AFSystemStateCode.NoData, new AFTime("19-sep-2012 12:00")));
            afDigitalGood02.Status = AFValueStatus.Good;
            AFValue afDigitalGood03 = new AFValue(AFValue.CreateSystemStateValue(AFSystemStateCode.NoData, new AFTime("19-sep-2012 13:00")));
            afDigitalGood03.Status = AFValueStatus.Good;

            AFValues afValuesBad = new AFValues();
            afValuesBad.Add(afDigitalBad01);
            afValuesBad.Add(afDigitalBad02);
            afValuesBad.Add(afDigitalBad03);

            AFValues afValuesGood = new AFValues();
            afValuesGood.Add(afDigitalGood01);
            afValuesGood.Add(afDigitalGood02);
            afValuesGood.Add(afDigitalGood03);

            AFAttribute testBadAttr = afDatabase.Elements["test"].Attributes["testDigitalBad"];
            AFAttribute testGoodAttr = afDatabase.Elements["test"].Attributes["testDigitalGood"];

            Console.WriteLine("afValuesBad  - before Data.UpdatesValues:");
            foreach (var item in afValuesBad)
                Console.WriteLine(item.Timestamp.ToString() + " | " + item.Value.ToString() + " | " + item.Status.ToString());

            Console.WriteLine("afValuesGood - before Data.UpdatesValues:");
            foreach (var item in afValuesGood)
                Console.WriteLine(item.Timestamp.ToString() + " | " + item.Value.ToString() + " | " + item.Status.ToString());

            // write digital values with to PI. IsGood = false 
            testBadAttr.Data.UpdateValues(afValuesBad, AFUpdateOption.Replace);

            // write digital values with to PI. IsGood = true 
            testGoodAttr.Data.UpdateValues(afValuesGood, AFUpdateOption.Replace);

            System.Threading.Thread.Sleep(5000); // wait 5 seconds for archiving

            // get values from archive
            var recordedValuesBad = testBadAttr.Data.RecordedValuesByCount(new AFTime("19-Sep-2012"), 10, true, AFBoundaryType.Inside, null, null, true);
            var recordedValuesGood = testGoodAttr.Data.RecordedValuesByCount(new AFTime("19-Sep-2012"), 10, true, AFBoundaryType.Inside, null, null, true);

            Console.WriteLine("\nafValuesBad  -  after Data.UpdatesValues:");
            foreach (var item in afValuesBad)
                Console.WriteLine(item.Timestamp.ToString() + " | " + item.Value.ToString() + " | " + item.Status.ToString());

            Console.WriteLine("afValuesGood -  after Data.UpdatesValues:");
            foreach (var item in afValuesGood)
                Console.WriteLine(item.Timestamp.ToString() + " | " + item.Value.ToString() + " | " + item.Status.ToString());

            Console.WriteLine("\nrecordedValuesBad (read from PI):");
            foreach (var item in recordedValuesBad)
                Console.WriteLine(item.Timestamp.ToString() + " | " + item.Value.ToString() + " | " + item.Status.ToString());

            Console.WriteLine("recordedValuesGood (read from PI):");
            foreach (var item in recordedValuesGood)
                Console.WriteLine(item.Timestamp.ToString() + " | " + item.Value.ToString() + " | " + item.Status.ToString());

            Console.ReadLine();

            // Expected output: 
            //
            //afValuesBad  - before Data.UpdatesValues:
            //9/19/2012 3:00:00 PM | No Data | Bad
            //9/19/2012 4:00:00 PM | No Data | Bad
            //9/19/2012 5:00:00 PM | No Data | Bad
            //afValuesGood - before Data.UpdatesValues:
            //9/19/2012 11:00:00 AM | No Data | Good
            //9/19/2012 12:00:00 PM | No Data | Good
            //9/19/2012 1:00:00 PM | No Data | Good
            //
            //afValuesBad  -  after Data.UpdatesValues:
            //9/19/2012 3:00:00 PM | No Data | Bad
            //9/19/2012 4:00:00 PM | No Data | Bad
            //9/19/2012 5:00:00 PM | No Data | Bad
            //afValuesGood -  after Data.UpdatesValues:
            //9/19/2012 11:00:00 AM | 248 | Good
            //9/19/2012 12:00:00 PM | 248 | Good
            //9/19/2012 1:00:00 PM | 248 | Good
            //
            //recordedValuesBad (read from PI):
            //9/19/2012 3:00:00 PM | No Data | Bad
            //9/19/2012 4:00:00 PM | No Data | Bad
            //9/19/2012 5:00:00 PM | No Data | Bad
            //recordedValuesGood (read from PI):
            //9/19/2012 11:00:00 AM | 248 | Good
            //9/19/2012 12:00:00 PM | 248 | Good
            //9/19/2012 1:00:00 PM | 248 | Good

        }
    }
}

 

Outcomes