AnsweredAssumed Answered

How to make this code more simple and smart?

Question asked by ZackZH on Jul 16, 2019
Latest reply on Jul 18, 2019 by ZackZH

I am doing the program development(utilizing AF SDK) about PI and R integration.

While I need to get data from PI DA. Here I mean not only one PI Point, but multiple PI Points. Because I need to do data analysis at the end.

I define the period of output data(recorded) and call them. Look at my code, every process must be run 3 times if I want to get 3 PI Points.  If more PI Points I need to call, more repeated lines must be added. It looks stupid.

I have not too much experience about programming in C#. I think it may use loops or other functions to improve this program. Or any other methods. Who can help me ? Thank you!



The source code:


using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OSIsoft.AF;
using OSIsoft.AF.PI;
using OSIsoft.AF.Time;
using OSIsoft.AF.Asset;
using RDotNet;

namespace FinalProgram
    class Program
        static void Main()
            PISystems myPISystems = new PISystems();
            PISystem myPISystem = myPISystems.DefaultPISystem;
            PIServer myPIServer = PIServer.FindPIServer(myPISystem, "piserver");

            PIPoint myPIPoint = PIPoint.FindPIPoint(myPIServer, "tem");
            PIPoint myPIPoint1 = PIPoint.FindPIPoint(myPIServer, "hum");
            PIPoint myPIPoint2 = PIPoint.FindPIPoint(myPIServer, "wisp");

            AFValue Snapshot = myPIPoint.CurrentValue();
            Console.WriteLine("Snapshot from tem: " + Snapshot.Value + "\t" + Snapshot.Timestamp.LocalTime);

            AFValue Snapshot1 = myPIPoint1.CurrentValue();
            Console.WriteLine("Snapshot from hum: " + Snapshot1.Value + "\t" + Snapshot.Timestamp.LocalTime);

            AFValue Snapshot2 = myPIPoint2.CurrentValue();
            Console.WriteLine("Snapshot from wisp: " + Snapshot2.Value + "\t" + Snapshot.Timestamp.LocalTime);

            AFTimeRange range = new AFTimeRange("*-1y", "*");
            AFTimeRange range1 = new AFTimeRange("*-1y", "*");
            AFTimeRange range2 = new AFTimeRange("*-1y", "*");

            AFValues Recorded = myPIPoint.RecordedValues(range, OSIsoft.AF.Data.AFBoundaryType.Inside, "", false);
            AFValues Recorded1 = myPIPoint1.RecordedValues(range1, OSIsoft.AF.Data.AFBoundaryType.Inside, "", false);
            AFValues Recorded2 = myPIPoint2.RecordedValues(range2, OSIsoft.AF.Data.AFBoundaryType.Inside, "", false);

            Console.WriteLine("Showing Recorded data from tem,hum,wisp...");

            var strList = new List<string>();
            var strList1 = new List<string>();
            var strList2 = new List<string>();

            var number = new List<string>();
            var number1 = new List<string>();
            var number2 = new List<string>();

            Decimal numberD = 0;

            foreach (AFValue val in Recorded)
                Console.WriteLine("{0,20}{1,30}", val.Value, val.Timestamp.LocalTime);
                bool canConvert = Decimal.TryParse(val.Value.ToString(), out numberD);


                if (canConvert == true)

                    Console.WriteLine("This is not a valid decimal");


            Decimal numberD1 = 0;

            foreach (AFValue val1 in Recorded1)
                Console.WriteLine("{0,20}{1,30}", val1.Value, val1.Timestamp.LocalTime);
                bool canConvert = Decimal.TryParse(val1.Value.ToString(), out numberD1);


                if (canConvert == true)

                    Console.WriteLine("This is not a valid decimal");


            Decimal numberD2 = 0;

            foreach (AFValue val2 in Recorded2)
                Console.WriteLine("{0,20}{1,30}", val2.Value, val2.Timestamp.LocalTime);
                bool canConvert = Decimal.TryParse(val2.Value.ToString(), out numberD2);


                if (canConvert == true)

                    Console.WriteLine("This is not a valid decimal");


            var envPath = Environment.GetEnvironmentVariable("PATH");
            envPath += Path.PathSeparator + @"C:\Program Files\R\R-3.5.1\bin\x64";
            Environment.SetEnvironmentVariable("PATH", envPath);

            using (var r = REngine.GetInstance("R"))

                var number_vector = r.CreateCharacterVector(number);
                var number1_vector = r.CreateCharacterVector(number1);
                var number2_vector = r.CreateCharacterVector(number2);

                r.SetSymbol("number", number_vector);
                r.SetSymbol("number1", number1_vector);
                r.SetSymbol("number2", number2_vector);

                var numberA = r.GetSymbol("number").AsNumeric();
                var numberB = r.GetSymbol("number1").AsNumeric();
                var numberC = r.GetSymbol("number2").AsNumeric();

                r.SetSymbol("number", numberA);
                r.SetSymbol("number1", numberB);
                r.SetSymbol("number2", numberC);

                r.Evaluate("bodyData <- data.frame(number,number1,number2)");


                r.Evaluate("reg <- summary(lm(number ~ number + number1 + number2, data = bodyData))");



        private static AFTimeSpan AFTimeSpan(int hour)
            throw new NotImplementedException();