9 Replies Latest reply on Aug 8, 2016 12:05 PM by Bille

    Change Multisate Symbol VBA

    NoéAlvarado

      Good morning all,

      I have a PB file with 2 pumps animated with multistate symbol (When the pump is running the colour is green and when not the colour changes to red and blinks), But I need change this to as follows:

      Then the pump stops the pump must change to red and blink, but even if the pumps starts again I need to keep showing the blink on red animation until the operator presses a buttom to reset the alarm, then if the pump is running it will show the pump on green again, but if he presses the reset alarm and the pump keeps stopped, then the pump will be on red colour but will stop blinking.

      I know that is only possible with VBA codes, but I´m not used to VBA on PB.

      Please can you help me with this?

      Kind Regards,

      Noé.

        • Re: Change Multisate Symbol VBA
          gregor

          Hello Noé,

           

          I believe what you need is possible with the Multistate Symbol functionality as it is built-in with PI ProcessBook. What you need is a single Digital State Tag which is reflecting the different operation statuses that you like to consider.

          You would optimally create a Digital State Set with the desired states, create the Digital State Tag as calculated tag and assign the previously created Digital State Set.

           

          A Digital State tag in PI is like a Boolean type but with way more different states. CDM158 is a sample Digital State tag that becomes installed during the PI Data Archive installation except the option is explicitly disabled. I am attaching a ProcessBook display for your reference that is based on CDM158 and has a rectangle that shows as follows.

           

          There are different options to write to the calculated Digital State tag. If you have PI Asset Framework implemented, using Asset Analytics is probably a good and future proof option, otherwise PI Performance Equation Scheduler can serve well. PI ACE is another option just mentioned to provide a complete choice of options.

           

           

          StateNoStateColorBlinking
          0ManualRedNo
          1AutoRedYes
          2CascadeYellowNo
          3ProgramGreenYes
          4Prog-AutoGreenNo

           

          Please let us know if you need further assistance e.g. with setting up the calculations for a calculated tag.

            • Re: Change Multisate Symbol VBA
              NoéAlvarado

              Good morning Gregor,

              Thank you for the help, I saw the CDT signal and changes as you commented, the problem is that I don´t want to create points to do this. I will create a lot of signals, so will not be useful do that for every pump, that´s why I tried to do this by VBA.

              Now I´m trying to create a multistate symbol with 3 states on VBA, the problem is the next: I created a multistate symbol with VBA using the “CreateMultistate(TagName As String) As IDualMultistate” option, but the signal that needs to give me the value to evaluate the state is not a PI Tag, is a variable that a I created on the code As Integer (sSet), that´s because this sSet variable depends of a button that the operator need to press on the screen., but then I write “sSet” con the field of the tagname the PB doesn´t recognize de values of the signal and then cannot created the multistate. 

              The idea is make a multistate object of a pump that needs to change to red and blink If the pump stops, this blink and red colour will keep until the operator presses the button “Reset Alarm” on the PB Screen (Sub Resetear_Alarma), if he presses the alarm and the pump is started on that moment, will return to the green colour, if he presses the alarm and the pump still not working the pump need to keep staying on red but with no blinking.

              This is the code that I used:

              Sub Resetear_Alarma()

              Dim R As Boolean

              R = 1

              End Sub

               

              Sub Bombas()

              'Declaración de variables

              Dim oMultistate As MultiState

              Dim oMSState As MSState

              Dim sServer As Server

              Dim sSrv As String

              Dim sTagname As String

              Dim ImpactosCriticos As PIPoint

              Dim TagValue As Variant

              Dim sSet As Integer

              'Seteo tag PI a evaluar

              Set sServer = Servers("PELABPII02")

              sSrv = "\\PELABPII02\"

              sTagname = "0310VE02005_TC.PV"

              Set ImpactosCriticos =
              sServer.PIPoints(sTagname)

              TagValue = ImpactosCriticos.Data.Snapshot

               

              'Seteo de Multiestado

              Set oMultistate = Coolpump_1.CreateMultiState(sSet)

              • oMultistate.StateCount = 3
              • oMultistate.DefineState 3, 1, 3

               

              'Set Primer Estado

              Set oMSState = oMultistate.GetState(1)

              • oMSState.DefineState 1, 1.999, pbGreen
              • oMSState.Blink = False

               

              'Set Segundo Estado

              Set oMSState = oMultistate.GetState(2)

              • oMSState.DefineState 2, 2.999, pbRed
              • oMSState.Blink = True

               

              'Set Tercer Estado

              Set oMSState = oMultistate.GetState(3)

              • oMSState.DefineState 3, 3.999, pbRed
              • oMSState.Blink = False

               

              'Cálculo paradefinir estado de bomba

              If (TagValue >= 5 And R = 0) Then

                  sSet = 2

              ElseIf (TagValue >= 5 And R = 1) Then

                  sSet = 3

              Else

                  sSet = 3

              End If

              End Sub

               

              This could work, but the only problem is that the command "Create Multistate" doesn't allow me to use the sSet variable, only allows me use tagnames as string format.

              Regards,

              Noé,

                • Re: Change Multisate Symbol VBA
                  gregor

                  Hello Noé,

                   

                  You can assign your tag 0310VE02005_TC.PV to the multistate symbol and change color and blinking property based on your other conditions through VBA. So instead of writing the state which doesn't work, you modify how the state becomes visualized based on your other conditions.

                   

                  I understand that you are dealing with alarms including acknowledgement. Have you considered using PI Alarm or PI Notifications?

                  You mentioned that you don't like to spend additional PI tags but if you don't record e.g. the acknowledgement, you will later not be able to reproduce if the operator has acknowledge a certain alarm or not.

                  • Re: Change Multisate Symbol VBA
                    Guilherme Ferreira

                    Hello Noé!

                     

                    You do not need to create a multiState nor editing an existing one on runtime. You can set your multistate as desired using a Data Set (PI Calculation Data within ProcessBook) and then programatically change the values of the data set.

                    Something like:

                     

                    For index = 1 To ThisDisplay.DataSets.Count

                     

                        'Cálculo paradefinir estado de bomba

                              If (TagValue >= 5 And R = 0) Then

                                  sSet = 2

                              ElseIf (TagValue >= 5 And R = 1) Then

                                  sSet = 3

                              Else

                                 sSet = 3

                              End If

                     

                                Dim editDataSet As Dataset

                                Set editDataSet = ThisDisplay.DataSets.GetDataset(ThisDisplay.DataSets.Item(index).Name)

                                    editDataSet.Expression = sSet

                                    ThisDisplay.DataSets.SetDataset editDataSet

                                Set editDataSet = Nothing

                     

                    Next index

                     

                    Hope that helps!

                     

                    Regards

                    2 of 2 people found this helpful
                      • Re: Change Multisate Symbol VBA
                        NoéAlvarado

                        Hi Guilherme,

                        I almost have the code done I created a DataSet processbook, I made a Dataset with 3 states  and I write his value based on a condition on VBA.

                        I only have one problem when I use the button “Resetear Alarma” (Restart Alarm) this will be supposed to keep the the signal on red, but instead changes again to red and blink.

                        Please can your help me with this?

                        Also I don’t know how to make this condition work all time, I used a button but this will work all time.

                        Thank you so much for all the help, you code went really well!!

                        P.D. O attached the pdi file that I have until now.

                        Noé.

                          • Re: Change Multisate Symbol VBA
                            Guilherme Ferreira

                            Hi Noé!

                             

                            You will need to call your sub Bombas within the Display_DataUpdate so it is executed every 5s (default value).

                             

                            Private Sub Display_DataUpdate()
                                Call Bombas
                            End Sub
                            

                             

                            The problem is, once your operator resets the alarm, you set iReset to 1 but immediately after that it is set back to 0.

                             

                            ElseIf (TagValue >= 7 And iReset = 1) Then
                                sSet = 2
                                iReset = 0
                            

                             

                            The next iteration (5 seconds later), if you still have TagValue > 7 you will fall back to state 3

                             

                            ElseIf (TagValue >= 7 And iReset = 0) Then
                                sSet = 3
                            

                             

                            So, I see two options, depending on what you are actually looking for:

                             

                            1- Store the previous value of TagValue (within another Data Set, for example) to compare with the new one. If they are the same, don't change the pump state.

                            2- When the operator reset the alarm, write an annotation to the tag. Next time, if the TagValue is over 7 but it already has an annotation, keep the pump on state 2. If it is not annotated, that means it is a new alarm, set state 3.

                             

                            With this second solution, you would have the history of the reset operations, which might be a plus!

                             

                            Besides all that:

                             

                            ElseIf (TagValue >= 7 And iReset = 0) Then
                                sSet = 3
                            ElseIf (TagValue >= 7 And iReset = 0 And (sSet = 1 Or sSet = 3)) Then    //You will never get here, since for this to be true, the one before it must be true
                                sSet = 3
                            Else    //You don't need this, since you have already covered all options
                                sSet = 1
                            End If
                            
                            Set EditarDataSet = ThisDisplay.DataSets.GetDataset("DS:ALARMA_BOMBA")  //If you have the DS name, you can pass it directlly to GetDataSet function
                            

                             

                            Regards

                              • Re: Change Multisate Symbol VBA
                                Bille

                                Hello Fereira,

                                Am working on a PI Processbook design similar to this,; am having errors on the VBA:

                                see below the VBA code i used:

                                Private Sub Display_DataUpdate()

                                  

                                Dim iReset As Integer

                                 

                                 

                                Sub Bombas()

                                'Declaración de variables

                                Dim sServer As Server

                                Dim sSrv As String

                                Dim sTagname As String

                                Dim ImpactosCriticos As PIPoint

                                Dim TagValue As Variant

                                Dim sSet As Double

                                Dim EditarDataSet As DataSet

                                 

                                 

                                'Seteo tag PI a evaluar

                                Set sServer = Servers("PELABPII02")

                                sSrv = "\\PELABPII02\"

                                sTagname = "0310VE02005_TC.PV"

                                Set ImpactosCriticos = sServer.PIPoints(sTagname)

                                TagValue = ImpactosCriticos.Data.Snapshot

                                 

                                 

                                 

                                 

                                Call Bombas

                                 

                                 

                                 

                                 

                                If (TagValue >= 7 And iReset = 1) Then

                                    sSet = 2

                                    iReset

                                Else If (TagValue >= 7 And iReset = 0) Then

                                    sSet = 3

                                 

                                 

                                 

                                Else If (TagValue >= 7 And iReset = 0 And (sSet = 1 Or sSet = 3)) Then    //You will never get here, since for this to be true, the one before it must be true

                                    sSet = 3

                                 

                                 

                                End If

                                 

                                Set EditarDataSet = ThisDisplay.DataSets.GetDataset("DS:ALARMA_BOMBA")  //If you have the DS name, you can pass it directlly to GetDataSet function

                                 

                                 

                                End Sub

                                 

                                Can you please create a sample display with a working VBA code.

                                 

                                Regards

                                 

                                Bill

                                  • Re: Change Multisate Symbol VBA
                                    NoéAlvarado

                                    Hi Bill how are you? I truly sorry for forget posting the last PDI. I was able to make the alarm and also added a sound when the trigger condition activates. I´m attaching the PDI file and the soundfile too. The condition that I used is as follows. I was using a seconds timer to prove the alarm, so when the count is equal or higher than 30 the alarm (Sound) is activated and also the pump changes to red (Multistate with DataSet), even If the count goes below 30 this will be keep his state on red and the alarm until the operator resets the alarm with the button. Once he presses the reset button ("Resetear Alarma") If the actual value is below 30 then the pump will change to green and stop the alarm sound, else if the actual value still being 30 or higher then the pump will still on red (But with no blink) and will stop the sound and the logic will wait until the value goes below 30 to automatically change this to green and stop the macro (Until the value goes to 30 and start the conditions again).

                                    Hi Bill how are you?

                                    I truly sorry for forget posting the last PDI. I was able to make the alarm and also added a sound when the trigger condition activates. I´m attaching the PDI file and the soundfile too.

                                    The condition that I used is as follows. I was using a seconds timer to prove the alarm, so when the count is equal or higher than 30 the alarm (Sound) is activated and also the pump changes to red (Multistate with DataSet), even If the count goes below 30 this will be keep his state on red and the alarm until the operator resets the alarm with the button. Once he presses the reset button ("Resetear Alarma") If the actual value is below 30 then the pump will change to green and stop the alarm sound, else if the actual value still being 30 or higher then the pump will still on red (But with no blink) and will stop the sound and the logic will wait until the value goes below 30 to automatically change this to green and stop the macro (Until the value goes to 30 and start the conditions again).

                                     

                                     

                                    Private Sub Display_DataUpdate()
                                    Ruta = ThisDisplay.Path
                                    'ruta2 = Left(Ruta, InStrRev(sAlert, "\", -1, vtexcompare))
                                    sAlert = Replace(Ruta, "pdi", "wav")

                                    'Seteo tag PI a evaluar
                                    Set sServer = Servers("10.51.144.23")
                                    sSrv = "\\10.51.144.23\"
                                    sTagname = "0210ctrlc1.seg"
                                    Set ImpactosCriticos = sServer.PIPoints(sTagname)
                                    TagValue = ImpactosCriticos.Data.Snapshot

                                    'Cálculo para definir estado de la bomba
                                    If iReset = 0 Then
                                        If (sSet = 2 And TagValue < 30) Then
                                            sSet = 1
                                        ElseIf (sSet = 2 And TagValue > 30) Then
                                            sSet = 2
                                        ElseIf (sSet = 3 Or TagValue > 30) Then
                                            sSet = 3
                                        Else
                                            sSet = 1
                                        End If
                                    End If

                                    'Escribir a Dataset nuevo valor
                                    Set EditarDataSet = ThisDisplay.DataSets.GetDataset(ThisDisplay.DataSets.Item("DS:ALARMA_BOMBA").Name)
                                            EditarDataSet.Expression = sSet
                                            ThisDisplay.DataSets.SetDataset EditarDataSet
                                    Set EditarDataSet = Nothing

                                    If sSet = 3 Then
                                        playsound sAlert, 0, &H1 Or &H2 Or &H8
                                    End If
                                    End Sub
                                    Sub Resetear_Alarma()
                                    iReset = 1
                                    playsound 0, 0, &H1
                                    If TagValue < 30 Then
                                        sSet = 1
                                    Else
                                        sSet = 2
                                    End If
                                    Set EditarDataSet = ThisDisplay.DataSets.GetDataset(ThisDisplay.DataSets.Item("DS:ALARMA_BOMBA").Name)
                                            EditarDataSet.Expression = sSet
                                            ThisDisplay.DataSets.SetDataset EditarDataSet
                                    Set EditarDataSet = Nothing
                                    iReset = 0
                                    End Sub

                                     

                                     

                                    I hope this can help you, if you have any question about the PDI file just ask me.

                                    Regards,

                                    Noé.

                        • Re: Change Multisate Symbol VBA
                          Bille

                          Hello Noe,

                           

                          Thanks  for the reponse. Can I get a sample pdi to demonstrate your code. let say using sinusoid or cdt158.

                           

                          Thanks

                           

                          Bill