15 Replies Latest reply on Apr 5, 2018 6:29 PM by exelejames

    I want to write an app that writes values to PI history

    SMBLACK

      I want to write an app that writes values to PI history....value/quality and date/time

        • Re: I want to write an app that writes values to PI history
          rborges

          That's easy! Could you please provide some more context so I can point you to resources more appropriate to your goals? What language? What platform? Will it be a service, web or windows form?

            • Re: I want to write an app that writes values to PI history
              SMBLACK

              We have a product from Exele (OPCCALC) that allows me to write Visual Basic (VBNET simple) that only reads/writes from

              using OPC with many different partners including PI.

               

              I can write values in archive to PI using the manual PI SMT desktop, but wondered if there was a subroutine/function

              available for me to write back to PI (I already write back current values/qualities).

               

              I can read historic values (averages from PI using HDA), but want to write single values to PI history (like the SMT tool) ,

              with a  specified time attached in the past.

                • Re: I want to write an app that writes values to PI history
                  rborges

                  Oh, I see!

                   

                  I will provide you a C# snippets, but is pretty much the same thing in VB.NET.

                   

                  // First we define our imports
                  using OSIsoft.AF;
                  using OSIsoft.AF.EventFrame;
                  using OSIsoft.AF.PI;
                  using OSIsoft.AF.Search;
                  using OSIsoft.AF.Time;
                  
                  // Now we get the servers you have on your KST
                  PIServers piServers = new PIServers();
                  // Then you select the one you want
                  PIServer piServer = piServers["MyPIServer"];
                  // Now we find that tag we want to write data to
                  PIPoint point = PIPoint.FindPIPoint(piServer, "tag_1");
                  // Now we create the timestamp we want for our new data
                  AFTime time = new AFTime(DateTime.now);
                  // And then a value
                  AFValue afValueFloat = new AFValue(3.14, time);
                  // Now we associate the AFValue to a PI Point so we know where to write to.
                  afValueFloat.PIPoint = point;
                  
                  // Now we add this value to a list of values
                  // Here we have a single tag, but this is usefull when you
                  // want to update several tags
                  IList<AFValue> valuesToWrite = new List<AFValue>();
                  valuesToWrite.Add(afValueFloat);
                  
                  // Finally we perform a bulk write.
                  // Use a single local call to PI Buffer Subsystem if possible.
                  // Otherwise, make a single call to the PI Data Archive.
                  // We use no compression just so we can check all the values are written.
                  piServer.UpdateValues(valuesToWrite, AFUpdateOption.InsertNoCompression, AFBufferOption.BufferIfPossible);
                  

                   

                  Is this what you are looking for?

                    • Re: I want to write an app that writes values to PI history
                      Rick Davin

                      Hi Stephen,

                       

                      There are many ways to achieve what you want to do.  Rafael Borges  has shown you just one way using the PIServer.UpdateValues method which allows you to update many values for many PIPoints in one bulk call.  The key to it, as shown in line 19, was associating the PIPoint object to the AFValue's PIPoint property.

                       

                      The PIPoint object allows you to update one value for one PIPoint with the PIPoint.UpdateValue method.  Or you may update many values for the one PIPoint using the PIPoint.UpdateValues method.  The difference here compared to what Rafael demonstrated is that you do not need to set the AFValue's PIPoint property.  For example, given a PIPoint object named "point", this works fine:

                       

                      point.UpdateValue(afValueFloat, AFUpdateOption.Replace)

                      • Re: I want to write an app that writes values to PI history
                        SMBLACK

                        But what if these methods are not available on my windows systems:

                         

                        using OSIsoft.AF;

                         

                        using OSIsoft.AF.EventFrame;

                         

                        using OSIsoft.AF.PI;

                         

                        using OSIsoft.AF.Search;

                         

                        using OSIsoft.AF.Time;

                          • Re: I want to write an app that writes values to PI history
                            Rick Davin

                            In VB.NET the command is called Imports, as in:

                             

                            Imports OSIsoft.AF

                            etc.

                              • Re: I want to write an app that writes values to PI history
                                SMBLACK

                                These systems are not internet connected

                                  • Re: I want to write an app that writes values to PI history
                                    exelejames

                                    Hi Stephen,

                                     

                                    I work for Exele and am happy to help in whatever way I can here with any OPCcalc related questions.

                                     

                                    OPCcalc supports writing values in history through HDA natively, so it is possible to leverage OPCcalc to do that.

                                     

                                    That said, I'm not totally sure if that's what you're asking here. Are you trying to use OPCcalc to write values to PI history, or looking to write PI history independently of OPCcalc?

                                     

                                    As always, happy to help as I can. Feel free to email us at support@exele.com if you have any product-specific questions too

                                      • Re: I want to write an app that writes values to PI history
                                        SMBLACK

                                        Both, but I did not know I could use HAD to write 1-minute values back into PI 1-minute history?

                                        Here is an APP currently reading from HAD and writing what it gets to a local dcs:

                                         

                                        OPCNODE=DPRCPSAPP03

                                        READ_DEVICE

                                        {INIT

                                        Dim value(34) As Object

                                        Dim qualityx(34) As Int32

                                        Dim tagname(34) As String

                                        Dim time(34) As Date

                                        Dim writeerr(34) As Int32

                                        Dim writeerrstr(34) As String

                                        Dim statusx As int32

                                        Dim statusmsg As String

                                        Dim i As Integer

                                        Dim quality,status As Integer

                                         

                                        If $FIRSTTIME Then

                                        xlSetDAGroupActiveFlag("DPRCPSAPP03",False)

                                        xlSetDAGroupActiveFlag("DSDPKPIPCNCOLL",False)

                                        End If

                                         

                                         

                                        FileOpen(1,"C:\io_files\HOURAVGBADS1.txt",openmode.append)

                                        PrintLine(1,$CURTIME,"CPSAVG1 ",$TAG(F10346CCUAVG/PV_IN.CV),$TAG(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\CCU.FI10346.PV))

                                         

                                         

                                        value(0)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\CCU.FI10346.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(1)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\CCU.FI10365.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(2)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\SW1.FC19763.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(3)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\FC25400_ARO),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(4)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\FI115_ARO),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(5)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\FI1575_PAU),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(6)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\FI23380_ARO),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(7)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\SR5.FI53108.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(8)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\FI7092_IRU),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(9)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\FIO218_OP2),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(10)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\FIO323_OP2),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(11)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\DU2.F602.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(12)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F1571COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(13)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F1671COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(14)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F1771COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(15)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F1871COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(16)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F1971COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(17)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F2071COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(18)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F2171COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(19)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F2271COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(20)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F2371COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(21)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F2471COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(22)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\CR3.FI34502.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(23)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\HP1.FI52202.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(24)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F712COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(25)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\F762COM_OP3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(26)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\FI9260C_PA3),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(27)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\ESO.FI93652.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(28)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\SR8.FI94652.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(29)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\PL2.FR_527.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(30)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\UCC.ACHMUS.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(31)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\UCC.AOP2US.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(32)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\UCC.ACOMPR.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(33)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\UCC.ACPSUS.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        value(34)=xlTagTimeAverage($NAMEX(||DSDPKPIPCNCOLL||
                                        DSDPKPIPCNCOLL\UCC.FI44351.PV),$CURTIME.AddHours(-1),$CURTIME, _

                                                      quality,status,statusmsg)

                                        tagname( 0 )="F10346CCUAVG/PV_IN.CV"

                                        tagname( 1 )="F10365CCUAVG/PV_IN.CV"

                                        tagname( 2 )="FC19763SW1AVG/PV_IN.CV"

                                        tagname( 3 )="FC25400ACUAVG/PV_IN.CV"

                                        tagname( 4 )="FI115ACUAVG/PV_IN.CV"

                                        tagname( 5 )="FI1575PAUAVG/PV_IN.CV"

                                        tagname( 6 )="FI23380ACUAVG/PV_IN.CV"

                                        tagname( 7 )="FI53108SR56AVG/PV_IN.CV"

                                        tagname( 8 )="FI7092IRUAVG/PV_IN.CV"

                                        tagname( 9 )="FIO218OP2AVG/PV_IN.CV"

                                        tagname( 10 )="FIO323OP2AVG/PV_IN.CV"

                                        tagname( 11 )="F602DU2AVG/PV_IN.CV"

                                        tagname( 12 )="FI1571OP3AVG/PV_IN.CV"

                                        tagname( 13 )="FI1671OP3AVG/PV_IN.CV"

                                        tagname( 14 )="FI1771OP3AVG/PV_IN.CV"

                                        tagname( 15 )="FI1871OP3AVG/PV_IN.CV"

                                        tagname( 16 )="FI1971OP3AVG/PV_IN.CV"

                                        tagname( 17 )="FI2071OP3AVG/PV_IN.CV"

                                        tagname( 18 )="FI2171OP3AVG/PV_IN.CV"

                                        tagname( 19 )="FI2271OP3AVG/PV_IN.CV"

                                        tagname( 20 )="FI2371OP3AVG/PV_IN.CV"

                                        tagname( 21 )="FI2471OP3AVG/PV_IN.CV"

                                        tagname( 22 )="FI34502CR3AVG/PV_IN.CV"

                                        tagname( 23 )="FI52202HP1AVG/PV_IN.CV"

                                        tagname( 24 )="FI712OP3AVG/PV_IN.CV"

                                        tagname( 25 )="FI762OP3AVG/PV_IN.CV"

                                        tagname( 26 )="FI9260PA3AVG/PV_IN.CV"

                                        tagname( 27 )="FI93652SR67AVG/PV_IN.CV"

                                        tagname( 28 )="FI94652SR8AVG/PV_IN.CV"

                                        tagname( 29 )="FR527PLAT2AVG/PV_IN.CV"

                                        tagname( 30 )="ACHMUSAVG/PV_IN.CV"

                                        tagname( 31 )="AOP2USAVG/PV_IN.CV"

                                        tagname( 32 )="ACOMPRAVG/PV_IN.CV"

                                        tagname( 33 )="ACPSUSAVG/PV_IN.CV"

                                        tagname( 34 )="FI44351AVG/PV_IN.CV"

                                         

                                        For i = 0 To 34

                                          time(i)=$CURTIME

                                          qualityx(i)=qualGOOD

                                        Next i

                                         

                                        status=0

                                        Call xlSendTagValsCurrent(tagname,value,time,qualityx,writeerr, _

                                                                                         writeerrstr,statusx,statusmsg)

                                        If statusx<>0 Then PrintLine(1,"Overall status error = ", statusx)

                                        For i=0 To 34

                                           If writeerr(i)<>0 Then

                                              PrintLine(1,"Error on point = ",tagname(i))

                                              PrintLine(1,"Error msg is = ",writeerrstr(i))

                                           End If

                                        Next i

                                         

                                         

                                        FileClose(1)

                                          • Re: I want to write an app that writes values to PI history
                                            exelejames

                                            In case anyone is curious, or for future arrivals...

                                             

                                            OPCcalc can write data to PI's history through OPC HDA. It requires PI's HDA interface (of course) and HDA set up in OPCcalc's connection properties. Use either method:

                                             

                                            1. Set "$OUTTIME" to the time stamp at which to output values. This will write the value to that time in HDA.
                                            2. Use the "xlSendTagVal" function. It accepts multiple arguments including both the output timestamp as well as the quality to write.

                                             

                                            Qualities can be written via HDA by using the "$SETQUAL" function or, as mentioned above, in the "xlSendTagVal" function.

                                             

                                            OPCcalc also provides the ability to insert custom code, so any other methods that could be discussed here can also be used in what we call our "user functions" section.

                                             

                                            I'll leave writing to PI History via other methods (AFSDK, PI-SDK, etc.) to others for now

                                             

                                            Edict is OPCcalc's sister product geared specifically towards writing data to PI.

                                      • Re: I want to write an app that writes values to PI history
                                        SMBLACK

                                        OK I think I get it…..It will be later today before I can try this

                                        thanks

                                        Steve

                                    • Re: I want to write an app that writes values to PI history
                                      SMBLACK

                                      OK I think I get it…..It will be later today before I can try this

                                      thanks

                                      Steve

                                    • Re: I want to write an app that writes values to PI history
                                      tramachandran

                                      I would also like to point out that writing back data to PI can be done through a workbooks provided with PI Datalink.

                                      Custom coding generally requires resources for development and maintenance. If you are thinking of writing a of one off application for a specific task, it might be easier to leverage an existing product.

                                       

                                      Write data to PI Data Archive or PI AF discusses the use of example workbooks distributed with PI DataLink to write data to PI Data Archive or PI AF with the PIPutVal() and PIPutValX() functions. In the appropriate cells of the PutVal worksheet, enter the time stamp, data item, and value that you want to write, as well as the root path that specifies the server for the entered data items.

                                      (For an example of how you can write Visual Basic for Applications (VBA) code to use these functions, open the Visual Basic editor for the example workbook and examine the PutVal_code module.)

                                       

                                      If you prefer developing a custom application, Rafael Borges & Rick Davin's posts are great to get started.