/Library/PRIMITIVES/TspInstrument.vb
Visual Basic | 5519 lines | 3131 code | 886 blank | 1502 comment | 22 complexity | 2818617540a2164c5a6c36c94204e5ea MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- Imports isr.Core.StringExtensions
- ''' <summary>
- ''' Defines the I/O driver for accessing the master node of a TSP Linked system.
- ''' </summary>
- ''' <remarks>
- ''' </remarks>
- ''' <license>
- ''' (c) 2010 Integrated Scientific Resources, Inc.
- ''' Licensed under the Apache License Version 2.0.
- ''' Unless required by applicable law or agreed to in writing, this software is provided
- ''' "AS IS", WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ''' </license>
- ''' <history date="02/21/2009" by="David Hary" revision="3.0.3339.x">
- ''' Created
- ''' </history>
- Public Class TspInstrument
- Inherits isr.Visa.Ieee4882.Instrument
- Implements ITspInstrument
- #Region " CONSTRUCTORS and DESTRUCTORS "
- ''' <summary>Constructs this class.</summary>
- ''' <param name="resourceTitle">Specifies the instrument name.</param>
- Public Sub New(ByVal resourceTitle As String)
- MyBase.New(resourceTitle)
- Me._statusLatency = 1
- Me._statusRepeatCount = 3
- ' Creating TSP status manager..."
- ' My.MyLibrary.TspStatus = New isr.Tsp.TspStatus(Me)
- ' default to 8 nodes at this point
- Me._maximumNodeCount = 8
- Me._usingTspLink = True
- Me._systemInitTimeout = 30000
- Me._nilifyTimeout = 10000
- Me._deleteTimeout = 10000
- Me._saveTimeout = 10000
- MyBase.ErrorAvailableBits = Visa.Ieee4882.ServiceRequests.ErrorAvailable
- MyBase.MessageAvailableBits = Visa.Ieee4882.ServiceRequests.MessageAvailable
- MyBase.IsCheckBufferOnReceive = True
- MyBase.IsCheckBufferOnSend = True
- MyBase.IsCheckOpcAfterSend = False
- MyBase.IsDelegateErrorHandling = False
- Me.NewLegacyScripts()
- Me.NewScripts()
- ' set default commands and query commands.
- MyBase.ErrorQueueQueryCommand = TspSyntax.ErrorQueueQueryCommand(TspSyntax.GlobalNode)
- MyBase.ErrorQueueCountQueryCommand = TspSyntax.ErrorQueueCountQueryCommand(TspSyntax.GlobalNode)
- MyBase.ClearErrorQueueCommand = TspSyntax.ClearErrorQueueCommand(TspSyntax.GlobalNode)
- ' include the error clear command for compatibility with 2400 instruments.
- MyBase.ClearExecutionStateCommand = TspSyntax.ClearExecutionStateCommand(TspSyntax.GlobalNode)
- ' *IDN? *WAI
- MyBase.IdentifyQueryCommand = isr.Visa.Ieee4882.Syntax.IdentifyQueryCommand & " " & isr.Visa.Ieee4882.Syntax.WaitCommand
- ' MyBase.IdentifyQueryCommand = TspSyntax.IdentifyQueryCommand(TspSyntax.LocalNode)
- 'MyBase.OperationCompletedCommand = isr.Visa.Ieee4882.Syntax.OperationCompletedCommand ' "*OPC"
- MyBase.OperationCompletedCommand = TspSyntax.OperationCompletedCommand ' "opc()"
- 'MyBase.OperationCompletedQueryCommand = isr.Visa.Ieee4882.Syntax.OperationCompletedQueryCommand ' "*OPC?"
- MyBase.OperationCompletedQueryCommand = TspSyntax.OperationCompletedQueryCommand ' "waitcomplete() print(1)"
- MyBase.OperationEventEnableCommand = TspSyntax.OperationEventEnableCommand(TspSyntax.GlobalNode)
- MyBase.OperationEventEnableQueryCommand = TspSyntax.OperationEventEnableQueryCommand(TspSyntax.GlobalNode)
- MyBase.OperationEventStatusQueryCommand = TspSyntax.OperationEventStatusQueryCommand(TspSyntax.GlobalNode)
- ' Use reset() to reset all devices on the TSP link.
- MyBase.ResetKnownStateCommand = TspSyntax.ResetKnownStateCommand(TspSyntax.GlobalNode)
- MyBase.ServiceRequestEnableCommand = TspSyntax.ServiceRequestEnableCommand(TspSyntax.GlobalNode)
- MyBase.ServiceRequestEnableQueryCommand = TspSyntax.ServiceRequestEnableQueryCommand(TspSyntax.LocalNode)
- MyBase.ServiceRequestStatusQueryCommand = TspSyntax.ServiceRequestStatusQueryCommand(TspSyntax.LocalNode)
- MyBase.StandardEventEnableCommand = TspSyntax.StandardEventEnableCommand(TspSyntax.GlobalNode)
- MyBase.StandardEventEnableQueryCommand = TspSyntax.StandardEventEnableQueryCommand(TspSyntax.GlobalNode)
- MyBase.StandardEventStatusQueryCommand = TspSyntax.StandardEventStatusQueryCommand(TspSyntax.GlobalNode)
- MyBase.WaitCommand = isr.Visa.Ieee4882.Syntax.WaitCommand ' "*WAI"
- ' TSP instrument Ready to Connect.
- End Sub
- ''' <summary>Cleans up unmanaged or managed and unmanaged resources.</summary>
- ''' <param name="disposing">True if this method releases both managed and unmanaged
- ''' resources; False if this method releases only unmanaged resources.</param>
- ''' <remarks>Executes in two distinct scenarios as determined by
- ''' its disposing parameter. If True, the method has been called directly or
- ''' indirectly by a user's code--managed and unmanaged resources can be disposed.
- ''' If disposing equals False, the method has been called by the
- ''' runtime from inside the finalizer and you should not reference
- ''' other objects--only unmanaged resources can be disposed.</remarks>
- <System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2215:Dispose methods should call base class dispose")>
- Protected Overrides Sub Dispose(ByVal disposing As Boolean)
- Try
- If Not MyBase.IsDisposed Then
- If disposing Then
- ' Free managed resources when explicitly called
- Me._legacyScripts.Dispose()
- Me._scripts.Dispose()
- If MyBase.IsConnected Then
- MyBase.Disconnect()
- End If
- End If
- ' Free shared unmanaged resources
- End If
- Finally
- ' invoke the dispose method on the base class.
- MyBase.Dispose(disposing)
- End Try
- End Sub
- #End Region
- #Region " SINGLETON "
- ''' <summary>
- ''' The locking object to enforce thread safety when creating the singleton instance.
- ''' </summary>
- Private Shared ReadOnly syncLocker As New Object
- ''' <summary>
- ''' Disposes of the default instance.
- ''' </summary>
- Public Shared Sub DisposeDefault()
- If TspInstrument.Instantiated Then
- SyncLock TspInstrument.syncLocker
- TspInstrument.instance.Dispose()
- TspInstrument.instance = Nothing
- End SyncLock
- End If
- End Sub
- ''' <summary>
- ''' Creates a new default instance of this class.</summary>
- Public Shared Sub NewDefault(ByVal resourceTitle As String)
- SyncLock TspInstrument.syncLocker
- TspInstrument.instance = New TspInstrument(resourceTitle)
- End SyncLock
- End Sub
- ''' <summary>
- ''' The shared instance.
- ''' </summary>
- Private Shared instance As TspInstrument
- ''' <summary>
- ''' Instantiates the class.
- ''' </summary>
- ''' <returns>
- ''' A new or existing instance of the class.
- ''' </returns>
- ''' <remarks>
- ''' Use this property to instantiate a single instance of this class.
- ''' This class uses lazy instantiation, meaning the instance isn't
- ''' created until the first time it's retrieved.
- ''' </remarks>
- Public Shared Function [Get](ByVal resourceTitle As String) As TspInstrument
- If Not TspInstrument.Instantiated Then
- TspInstrument.NewDefault(resourceTitle)
- End If
- Return TspInstrument.instance
- End Function
- ''' <summary>
- ''' Gets True if the singleton instance was instantiated.
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Shared ReadOnly Property Instantiated() As Boolean
- Get
- SyncLock TspInstrument.syncLocker
- Return TspInstrument.instance IsNot Nothing AndAlso Not TspInstrument.instance.IsDisposed
- End SyncLock
- End Get
- End Property
- #End Region
- #Region " ICONNECTABLE "
- ''' <summary>Raises the connecting event.</summary>
- ''' <param name="e">Passes reference to the
- ''' <see cref="System.ComponentModel.CancelEventArgs">cancel event arguments</see>.</param>
- <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
- Protected Overrides Sub OnConnecting(ByVal e As System.ComponentModel.CancelEventArgs)
- Dim synopsis As String = "On Connecting"
- ' MUST TURN OFF PROMPTS because THE TSB SYSTEM LEAVES PROMPTS ON AND RESET CLEAR DOES NOT TURN THEM OFF.
- Try
- ' allow connection time to materialize
- Threading.Thread.Sleep(100)
- Try
- Me.StoreTimeout(Me.ConnectTimeout)
- Me.OnMessageAvailable(TraceEventType.Verbose, synopsis, "Clearing error queue.")
- ' clear the error queue on the controller node only.
- Me.ClearErrorQueue()
- Catch ex As Exception
- Me.OnMessageAvailable(TraceEventType.Information, "EXCEPTION OCCURRED CLEARING ERROR QUEUE",
- "Exception occurred clearing error queue. Details: {0}. Ignored.", ex)
- Finally
- Me.RestoreTimeout()
- End Try
- Try
- Me.StoreTimeout(Me.ConnectTimeout)
- ' turn prompts off. This may not be necessary.
- TurnPromptsErrorsOff()
- Catch ex As Exception
- Me.OnMessageAvailable(TraceEventType.Information, "EXCEPTION OCCURRED TURNING OFF PROMPTS",
- "Exception occurred turning off prompts. Details: {0}. Ignored.", ex)
- Finally
- Me.RestoreTimeout()
- End Try
- ' flush the input buffer in case the instrument has some left overs.
- DiscardUnreadData()
- DiscardUnsentData()
- ' flush write may cause the instrument to send off a new data.
- DiscardUnreadData()
- ' establish the current node as the controller node.
- Dim modelNumber As String = Me.QueryTrimEnd("print(localnode.model)")
- Dim controllerNodeNumber As Integer = Me.LocalNodeNumber
- Me._controllerNode = New NodeEntity(controllerNodeNumber, modelNumber, controllerNodeNumber)
- Catch ex As Exception
- Me.OnMessageAvailable(TraceEventType.Error, "EXCETION OCCURRED TURNING OFF PROMPTS AND ERRORS",
- "Exception occurred turning off prompts and errors. Details: {0}", ex)
- If e IsNot Nothing Then
- e.Cancel = True
- End If
- End Try
- MyBase.OnConnecting(e)
- End Sub
- ''' <summary>Closes the device.
- ''' Performs the necessary termination
- ''' functions, which will cleanup and disconnect the
- ''' interface connection.
- ''' </summary>
- ''' <history>
- ''' </history>
- <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
- Public Overrides Function Disconnect() As Boolean
- ' Close the device
- Return MyBase.Disconnect()
- End Function
- ''' <summary>Raises the disconnecting event.</summary>
- ''' <param name="e">Passes reference to the <see cref="System.EventArgs">event arguments</see>.</param>
- <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
- Protected Overrides Sub OnDisconnecting(ByVal e As System.ComponentModel.CancelEventArgs)
- Dim synopsis As String = "On Disconnecting"
- If Me.IsConnected Then
- Try
- ' send termination command
- If Not Me.WriteLine("localnode.prompts = 0 localnode.showerrors = 0") Then
- MyBase.OnMessageAvailable(TraceEventType.Warning, synopsis, "Failed turning off prompts or error messages.")
- End If
- Me.ReportVisaDeviceOperationOkay(False, synopsis, "turning off prompts or error messages")
- Catch ex As BaseException
- MyBase.OnMessageAvailable(TraceEventType.Error, synopsis, "Exception occurred turning off prompts or error messages. Details: {0}", ex)
- End Try
- End If
- MyBase.OnDisconnecting(e)
- End Sub
- #End Region
- #Region " IRESETTABLE "
- ''' <summary>
- ''' Reset known state of this instance.
- ''' </summary>
- ''' <remarks></remarks>
- Public Sub ResetLocalKnownState() Implements ITspInstrument.ResetLocalKnownState
- Me._firmwareExists = New Boolean?
- Me._supportfirmwareExists = New Boolean?
- Me._serialNumber = New Long?
- Me._isTspLinkOnline = New Boolean?
- Me._lastFetchedSavedRemoteScripts = ""
- End Sub
- #End Region
- #Region " IINITIALIZATABLE "
- Private _systemInitTimeout As Integer
- ''' <summary>
- ''' Gets or sets the time out for initializing the TSP system.
- ''' </summary>
- Public Property SystemInitTimeout() As Integer Implements ITspInstrument.SystemInitTimeout
- Get
- Return Me._systemInitTimeout
- End Get
- Set(ByVal Value As Integer)
- Me._systemInitTimeout = Value
- End Set
- End Property
- Public Function InitializeSystemState() As Boolean Implements Core.IInitializable.InitializeSystemState
- Try
- Me.StoreTimeout(Me._systemInitTimeout)
- Return True
- Catch
- Throw
- Finally
- Me.RestoreTimeout()
- End Try
- End Function
- Public Function InitializeSystemState(ByVal timeout As Integer) As Boolean Implements Core.IInitializable.InitializeSystemState
- Me._systemInitTimeout = timeout
- Return Me.InitializeSystemState
- End Function
- #End Region
- #Region " PROMPT HANDLING "
- ''' <summary>
- ''' Flushes the read buffer ignoring errors.
- ''' </summary>
- ''' <param name="reportUnderData">Specifies the condition for reporting unread data.</param>
- ''' <remarks></remarks>
- <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
- Private Sub _discardUnreadData(ByVal reportUnderData As Boolean)
- Try
- Me.StoreTimeout(1000)
- MyBase.DiscardUnreadData(10, 100, reportUnderData)
- Catch ex As Exception
- Me.OnMessageAvailable(TraceEventType.Verbose, "EXCEPTION occurred FLUSHING READ BUFFER",
- "Exception occurred flushing read buffer. Details: {0}. Ignored.", ex)
- Finally
- Me.RestoreTimeout()
- End Try
- End Sub
- Private _statusLatency As Integer
- ''' <summary>
- ''' Gets or sets the time to delay checking the instrument status. This allows the instrument
- ''' time to process a write command, return the status prompt and update the message and error available bits.
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Property StatusLatency() As Integer
- Get
- Return Me._statusLatency
- End Get
- Set(ByVal value As Integer)
- Me._statusLatency = value
- End Set
- End Property
- Private _statusRepeatCount As Integer
- ''' <summary>
- ''' Gets or sets the number of time to check before returning status.
- ''' It seems that the instruments has some delay resetting the status that get cleared only after
- ''' repeated checks.
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Property StatusRepeatCount() As Integer
- Get
- Return Me._statusRepeatCount
- End Get
- Set(ByVal value As Integer)
- Me._statusRepeatCount = value
- End Set
- End Property
- ''' <summary>Reads the device status data byte and returns True
- ''' if the message available bits were set.
- ''' Delays looking for the message status by the status latency to make sure
- ''' the instrument had enough time to process the previous command.
- ''' </summary>
- ''' <returns>True if the device has data in the queue
- ''' </returns>
- Public Overrides Function IsMessageAvailable() As Boolean
- ' wait for the instrument to process the previous command before checking the message status.
- If Me._statusLatency > 0 Then
- Threading.Thread.Sleep(Me._statusLatency)
- For i As Integer = 1 To Me.StatusRepeatCount
- MyBase.IsMessageAvailable()
- Next
- End If
- ' check if we have data in the queue
- Return MyBase.IsMessageAvailable
- End Function
- ''' <summary>
- ''' Flushes the read buffer.
- ''' </summary>
- ''' <remarks></remarks>
- <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
- Public Overloads Function DiscardUnreadData() As Boolean
- Dim synopsis As String = "Flushing read buffer"
- If Me.IsMessageAvailable Then
- Me.OnMessageAvailable(TraceEventType.Verbose, synopsis, "Instrument '{0}' flushing read buffer", Me.ResourceName)
- End If
- ' flush the input buffer in case the instrument has some left overs.
- Try
- Me.StoreTimeout(1000)
- MyBase.DiscardUnreadData(10, 100, True)
- Catch ex As Exception
- Me.OnMessageAvailable(TraceEventType.Error, "EXCEPTION occurred FLUSHING READ BUFFER.",
- "Exception occurred flushing read buffer. Details: {0}", ex)
- Finally
- Me.RestoreTimeout()
- End Try
- End Function
- ''' <summary>
- ''' Flushes the read buffer.
- ''' </summary>
- ''' <remarks></remarks>
- <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
- Public Sub DiscardUnsentData()
- Try
- Me.StoreTimeout(1000)
- Me.FlushWrite()
- Catch ex As Exception
- Me.OnMessageAvailable(TraceEventType.Error, "EXCEPTION occurred FLUSHING WRITE BUFFER",
- "Exception occurred flushing write buffer. Details: {0}", ex)
- Finally
- Me.RestoreTimeout()
- End Try
- End Sub
- ''' <summary>
- ''' Turns off prompts and errors. It seems that the new systems come with prompts and errors off when
- ''' the instrument is started or reset so this is not needed.
- ''' </summary>
- ''' <remarks></remarks>
- <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
- Public Sub TurnPromptsErrorsOff()
- Dim synopsis As String = "Turning Prompts Off"
- ' flush the input buffer in case the instrument has some left overs.
- Me._discardUnreadData(True)
- Try
- ' turn off prompt transmissions
- Me.OnMessageAvailable(TraceEventType.Verbose, synopsis, "Instrument '{0}' turning off automatic sending of prompt messages. Ignoring errors.", Me.ResourceName)
- Me.WriteLine(TspSyntax.ShowPromptsCommand(False))
- Catch ex As Exception
- Me.OnMessageAvailable(TraceEventType.Verbose, "EXCEPTION occurred TURNING OFF AUTOMATIC SENDING OF PROMPT MESSASGES",
- "Exception occurred turning off automatic sending of prompt messages. Details: {0}. Exception ignored.", ex)
- End Try
- ' flush again in case turning off prompts added stuff to the buffer.
- Me._discardUnreadData(True)
- Try
- ' turn off error transmissions
- Me.OnMessageAvailable(TraceEventType.Verbose, synopsis, "Instrument '{0}' turning off automatic sending of error messages. Ignoring errors.", Me.ResourceName)
- Me.WriteLine(TspSyntax.ShowErrorsCommand(False))
- Catch ex As Exception
- Me.OnMessageAvailable(TraceEventType.Verbose, synopsis,
- "Exception occurred turning off automatic sending of error messages. Details: {1}. Exception ignored.",
- Me.ResourceName, ex)
- End Try
- ' flush again in case turning off errors added stuff to the buffer.
- Me._discardUnreadData(True)
- ' flush visa and device errors
- ' Me.FlashVisaAndDeviceErrors(False, synopsis, "before or while turning off prompts and errors.")
- Me.ReportVisaDeviceOperationOkay(False, synopsis, "before or while turning off prompts and errors.")
- End Sub
- #End Region
- #Region " TSP: DISPLAY "
- ''' <summary>
- ''' Clears the display
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks>
- ''' Sets teh display to the user mode.
- ''' </remarks>
- Public Function ClearDisplay() As Boolean Implements ITspInstrument.ClearDisplay
- Me._displayStatus = DisplayScreens.User
- If Not Me.IsDisplayExists Then
- Return True
- End If
- Me.WriteLine("display.clear()")
- Return Me.ReportVisaDeviceOperationOkay(False, "Clear Display", "clearing display")
- End Function
- ''' <summary>
- ''' Clears the display if not in measurement mode and set measurement mode.
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks>
- ''' Sets the display to the user mode.
- ''' </remarks>
- Public Function ClearDisplayMeasurement() As Boolean
- If Me.IsDisplayExists Then
- If (Me._displayStatus And DisplayScreens.Measurement) = 0 Then
- Me.ClearDisplay()
- End If
- End If
- Me._displayStatus = DisplayScreens.Measurement
- Return MyBase.LastOperationOkay
- End Function
- ''' <summary>
- ''' Displays message on line one of the display.
- ''' </summary>
- Public Function DisplayLine(ByVal lineNumber As Integer, ByVal format As String, ByVal ParamArray args() As Object) As Boolean Implements ITspInstrument.DisplayLine
- Return Me.DisplayLine(lineNumber, String.Format(Globalization.CultureInfo.CurrentCulture, format, args))
- End Function
- ''' <summary>
- ''' Displays a message on the display.
- ''' </summary>
- ''' <param name="value"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function DisplayLine(ByVal lineNumber As Integer, ByVal value As String) As Boolean Implements ITspInstrument.DisplayLine
- Me._displayStatus = DisplayScreens.User Or DisplayScreens.Custom
- If Not Me.IsDisplayExists Then
- Return True
- End If
- ' ignore empty strings.
- If String.IsNullOrEmpty(value) Then
- Return True
- End If
- Dim length As Integer = 20
- If lineNumber < 1 Then
- lineNumber = 1
- ElseIf lineNumber > 2 Then
- lineNumber = 2
- End If
- If lineNumber = 2 Then
- length = 33
- End If
- If Me.WriteLine("display.setcursor({0}, 1)", lineNumber) Then
- If value.Length < length Then
- value = value.PadRight(length)
- End If
- If Me.WriteLine("display.settext('{0}')", value) Then
- End If
- Else
- Return False
- End If
- Return Me.ReportVisaDeviceOperationOkay(False, "Display Line", "displaying line {0}.", lineNumber)
- End Function
- Private _displayStatus As DisplayScreens
- ''' <summary>
- ''' Gets the <see cref="DisplayScreens">display screen and status</see>.
- ''' </summary>
- ''' <remarks></remarks>
- Public ReadOnly Property DisplayScreen() As DisplayScreens
- Get
- Return Me._displayStatus
- End Get
- End Property
- ''' <summary>
- ''' Displays the program title.
- ''' </summary>
- ''' <param name="title">Top row data.</param>
- ''' <param name="subtitle">Bottom row data.</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function DisplayTitle(ByVal title As String, ByVal subtitle As String) As Boolean
- If Not Me.DisplayLine(0, title) Then
- Me._displayStatus = DisplayScreens.User Or DisplayScreens.Title
- Return False
- End If
- If Not Me.DisplayLine(2, subtitle) Then
- Me._displayStatus = DisplayScreens.User Or DisplayScreens.Title
- Return False
- End If
- Return True
- End Function
- Private _isDisplayExists As Boolean?
- ''' <summary>
- ''' Gets the display existence indicator. Some TSP instruments (e.g., 3706) may have no display.
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public ReadOnly Property IsDisplayExists() As Boolean Implements ITspInstrument.IsDisplayExists
- Get
- If Not Me._isDisplayExists.HasValue Then
- Try
- ' detect the display
- Me._isDisplayExists = Not Me.IsNil("display")
- Catch ex As isr.Visa.BaseException
- ' throw an exception
- Me.OnMessageAvailable(TraceEventType.Error, "EXCEPTION OCCURRED CHECKING DISPLAY EXISTANCE.",
- "Exception occurred checking display existence. Details: {0}", ex)
- Me._isDisplayExists = False
- Finally
- End Try
- End If
- Return Me._isDisplayExists.Value
- End Get
- End Property
- ''' <summary>
- ''' Restores the instrument display to its main mode.
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function RestoreDisplay() As Boolean Implements ITspInstrument.RestoreDisplay
- Me._displayStatus = DisplayScreens.Default
- If Not Me.IsDisplayExists Then
- Return True
- End If
- ' Documentation error: Display Main equals 1, not 0. This code should work on
- ' other instruments.
- Me.WriteLine("display.screen = display.MAIN or 0")
- Return Me.ReportVisaDeviceOperationOkay(False, "Restore Display", "restoring display")
- End Function
- #End Region
- #Region " TSP: ERRORS "
- Private _showErrors As Nullable(Of Boolean)
- ''' <summary>Gets the condition for showing errors.
- ''' </summary>
- Public ReadOnly Property ShowErrors() As Nullable(Of Boolean) Implements ITspInstrument.ShowErrors
- Get
- Return Me._showErrors
- End Get
- End Property
- ''' <summary>Returns the condition for showing errors.
- ''' When true, the unit will automatically display the errors stored in the
- ''' error queue, and then clear the queue. Errors will be processed at the
- ''' end of executing a command message (just prior to issuing a prompt if
- ''' prompts are enabled).
- ''' When false, errors will not display. Errors will be left in the error
- ''' queue and must be explicitly read or cleared. The error prompt (TSP?)
- ''' is enabled.
- ''' </summary>
- ''' <param name="access"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function ShowErrorsGetter(ByVal access As isr.Visa.ResourceAccessLevels) As Boolean Implements ITspInstrument.ShowErrorsGetter
- If (access = Visa.ResourceAccessLevels.Device) OrElse Not Me._showErrors.HasValue Then
- If Me.WriteQueryLine(TspSyntax.ShowErrorsQueryCommand) Then
- If Me.RaiseVisaOrDeviceException("failed getting error prompts status") Then
- Me._showErrors = 1 = Me.ReadInt32().Value
- End If
- End If
- Me.RaiseVisaOrDeviceException("failed getting error prompts status")
- End If
- Return Me._showErrors.Value
- End Function
- ''' <summary>Sets the condition for showing errors.
- ''' When true, the unit will automatically display the errors stored in the
- ''' error queue, and then clear the queue. Errors will be processed at the
- ''' end of executing a command message (just prior to issuing a prompt if
- ''' prompts are enabled).
- ''' When false, errors will not display. Errors will be left in the error
- ''' queue and must be explicitly read or cleared. The error prompt (TSP?)
- ''' is enabled.
- ''' </summary>
- ''' <param name="access"></param>
- ''' <param name="value"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function ShowErrorsSetter(ByVal value As Boolean, ByVal access As isr.Visa.ResourceAccessLevels) As Boolean Implements ITspInstrument.ShowErrorsSetter
- If (access = Visa.ResourceAccessLevels.Device) OrElse (Not Me._showErrors.HasValue) OrElse (value <> showErrors.Value) Then
- ' now send the command. This will also update the status.
- If Me.WriteLine(TspSyntax.ShowErrorsCommand(value)) Then
- Me._showErrors = value
- End If
- Me.RaiseVisaOrDeviceException("failed setting error prompts status to {0}", value)
- End If
- Return Me._showErrors.Value
- End Function
- #End Region
- #Region " TSP: GLOBAL "
- ''' <summary>
- ''' Sends a collect garbage command.
- ''' </summary>
- Public Function CollectGarbage() As Boolean Implements ITspInstrument.CollectGarbage
- ' send the message
- Return Me.WriteLine(TspSyntax.CollectGarbageCommand)
- End Function
- ''' <summary>
- ''' Collects garbage on the specified node.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the node number.</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function CollectGarbage(ByVal nodeNumber As Integer) As Boolean Implements ITspInstrument.CollectGarbage
- ' send the message
- Return Me.WriteLine(TspSyntax.CollectNodeGarbage, nodeNumber)
- End Function
- #End Region
- #Region " TSP: NODE "
- ''' <summary>
- ''' Gets the error count on a remote node.
- ''' </summary>
- ''' <param name="nodeNumber"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Overloads Function ErrorQueueCount(ByVal nodeNumber As Integer) As Integer
- If nodeNumber <= 1 Then
- Return MyBase.ErrorQueueCount(Visa.ResourceAccessLevels.Device)
- Else
- Dim count As Integer? = Me.QueryInt32("print(string.format('%d',node[{0}].errorqueue.count)) waitcomplete()", nodeNumber)
- If Me.ReportVisaOperationOkay("Fetch error queue count", "Failed fetching error queue count from node {0}", nodeNumber) Then
- Return count.Value
- Else
- Return 0
- End If
- End If
- End Function
- ''' <summary>
- ''' Fetches the error queue.
- ''' </summary>
- ''' <param name="nodeNumber"></param>
- ''' <returns></returns>
- ''' <remarks>Error messages are formatted as follows:<para>
- ''' Error #,message,level=#.</para>
- ''' <list type="bullet">
- ''' <listheader><description>Error levels are:</description>
- ''' </listheader>
- ''' <item><description>0 - Informational.</description></item>
- ''' <item><description>10 - Informational.</description></item>
- ''' <item><description>30 - Serious.</description></item>
- ''' <item><description>40 - Critical.</description></item>
- ''' </list>
- ''' </remarks>
- Public Function DequeueErrorQueue(ByVal nodeNumber As Integer) As String
- If nodeNumber <= 1 Then
- Return MyBase.ErrorQueue(Visa.ResourceAccessLevels.Device)
- Else
- Dim errors As New System.Text.StringBuilder(2048)
- Do While Me.ErrorQueueCount(nodeNumber) > 0
- Dim message As String = Me.QueryPrintFormat(String.Format(Globalization.CultureInfo.CurrentCulture,
- "error %d,%s,level=%d,node{0}", nodeNumber),
- String.Format(Globalization.CultureInfo.CurrentCulture,
- "node[{0}].errorqueue.next()", nodeNumber))
- If Me.ReportVisaDeviceOperationOkay(True, "dequeue node error", "failed dequeuing errors from node {0}", nodeNumber) Then
- errors.AppendFormat(Globalization.CultureInfo.CurrentCulture,
- "{0},node={1}", message, nodeNumber)
- errors.AppendLine()
- Else
- errors.AppendFormat(Globalization.CultureInfo.CurrentCulture,
- "Error occurred fetching error queue element from node {0}", nodeNumber)
- errors.AppendLine()
- Return errors.ToString
- End If
- Loop
- Return errors.ToString
- End If
- End Function
- ''' <summary>
- ''' Dequeues errors on all nodes.
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function DequeueErrorQueue() As String
- Dim builder As New isr.Core.MyStringBuilder
- For Each node As NodeEntity In Me._nodeEntities
- If Me.ErrorQueueCount(node.Number) > 0 Then
- Dim errors As String = Me.DequeueErrorQueue(node.Number)
- If Not String.IsNullOrEmpty(errors) Then
- builder.AppendLine("Node #{0} errors: {1}", node.Number, errors)
- End If
- End If
- Next
- Return builder.ToString
- End Function
- ''' <summary>
- ''' Reports if a device error occurred as set the <see cref="LastOperationOkay">success condition</see>
- ''' Can only be used after receiving a full reply from the instrument.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the node number.</param>
- ''' <param name="synopsis">Specifies a synopsis for the warning if an error occurred.</param>
- ''' <param name="format">Specifies the report format.</param>
- ''' <param name="args">Specifies the report arguments.</param>
- ''' <returns>True if success</returns>
- ''' <remarks></remarks>
- Public Function ReportDeviceOperationOkay(ByVal nodeNumber As Integer, ByVal synopsis As String,
- ByVal format As String, ByVal ParamArray args() As Object) As Boolean Implements ITspInstrument.ReportDeviceOperationOkay
- MyBase.ReportVisaDeviceOperationOkay(False, synopsis, format, args)
- If nodeNumber > 1 AndAlso Me.ErrorQueueCount(nodeNumber) > 0 Then
- Me.LastOperationOkay = False
- Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{1}' encountered errors {0}. Details:{3}{2}{3}{4}",
- String.Format(Globalization.CultureInfo.CurrentCulture, format, args),
- Me.ResourceName,
- Me.DequeueErrorQueue(nodeNumber),
- Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
- End If
- Return Me.LastOperationOkay
- End Function
- ''' <summary>
- ''' Makes a script nil and returns true if the script was nilified.
- ''' Does not check if the script exists.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the remote node number.</param>
- ''' <param name="name">Specifies the script name</param>
- ''' <returns></returns>
- ''' <remarks>Assumes the script is known to exist.
- ''' Waits till completion.
- ''' </remarks>
- Private Function _nilifyScript(ByVal nodeNumber As Integer, ByVal name As String) As Boolean
- If String.IsNullOrEmpty(name) Then
- Return False
- End If
- Dim synopsis As String = "Nullifying Script"
- ' ignore errors as failure is handled below.
- Me.ExecuteCommandWaitComplete(nodeNumber, Me._nilifyTimeout, False, "{0} = nil", name)
- ' allow the next command to create an error if wait complete times out.
- If Me.IsNil(nodeNumber, name) Then
- Return True
- Else
- Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' script {1} still exists on node {2} after nil.{3}{4}",
- Me.ResourceName, name, nodeNumber,
- Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
- Return False
- End If
- End Function
- ''' <summary>
- ''' Makes a script nil and returns true if the script was nullified.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the remote node number.</param>
- ''' <param name="name">Specifies the script name</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function NilifyScript(ByVal nodeNumber As Integer, ByVal name As String) As Boolean Implements ITspInstrument.NilifyScript
- If String.IsNullOrEmpty(name) Then
- Return False
- End If
- If Me.IsNil(nodeNumber, name) Then
- Return True
- Else
- Return Me._nilifyScript(nodeNumber, name)
- End If
- End Function
- ''' <summary>
- ''' Sets the connect rule on the specified node.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the remote node number.</param>
- ''' <param name="value"></param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function ConnectRuleSetter(ByVal nodeNumber As Integer, ByVal value As Integer) As Boolean Implements ITspInstrument.ConnectRuleSetter
- Return Me.WriteLine(TspSyntax.ConnectRuleSetter, nodeNumber, value)
- End Function
- ''' <summary>
- ''' Deletes the <paramref name="name">specified</paramref> script.
- ''' Also nilifies the script if delete command worked.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the remote node number.</param>
- ''' <param name="name">Specifies the script name</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function DeleteScript(ByVal nodeNumber As Integer, ByVal name As String, ByVal refreshScriptCatalog As Boolean) As Boolean Implements ITspInstrument.DeleteScript
- If String.IsNullOrEmpty(name) Then
- Return False
- End If
- If Me.SavedScriptExists(nodeNumber, name, refreshScriptCatalog) Then
- Return Me.DeleteSavedScript(nodeNumber, name)
- Else
- Return Me.NilifyScript(nodeNumber, name)
- End If
- End Function
- ''' <summary>
- ''' Deletes the <paramref name="name">specified</paramref> script.
- ''' Also nilifies the script if delete command worked.
- ''' </summary>
- ''' <param name="node">Specifies the node.</param>
- ''' <param name="name">Specifies the script name</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function DeleteScript(ByVal node As INodeEntity, ByVal name As String, ByVal refreshScriptCatalog As Boolean) As Boolean
- If node Is Nothing Then
- Throw New ArgumentNullException("node")
- End If
- If String.IsNullOrEmpty(name) Then
- Return False
- End If
- If node.IsController Then
- Return DeleteScript(name, refreshScriptCatalog)
- Else
- Return DeleteScript(node.Number, name, refreshScriptCatalog)
- End If
- End Function
- ''' <summary>
- ''' Deletes the <paramref name="name">specified</paramref> saved script.
- ''' Also nilifies the script if delete command worked.
- ''' Then checks if the script was deleted and if so returns true.
- ''' Otherwise, returns false.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the remote node number.</param>
- ''' <param name="name">Specifies the script name</param>
- ''' <returns></returns>
- ''' <remarks>Presumes the saved script exists.
- ''' Waits for operation completion.
- ''' </remarks>
- Public Function DeleteSavedScript(ByVal nodeNumber As Integer, ByVal name As String) As Boolean
- If String.IsNullOrEmpty(name) Then
- Return False
- End If
- Dim synopsis As String = "Deleting Saved Script"
- ' failure is handled below.
- Me.ExecuteCommandWaitComplete(nodeNumber, Me.DeleteTimeout, False, "script.delete('{0}')", name)
- ' make script nil
- If Me.NilifyScript(nodeNumber, name) Then
- ' make sure to re-check that script is gone.
- If Me.SavedScriptExists(nodeNumber, name, True) Then
- Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' saved script {1} still exists after nil on node {2}{3}{4}",
- Me.ResourceName, name, nodeNumber,
- Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
- Return False
- Else
- Return True
- End If
- Else
- Return False
- End If
- End Function
- ''' <summary>
- ''' Deletes the <paramref name="name">specified</paramref> saved script.
- ''' Also nilifies the script if delete command worked.
- ''' Returns true if the script was deleted.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the remote node number.</param>
- ''' <param name="name">Specifies the script name</param>
- ''' <returns></returns>
- ''' <remarks>
- ''' Waits for operation completion.
- ''' </remarks>
- Public Function DeleteSavedScript(ByVal nodeNumber As Integer, ByVal name As String, ByVal refreshScriptCatalog As Boolean) As Boolean Implements ITspInstrument.DeleteSavedScript
- If String.IsNullOrEmpty(name) Then
- Return False
- End If
- Dim synopsis As String = "Deleting Saved Script"
- If Me.SavedScriptExists(nodeNumber, name, refreshScriptCatalog) Then
- ' execute command but ignore errors as they are handled below.
- Me.ExecuteCommandWaitComplete(nodeNumber, Me.DeleteTimeout, False, "script.delete('{0}')", name)
- ' make script nil
- If Me.NilifyScript(nodeNumber, name) Then
- ' make sure to re-check that script is gone.
- If Me.SavedScriptExists(nodeNumber, name, True) Then
- Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' saved script {1} still exists after nil on node {2}{3}{4}",
- Me.ResourceName, name, nodeNumber,
- Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
- Return False
- Else
- Return True
- End If
- Else
- Return False
- End If
- Else
- Return True
- End If
- End Function
- ''' <summary>
- ''' Executes a command on the node.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the node number.</param>
- ''' <param name="isQuery">Specifies the condition indicating if the command is a query, which determines how errors are fetched.</param>
- ''' <param name="format">Specifies the command format.</param>
- ''' <param name="args">Specifies the command arguments.</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function ExecuteCommandWaitComplete(ByVal nodeNumber As Integer,
- ByVal timeout As Integer,
- ByVal isQuery As Boolean,
- ByVal format As String,
- ByVal ParamArray args() As Object) As Boolean
- Dim synopsis As String = "Execute node command"
- Dim command As String = String.Format(Globalization.CultureInfo.CurrentCulture, format, args)
- If Me.WriteLine(TspSyntax.ExecuteCommand, nodeNumber, command) Then
- IssueWaitComplete(0)
- Me.AwaitOperationCompleted(timeout, timeout \ 10 + 10)
- If isQuery Then
- If Not ReportVisaOperationOkay(synopsis, "executing '{0}' on node {1}", command, nodeNumber) Then
- Return False
- End If
- Else
- If Not ReportDeviceOperationOkay(nodeNumber, synopsis, "executing '{0}' on node {1}", command, nodeNumber) Then
- Return False
- End If
- End If
- Else
- Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' failed executing '{1}' on node {2}.{3}{4}",
- Me.ResourceName, command, nodeNumber,
- Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
- Return False
- End If
- Return True
- End Function
- ''' <summary>
- ''' Executes a command on the node.
- ''' </summary>
- ''' <param name="node">Specifies the node.</param>
- ''' <param name="isQuery">Specifies the condition indicating if the command is a query, which determines how errors are fetched.
- ''' While the remote command will not return values, the local node may.</param>
- ''' <param name="format">Specifies the command format.</param>
- ''' <param name="args">Specifies the command arguments.</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function ExecuteCommandWaitComplete(ByVal node As INodeEntity,
- ByVal timeout As Integer,
- ByVal isQuery As Boolean,
- ByVal format As String,
- ByVal ParamArray args() As Object) As Boolean
- If node Is Nothing Then
- Throw New ArgumentNullException("node")
- End If
- If node.IsController Then
- Dim synopsis As String = "Execute node command"
- Dim command As String = String.Format(Globalization.CultureInfo.CurrentCulture, format, args)
- If Me.WriteLine(format, args) Then
- IssueWaitComplete(0)
- Me.AwaitOperationCompleted(timeout, timeout \ 10 + 10)
- If isQuery Then
- If Not ReportVisaOperationOkay(synopsis, "executing '{0}' on node {1}", command, node.Number) Then
- Return False
- End If
- Else
- If Not ReportDeviceOperationOkay(node.Number, synopsis, "executing '{0}' on node {1}", command, node.Number) Then
- Return False
- End If
- End If
- Else
- Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' failed executing '{1}' on node {2}.{3}{4}",
- Me.ResourceName, command, node.Number,
- Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
- Return False
- End If
- Return True
- Else
- Return Me.ExecuteCommandWaitComplete(node.Number, timeout, isQuery, format, args)
- End If
- End Function
- ''' <summary>
- ''' Executes a command on the remote node. This leaves an item in the input buffer that must be retried.
- ''' </summary>
- ''' <param name="nodeNumber">Specifies the remote node number.</param>
- ''' <param name="format">Specifies the command format.</param>
- ''' <param name="args">Specifies the command arguments.</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Function ExecuteValueGetter(ByVal nodeNumber As Integer, ByVal format As String, ByVal ParamArray args() As Object) As Boolean Implements ITspInstrument.ExecuteValueGetter
- If String.IsNullOrEmpty(format) Then
- Throw New ArgumentNullException("format")
- Else
- Return Me.WriteLine(TspSyntax.ValueGetterCommand1, nodeNumber,
- String.Format(Globalization.CultureInfo.CurrentCulture, format, args))
- End If
- Return False
- End Function
- Private _lastFetchedSavedRemoteScripts As String
- ''' <summary>
- ''' Gets a comma-separated and comma-terminated list of the saved scripts
- ''' that was fetched last from the remote node. A new script is fetched after save and delete.
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public ReadOnly Property LastFetchedSavedRemoteScripts() As String Implements ITspInstrument.LastFetchedSavedRemoteScripts
- Get
- Return Me._lastFetchedSavedRemoteScripts
- End Get
- End Property
- ''' <summary>
- ''' Fetches the list of saved scripts and saves it in the <see cref="LastFetchedSavedScripts"></see>
- ''' </summary>
- ''' <returns></returns>
- ''' <remarks></remarks>
- <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
- Public Function FetchSavedScripts(ByVal nodeNumber As Integer) As Boolean Implements ITspInstrument.FetchSavedScripts
- Dim synopsis As String = "Fetch Saved Scripts"
- Try
- Me.StoreTimeout(Me._saveTimeout)
- Me._lastFetchedSavedRemoteScripts = ""
- If Me.WriteQueryLine(TspSyntax.ValueGetterCommand2, nodeNumber, TspSyntax.ScriptCatalogGetterCommand, "names") Then
- If Me.ReportVisaDeviceOperationOkay(True, "Fetch Node Saved Scripts", "Failed fetching catalog from node {0}", nodeNumber) Then
- Me._lastFetchedSavedRemoteScripts = Me.ReadLineTrimEnd
- Else
- Return False
- End If
- If String.IsNullOrEmpty(Me._lastFetchedSavedRemoteScripts) Then
- Me._lastFetchedSavedRemoteScripts = ""
- End If
- End If
- Return ReportDeviceOperationOkay(nodeNumber, synopsis, "Failed fetching catalog from node {0}", nodeNumber)
- Catch
- Throw
- Finally
- MyBase.RestoreTimeout()
- End Try
- End …
Large files files are truncated, but you can click here to view the full file