2 Replies Latest reply on Feb 6, 2015 12:29 AM by bshang

    Need to interface with MatLab

    mdspath

      Hello:

      We built a DLL that can

      *connect with our PI server

      *establish collection of keys (PIPoint) and values (AFValues)

      *create a PiPointList

      * calls the method InterpolatedValues of the PIPointList class


      I need to have a MatLab function read that data that is returned IEnumerable<AFValues>.


      An 2D array of doubles for now would be good. Conceptually, the AFValues struct needs to be broken down into this return array.


      Any feedback is welcomed.


      code example:

      //*********************************************************************

              public IEnumerable<AFValues> PIFunction()

              {

                   //Connect to a PI Server

                  PIServers pIServers = new PIServers();

                 

                  foreach (var server in pIServers)

                  {

                      Console.WriteLine("Server: {0}", server.Name);

                  }

                 

                  PIServer piServ = pIServers.DefaultPIServer;

                //  Console.WriteLine("Default Server: {0}", piServ.Name);

                 

                  piServ.Connect();

               

                  PIPointList ptList = new PIPointList();

                 

                  AFTimeRange timeRange = new AFTimeRange("04-Feb-2015 13:09:40", "05-Feb-2015 13:09:40");

                 

                  AFTimeSpan timeInterval = new AFTimeSpan(0,0,0,0,0,5,0);

       

                   PIPagingConfiguration config = new PIPagingConfiguration(PIPageType.EventCount, 100);


                  // establish collection of keys (PIPoint) and values (AFValues)

                  Dictionary<PIPoint, AFValues> resultsMap = new Dictionary<PIPoint, AFValues>();

                  string[] tagName = { "arDateTime", "vessel1.dSimCO2", "vessel1.AgitatorRPM", "BA:Active.1" };

       

                  foreach (string tag in tagName)

                  {

                      ptList.Add(PIPoint.FindPIPoint(piServ, tag));

                  }

       

                  IEnumerable<AFValues> results = ptList.InterpolatedValues(timeRange, timeInterval, null, true, config);

                  int iNumResult = 0;

                  foreach (AFValues result in results)

                  {

                      resultsMap[result.PIPoint] = result;

                      iNumResult = result.Count();

                  }

                  Console.WriteLine("TimeStamp \t\t{0} \t{1} \t{2} \t{3}", tagName);

                  for (int i = 0; i < iNumResult-1; i++)

                  {

                      Console.WriteLine("{0} \t{1} \t{2} \t{3} \t{4}",

                          resultsMap[ptList[0]][i].Timestamp, resultsMap[ptList[0]][i].Value, resultsMap[ptList[1]][i].Value, resultsMap[ptList[2]][i].Value, resultsMap[ptList[3]][i].Value);

                  }

       

                  Console.WriteLine("\nFinished. press Enter.");

                  //Console.ReadLine(); 

       

                 piServ.Disconnect();

                 

                  return results;

              }

       

      thanks.

        • Re: Need to interface with MatLab
          dng

          Hi Mike,

           

          Since you have already built a DLL to retrieve the AF values, perhaps you can look into writing a wrapper to convert the PI AF SDK objects into simpler arrays before handing the data to MATLAB. While you can deal with .NET objects in MATLAB, there can be some performance overhead. Have you looked at White Paper - Using PI Data with MATLAB? You can write a similar helper function as shown in P.5-6.

          • Re: Need to interface with MatLab
            bshang

            Hi Mike,

             

            I think the suggestion here may be worthwhile. The issue discussed was that GetEnumerator() on the IEnumerable<AFValues> object was not exposed in MATLAB, and hence, we couldn't iterate via a for or while loop. The workaround is to convert the IEnumerable<AFValues> to an array AFValues[] via the ToArray() extension method. Then you can loop through the array and perform operations on the AFValues. A psuedo-MATLAB code might look like...

             

            NET.addAssembly('System.Core');   %# contains 'System.Linq' namespace
            arr
            = NET.invokeGenericMethod('System.Linq.Enumerable', 'ToArray', ...
              
            {'OSIsoft.AF.Asset.AFValues'}, results);

            %# loop through results
            for i=1:arr.Length
              %perform operations on AFValues. Note we might want to convert these to arrays (or construct a 2D array) for performance gains. See the last link (White Paper) in the post for a .NET helper function on how to do this.

            end

             

            I don't have access to a MATLAB installation currently so the above code snippet might be a bit buggy..

             

            You can work somewhat directly with .NET and AF SDK methods/types using MATLAB. These resources below may be helpful

            Call .NET libraries in MATLAB

            Accessing AF via Matlab

            White Paper - Using PI Data with MATLAB

             

             

            EDIT: Daphne beat me to it but another approach is to convert to array within the .NET class.