14 Replies Latest reply on Apr 21, 2010 7:28 AM by andreas

    Autoscale

    matthew.rivett

      Autoscale in ProcessBook will only make the scale larger and not make the scale smaller.  To get around this one of our users did the following:

      Private Sub Display_DataUpdate()
         ThisDisplay.Revert
      End Sub

      This would cause all of the trends to query the archive subsystem every 5 seconds.  There are also datasets on the display which cause us big headaches with pibasess using up a ton of CPU (this has been an issue for us since upgrading to 3.4.375.99 when some locking mechanism was changed to prevent pi database corruption).

       

      Is there a way to make autoscale work in both directions?  It must be able to done with some code.

        • Re: Autoscale
          matthew.rivett

          For now I am just going to limit how often the revert runs.

          Dim dtLastRevert As Date

          Private Sub Display_DataUpdate()
              If DateDiff("n", dtLastRevert, Now) >= 60 Then
                  ThisDisplay.Revert
                  dtLastRevert = Now()
              End If
          End Sub

          Private Sub Display_Open()
              dtLastRevert = Now()
              ThisDisplay.Zoom = "FitAll"
          End Sub

          • Re: Autoscale
            mheere

            Hi Matt,

             

            Have you tried explicitly resetting the trend scale via code?  I don't know if just resetting it to autoscale actually forces the scaling to occur.  You may have to set it to a fixed value, and the immediately reset it back to auto.

             

            Look in the PI ProcessBook VBA Language Reference for the trend method SetTraceScale

             

            Regards,

             

            Matt

              • Re: Autoscale
                andreas

                Hi Matt,

                 

                Matt's suggestion works fine with just setting Autorange.

                Dim MySymbol As Symbol
                For Each MySymbol In ThisDisplay.Symbols
                    If MySymbol.Type = pbSymbolTrend Then
                        Dim MyTrend As Trend
                         Set MyTrend = MySymbol
                         Call MyTrend.SetTraceScale("Autorange", "Autorange")
                     End If
                Next MySymbol
                  • Re: Autoscale
                    matthew.rivett

                    Thanks I think that is a better method than reverting the display.  I'll test it out and see.

                      • Re: Autoscale
                        matthew.rivett

                        This works well except it changes all trends to Autoscale.  Some of the trends have scales defined.  I tried looking at MyTrend.ScaleMin and MyTrend.ScaleMax and only reset if they are "Autorange" but they don't seem to have a value.

                        Private Sub AutoScaleTrends()
                            Dim MySymbol As Symbol
                            For Each MySymbol In ThisDisplay.Symbols
                                If MySymbol.Type = pbSymbolTrend Then
                                    Dim MyTrend As Trend
                                    Set MyTrend = MySymbol
                                    MsgBox ("Max: " + MyTrend.ScaleMax + " Min: " + MyTrend.ScaleMin)
                                    Call MyTrend.SetTraceScale("Autorange", "Autorange")
                                End If
                            Next MySymbol
                        End Sub
                          • Re: Autoscale
                            andreas

                            For a Trend you will have to check the traces. I'll need to take a look and come back with some more code

                              • Re: Autoscale

                                For a Trend you can just loop through the traces and set the same trace scale.  Something like...

                                If MyTrend.TraceCount > 0 Then
                                    For i = 1 To MyTrend.TraceCount
                                        MyTrend.CurrentTrace = i
                                        MyTrend.SetTraceScale MyTrend.ScaleMin, MyTrend.ScaleMax
                                    Next i
                                End If

                                 

                                  • Re: Autoscale
                                    andreas

                                    Rhys was faster than I.

                                      • Re: Autoscale
                                        matthew.rivett

                                        Thanks for the help everyone.  I'm testing out the code below to make sure there is no unexpected issues but it is working great so far.

                                        Dim dtLastScaleReset As Date

                                        Private Sub Display_DataUpdate()
                                            ResetTrendScales
                                        End Sub

                                        Private Sub Display_Open()
                                            dtLastScaleReset = Now()
                                            ThisDisplay.Zoom = "FitAll"
                                        End Sub

                                        Private Sub ResetTrendScales()
                                            If DateDiff("n", dtLastScaleReset, Now) >= 5 Then
                                                    Dim MySymbol As Symbol
                                                    For Each MySymbol In ThisDisplay.Symbols
                                                        If MySymbol.Type = pbSymbolTrend Then
                                                            Dim MyTrend As Trend
                                                            Set MyTrend = MySymbol
                                                            If MyTrend.TraceCount > 0 Then
                                                                For i = 1 To MyTrend.TraceCount
                                                                    MyTrend.CurrentTrace = i
                                                                    MyTrend.SetTraceScale MyTrend.ScaleMin, MyTrend.ScaleMax
                                                                Next i
                                                            End If
                                                        End If
                                                    Next MySymbol
                                                dtLastScaleReset = Now()
                                            End If
                                        End Sub

                                          • Re: Autoscale
                                            mheere

                                            Hi Matt,

                                             

                                            Only thing I might suggest is doign the loop to find all the trends, and subsequently the traces that are set to auto, once and stashing the results away in a collection.  Looping through every symbol in the display is going to be a terribly expensive operation given the size of some of your ProcessBook stuff.

                                             

                                            Something like this (pseudo code obviously)

                                             

                                            Dim bInitComplete as Boolean

                                             

                                            Dim cTracesToReset as Collection

                                             

                                            Private Sub Display_Open()

                                             

                                                 bInitComplete = false

                                             

                                            End Sub

                                             

                                             

                                             

                                            Private Sub ResetTrendScales()

                                             

                                                If Not bInitComplete Then

                                             

                                                      For each symbol on the display

                                             

                                                             If symbol is a Trend Then 

                                             

                                                                      For each trace in the trend

                                             

                                                                                  If trace is autoscale then add to cTracesToReset

                                             

                                                       bInitCoplete = True

                                             

                                                 Else

                                             

                                                      For each trace in ctracesToReset do the reset

                                             

                                            End Sub

                                              • Re: Autoscale
                                                matthew.rivett

                                                This particular display is pretty small.  As soon as I put the code on this display it will only be a matter of days before it shows up on every display.  So you're right and I'll look into this.

                                                 

                                                 

                                                  • Re: Autoscale

                                                    Matt Rivett

                                                    As soon as I put the code on this display it will only be a matter of days before it shows up on every display. 

                                                     

                                                     

                                                    That sounds very familiar

                                                     

                                                     

                                                      • Re: Autoscale
                                                        matthew.rivett

                                                        I don't know how to do anything with Traces as they don't appear to be objects.  I can however make a collection of trends that contain autoscaled traces.

                                                        
                                                        

                                                        Dim dtLastScaleReset As Date
                                                        Dim cTrends As Collection
                                                        Dim bTrendsLoaded As Boolean

                                                        Private Sub Display_Open()
                                                            dtLastScaleReset = Now()
                                                            ThisDisplay.Zoom = "FitAll"
                                                           
                                                            ' load trends
                                                            bTrendsLoaded = False
                                                            Set cTrends = getAutoScaledTrends
                                                            bTrendsLoaded = True
                                                        End Sub

                                                        Private Function getAutoScaledTrends() As Collection
                                                        ' all trends that contain at least one trace that is autoscaled
                                                            Dim myTrends As New Collection
                                                            For Each MySymbol In ThisDisplay.Symbols
                                                                If MySymbol.Type = pbSymbolTrend Then
                                                                    Dim bAddTrend As Boolean
                                                                    bAddTrend = False
                                                                    Dim myTrend As Trend
                                                                    Set myTrend = MySymbol
                                                                    If myTrend.TraceCount > 0 Then
                                                                        For i = 1 To myTrend.TraceCount
                                                                            myTrend.CurrentTrace = i
                                                                            If (myTrend.ScaleMin = "Autorange" Or myTrend.ScaleMax = "Autorange") Then
                                                                                bAddTrend = True
                                                                            End If
                                                                        Next i
                                                                    End If
                                                                    If bAddTrend Then
                                                                        myTrends.Add myTrend
                                                                    End If
                                                                End If
                                                            Next MySymbol
                                                            Set getAutoScaledTrends = myTrends
                                                        End Function

                                                        Private Sub Display_DataUpdate()
                                                        ' fires each time data updates in processbook
                                                            If bTrendsLoaded Then
                                                                ResetTrendScales
                                                            End If
                                                        End Sub

                                                        Private Sub ResetTrendScales()
                                                        ' reset trend scales for all trends in cTrends collection
                                                            If DateDiff("n", dtLastScaleReset, Now) >= 5 Then
                                                                Dim myTrend As Trend
                                                                For Each myTrend In cTrends
                                                                    For i = 1 To myTrend.TraceCount
                                                                        myTrend.CurrentTrace = i
                                                                        myTrend.SetTraceScale myTrend.ScaleMin, myTrend.ScaleMax
                                                                    Next i
                                                                Next myTrend
                                                                dtLastScaleReset = Now()
                                                            End If
                                                        End Sub