PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/Library/PRIMITIVES/TspInstrument.vb

https://bitbucket.org/davidhary/isr.tsp.vb.3.x
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

  1. Imports isr.Core.StringExtensions
  2. ''' <summary>
  3. ''' Defines the I/O driver for accessing the master node of a TSP Linked system.
  4. ''' </summary>
  5. ''' <remarks>
  6. ''' </remarks>
  7. ''' <license>
  8. ''' (c) 2010 Integrated Scientific Resources, Inc.
  9. ''' Licensed under the Apache License Version 2.0.
  10. ''' Unless required by applicable law or agreed to in writing, this software is provided
  11. ''' "AS IS", WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. ''' </license>
  13. ''' <history date="02/21/2009" by="David Hary" revision="3.0.3339.x">
  14. ''' Created
  15. ''' </history>
  16. Public Class TspInstrument
  17. Inherits isr.Visa.Ieee4882.Instrument
  18. Implements ITspInstrument
  19. #Region " CONSTRUCTORS and DESTRUCTORS "
  20. ''' <summary>Constructs this class.</summary>
  21. ''' <param name="resourceTitle">Specifies the instrument name.</param>
  22. Public Sub New(ByVal resourceTitle As String)
  23. MyBase.New(resourceTitle)
  24. Me._statusLatency = 1
  25. Me._statusRepeatCount = 3
  26. ' Creating TSP status manager..."
  27. ' My.MyLibrary.TspStatus = New isr.Tsp.TspStatus(Me)
  28. ' default to 8 nodes at this point
  29. Me._maximumNodeCount = 8
  30. Me._usingTspLink = True
  31. Me._systemInitTimeout = 30000
  32. Me._nilifyTimeout = 10000
  33. Me._deleteTimeout = 10000
  34. Me._saveTimeout = 10000
  35. MyBase.ErrorAvailableBits = Visa.Ieee4882.ServiceRequests.ErrorAvailable
  36. MyBase.MessageAvailableBits = Visa.Ieee4882.ServiceRequests.MessageAvailable
  37. MyBase.IsCheckBufferOnReceive = True
  38. MyBase.IsCheckBufferOnSend = True
  39. MyBase.IsCheckOpcAfterSend = False
  40. MyBase.IsDelegateErrorHandling = False
  41. Me.NewLegacyScripts()
  42. Me.NewScripts()
  43. ' set default commands and query commands.
  44. MyBase.ErrorQueueQueryCommand = TspSyntax.ErrorQueueQueryCommand(TspSyntax.GlobalNode)
  45. MyBase.ErrorQueueCountQueryCommand = TspSyntax.ErrorQueueCountQueryCommand(TspSyntax.GlobalNode)
  46. MyBase.ClearErrorQueueCommand = TspSyntax.ClearErrorQueueCommand(TspSyntax.GlobalNode)
  47. ' include the error clear command for compatibility with 2400 instruments.
  48. MyBase.ClearExecutionStateCommand = TspSyntax.ClearExecutionStateCommand(TspSyntax.GlobalNode)
  49. ' *IDN? *WAI
  50. MyBase.IdentifyQueryCommand = isr.Visa.Ieee4882.Syntax.IdentifyQueryCommand & " " & isr.Visa.Ieee4882.Syntax.WaitCommand
  51. ' MyBase.IdentifyQueryCommand = TspSyntax.IdentifyQueryCommand(TspSyntax.LocalNode)
  52. 'MyBase.OperationCompletedCommand = isr.Visa.Ieee4882.Syntax.OperationCompletedCommand ' "*OPC"
  53. MyBase.OperationCompletedCommand = TspSyntax.OperationCompletedCommand ' "opc()"
  54. 'MyBase.OperationCompletedQueryCommand = isr.Visa.Ieee4882.Syntax.OperationCompletedQueryCommand ' "*OPC?"
  55. MyBase.OperationCompletedQueryCommand = TspSyntax.OperationCompletedQueryCommand ' "waitcomplete() print(1)"
  56. MyBase.OperationEventEnableCommand = TspSyntax.OperationEventEnableCommand(TspSyntax.GlobalNode)
  57. MyBase.OperationEventEnableQueryCommand = TspSyntax.OperationEventEnableQueryCommand(TspSyntax.GlobalNode)
  58. MyBase.OperationEventStatusQueryCommand = TspSyntax.OperationEventStatusQueryCommand(TspSyntax.GlobalNode)
  59. ' Use reset() to reset all devices on the TSP link.
  60. MyBase.ResetKnownStateCommand = TspSyntax.ResetKnownStateCommand(TspSyntax.GlobalNode)
  61. MyBase.ServiceRequestEnableCommand = TspSyntax.ServiceRequestEnableCommand(TspSyntax.GlobalNode)
  62. MyBase.ServiceRequestEnableQueryCommand = TspSyntax.ServiceRequestEnableQueryCommand(TspSyntax.LocalNode)
  63. MyBase.ServiceRequestStatusQueryCommand = TspSyntax.ServiceRequestStatusQueryCommand(TspSyntax.LocalNode)
  64. MyBase.StandardEventEnableCommand = TspSyntax.StandardEventEnableCommand(TspSyntax.GlobalNode)
  65. MyBase.StandardEventEnableQueryCommand = TspSyntax.StandardEventEnableQueryCommand(TspSyntax.GlobalNode)
  66. MyBase.StandardEventStatusQueryCommand = TspSyntax.StandardEventStatusQueryCommand(TspSyntax.GlobalNode)
  67. MyBase.WaitCommand = isr.Visa.Ieee4882.Syntax.WaitCommand ' "*WAI"
  68. ' TSP instrument Ready to Connect.
  69. End Sub
  70. ''' <summary>Cleans up unmanaged or managed and unmanaged resources.</summary>
  71. ''' <param name="disposing">True if this method releases both managed and unmanaged
  72. ''' resources; False if this method releases only unmanaged resources.</param>
  73. ''' <remarks>Executes in two distinct scenarios as determined by
  74. ''' its disposing parameter. If True, the method has been called directly or
  75. ''' indirectly by a user's code--managed and unmanaged resources can be disposed.
  76. ''' If disposing equals False, the method has been called by the
  77. ''' runtime from inside the finalizer and you should not reference
  78. ''' other objects--only unmanaged resources can be disposed.</remarks>
  79. <System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2215:Dispose methods should call base class dispose")>
  80. Protected Overrides Sub Dispose(ByVal disposing As Boolean)
  81. Try
  82. If Not MyBase.IsDisposed Then
  83. If disposing Then
  84. ' Free managed resources when explicitly called
  85. Me._legacyScripts.Dispose()
  86. Me._scripts.Dispose()
  87. If MyBase.IsConnected Then
  88. MyBase.Disconnect()
  89. End If
  90. End If
  91. ' Free shared unmanaged resources
  92. End If
  93. Finally
  94. ' invoke the dispose method on the base class.
  95. MyBase.Dispose(disposing)
  96. End Try
  97. End Sub
  98. #End Region
  99. #Region " SINGLETON "
  100. ''' <summary>
  101. ''' The locking object to enforce thread safety when creating the singleton instance.
  102. ''' </summary>
  103. Private Shared ReadOnly syncLocker As New Object
  104. ''' <summary>
  105. ''' Disposes of the default instance.
  106. ''' </summary>
  107. Public Shared Sub DisposeDefault()
  108. If TspInstrument.Instantiated Then
  109. SyncLock TspInstrument.syncLocker
  110. TspInstrument.instance.Dispose()
  111. TspInstrument.instance = Nothing
  112. End SyncLock
  113. End If
  114. End Sub
  115. ''' <summary>
  116. ''' Creates a new default instance of this class.</summary>
  117. Public Shared Sub NewDefault(ByVal resourceTitle As String)
  118. SyncLock TspInstrument.syncLocker
  119. TspInstrument.instance = New TspInstrument(resourceTitle)
  120. End SyncLock
  121. End Sub
  122. ''' <summary>
  123. ''' The shared instance.
  124. ''' </summary>
  125. Private Shared instance As TspInstrument
  126. ''' <summary>
  127. ''' Instantiates the class.
  128. ''' </summary>
  129. ''' <returns>
  130. ''' A new or existing instance of the class.
  131. ''' </returns>
  132. ''' <remarks>
  133. ''' Use this property to instantiate a single instance of this class.
  134. ''' This class uses lazy instantiation, meaning the instance isn't
  135. ''' created until the first time it's retrieved.
  136. ''' </remarks>
  137. Public Shared Function [Get](ByVal resourceTitle As String) As TspInstrument
  138. If Not TspInstrument.Instantiated Then
  139. TspInstrument.NewDefault(resourceTitle)
  140. End If
  141. Return TspInstrument.instance
  142. End Function
  143. ''' <summary>
  144. ''' Gets True if the singleton instance was instantiated.
  145. ''' </summary>
  146. ''' <value></value>
  147. ''' <returns></returns>
  148. ''' <remarks></remarks>
  149. Public Shared ReadOnly Property Instantiated() As Boolean
  150. Get
  151. SyncLock TspInstrument.syncLocker
  152. Return TspInstrument.instance IsNot Nothing AndAlso Not TspInstrument.instance.IsDisposed
  153. End SyncLock
  154. End Get
  155. End Property
  156. #End Region
  157. #Region " ICONNECTABLE "
  158. ''' <summary>Raises the connecting event.</summary>
  159. ''' <param name="e">Passes reference to the
  160. ''' <see cref="System.ComponentModel.CancelEventArgs">cancel event arguments</see>.</param>
  161. <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
  162. Protected Overrides Sub OnConnecting(ByVal e As System.ComponentModel.CancelEventArgs)
  163. Dim synopsis As String = "On Connecting"
  164. ' MUST TURN OFF PROMPTS because THE TSB SYSTEM LEAVES PROMPTS ON AND RESET CLEAR DOES NOT TURN THEM OFF.
  165. Try
  166. ' allow connection time to materialize
  167. Threading.Thread.Sleep(100)
  168. Try
  169. Me.StoreTimeout(Me.ConnectTimeout)
  170. Me.OnMessageAvailable(TraceEventType.Verbose, synopsis, "Clearing error queue.")
  171. ' clear the error queue on the controller node only.
  172. Me.ClearErrorQueue()
  173. Catch ex As Exception
  174. Me.OnMessageAvailable(TraceEventType.Information, "EXCEPTION OCCURRED CLEARING ERROR QUEUE",
  175. "Exception occurred clearing error queue. Details: {0}. Ignored.", ex)
  176. Finally
  177. Me.RestoreTimeout()
  178. End Try
  179. Try
  180. Me.StoreTimeout(Me.ConnectTimeout)
  181. ' turn prompts off. This may not be necessary.
  182. TurnPromptsErrorsOff()
  183. Catch ex As Exception
  184. Me.OnMessageAvailable(TraceEventType.Information, "EXCEPTION OCCURRED TURNING OFF PROMPTS",
  185. "Exception occurred turning off prompts. Details: {0}. Ignored.", ex)
  186. Finally
  187. Me.RestoreTimeout()
  188. End Try
  189. ' flush the input buffer in case the instrument has some left overs.
  190. DiscardUnreadData()
  191. DiscardUnsentData()
  192. ' flush write may cause the instrument to send off a new data.
  193. DiscardUnreadData()
  194. ' establish the current node as the controller node.
  195. Dim modelNumber As String = Me.QueryTrimEnd("print(localnode.model)")
  196. Dim controllerNodeNumber As Integer = Me.LocalNodeNumber
  197. Me._controllerNode = New NodeEntity(controllerNodeNumber, modelNumber, controllerNodeNumber)
  198. Catch ex As Exception
  199. Me.OnMessageAvailable(TraceEventType.Error, "EXCETION OCCURRED TURNING OFF PROMPTS AND ERRORS",
  200. "Exception occurred turning off prompts and errors. Details: {0}", ex)
  201. If e IsNot Nothing Then
  202. e.Cancel = True
  203. End If
  204. End Try
  205. MyBase.OnConnecting(e)
  206. End Sub
  207. ''' <summary>Closes the device.
  208. ''' Performs the necessary termination
  209. ''' functions, which will cleanup and disconnect the
  210. ''' interface connection.
  211. ''' </summary>
  212. ''' <history>
  213. ''' </history>
  214. <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
  215. Public Overrides Function Disconnect() As Boolean
  216. ' Close the device
  217. Return MyBase.Disconnect()
  218. End Function
  219. ''' <summary>Raises the disconnecting event.</summary>
  220. ''' <param name="e">Passes reference to the <see cref="System.EventArgs">event arguments</see>.</param>
  221. <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
  222. Protected Overrides Sub OnDisconnecting(ByVal e As System.ComponentModel.CancelEventArgs)
  223. Dim synopsis As String = "On Disconnecting"
  224. If Me.IsConnected Then
  225. Try
  226. ' send termination command
  227. If Not Me.WriteLine("localnode.prompts = 0 localnode.showerrors = 0") Then
  228. MyBase.OnMessageAvailable(TraceEventType.Warning, synopsis, "Failed turning off prompts or error messages.")
  229. End If
  230. Me.ReportVisaDeviceOperationOkay(False, synopsis, "turning off prompts or error messages")
  231. Catch ex As BaseException
  232. MyBase.OnMessageAvailable(TraceEventType.Error, synopsis, "Exception occurred turning off prompts or error messages. Details: {0}", ex)
  233. End Try
  234. End If
  235. MyBase.OnDisconnecting(e)
  236. End Sub
  237. #End Region
  238. #Region " IRESETTABLE "
  239. ''' <summary>
  240. ''' Reset known state of this instance.
  241. ''' </summary>
  242. ''' <remarks></remarks>
  243. Public Sub ResetLocalKnownState() Implements ITspInstrument.ResetLocalKnownState
  244. Me._firmwareExists = New Boolean?
  245. Me._supportfirmwareExists = New Boolean?
  246. Me._serialNumber = New Long?
  247. Me._isTspLinkOnline = New Boolean?
  248. Me._lastFetchedSavedRemoteScripts = ""
  249. End Sub
  250. #End Region
  251. #Region " IINITIALIZATABLE "
  252. Private _systemInitTimeout As Integer
  253. ''' <summary>
  254. ''' Gets or sets the time out for initializing the TSP system.
  255. ''' </summary>
  256. Public Property SystemInitTimeout() As Integer Implements ITspInstrument.SystemInitTimeout
  257. Get
  258. Return Me._systemInitTimeout
  259. End Get
  260. Set(ByVal Value As Integer)
  261. Me._systemInitTimeout = Value
  262. End Set
  263. End Property
  264. Public Function InitializeSystemState() As Boolean Implements Core.IInitializable.InitializeSystemState
  265. Try
  266. Me.StoreTimeout(Me._systemInitTimeout)
  267. Return True
  268. Catch
  269. Throw
  270. Finally
  271. Me.RestoreTimeout()
  272. End Try
  273. End Function
  274. Public Function InitializeSystemState(ByVal timeout As Integer) As Boolean Implements Core.IInitializable.InitializeSystemState
  275. Me._systemInitTimeout = timeout
  276. Return Me.InitializeSystemState
  277. End Function
  278. #End Region
  279. #Region " PROMPT HANDLING "
  280. ''' <summary>
  281. ''' Flushes the read buffer ignoring errors.
  282. ''' </summary>
  283. ''' <param name="reportUnderData">Specifies the condition for reporting unread data.</param>
  284. ''' <remarks></remarks>
  285. <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
  286. Private Sub _discardUnreadData(ByVal reportUnderData As Boolean)
  287. Try
  288. Me.StoreTimeout(1000)
  289. MyBase.DiscardUnreadData(10, 100, reportUnderData)
  290. Catch ex As Exception
  291. Me.OnMessageAvailable(TraceEventType.Verbose, "EXCEPTION occurred FLUSHING READ BUFFER",
  292. "Exception occurred flushing read buffer. Details: {0}. Ignored.", ex)
  293. Finally
  294. Me.RestoreTimeout()
  295. End Try
  296. End Sub
  297. Private _statusLatency As Integer
  298. ''' <summary>
  299. ''' Gets or sets the time to delay checking the instrument status. This allows the instrument
  300. ''' time to process a write command, return the status prompt and update the message and error available bits.
  301. ''' </summary>
  302. ''' <value></value>
  303. ''' <returns></returns>
  304. ''' <remarks></remarks>
  305. Public Property StatusLatency() As Integer
  306. Get
  307. Return Me._statusLatency
  308. End Get
  309. Set(ByVal value As Integer)
  310. Me._statusLatency = value
  311. End Set
  312. End Property
  313. Private _statusRepeatCount As Integer
  314. ''' <summary>
  315. ''' Gets or sets the number of time to check before returning status.
  316. ''' It seems that the instruments has some delay resetting the status that get cleared only after
  317. ''' repeated checks.
  318. ''' </summary>
  319. ''' <value></value>
  320. ''' <returns></returns>
  321. ''' <remarks></remarks>
  322. Public Property StatusRepeatCount() As Integer
  323. Get
  324. Return Me._statusRepeatCount
  325. End Get
  326. Set(ByVal value As Integer)
  327. Me._statusRepeatCount = value
  328. End Set
  329. End Property
  330. ''' <summary>Reads the device status data byte and returns True
  331. ''' if the message available bits were set.
  332. ''' Delays looking for the message status by the status latency to make sure
  333. ''' the instrument had enough time to process the previous command.
  334. ''' </summary>
  335. ''' <returns>True if the device has data in the queue
  336. ''' </returns>
  337. Public Overrides Function IsMessageAvailable() As Boolean
  338. ' wait for the instrument to process the previous command before checking the message status.
  339. If Me._statusLatency > 0 Then
  340. Threading.Thread.Sleep(Me._statusLatency)
  341. For i As Integer = 1 To Me.StatusRepeatCount
  342. MyBase.IsMessageAvailable()
  343. Next
  344. End If
  345. ' check if we have data in the queue
  346. Return MyBase.IsMessageAvailable
  347. End Function
  348. ''' <summary>
  349. ''' Flushes the read buffer.
  350. ''' </summary>
  351. ''' <remarks></remarks>
  352. <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
  353. Public Overloads Function DiscardUnreadData() As Boolean
  354. Dim synopsis As String = "Flushing read buffer"
  355. If Me.IsMessageAvailable Then
  356. Me.OnMessageAvailable(TraceEventType.Verbose, synopsis, "Instrument '{0}' flushing read buffer", Me.ResourceName)
  357. End If
  358. ' flush the input buffer in case the instrument has some left overs.
  359. Try
  360. Me.StoreTimeout(1000)
  361. MyBase.DiscardUnreadData(10, 100, True)
  362. Catch ex As Exception
  363. Me.OnMessageAvailable(TraceEventType.Error, "EXCEPTION occurred FLUSHING READ BUFFER.",
  364. "Exception occurred flushing read buffer. Details: {0}", ex)
  365. Finally
  366. Me.RestoreTimeout()
  367. End Try
  368. End Function
  369. ''' <summary>
  370. ''' Flushes the read buffer.
  371. ''' </summary>
  372. ''' <remarks></remarks>
  373. <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
  374. Public Sub DiscardUnsentData()
  375. Try
  376. Me.StoreTimeout(1000)
  377. Me.FlushWrite()
  378. Catch ex As Exception
  379. Me.OnMessageAvailable(TraceEventType.Error, "EXCEPTION occurred FLUSHING WRITE BUFFER",
  380. "Exception occurred flushing write buffer. Details: {0}", ex)
  381. Finally
  382. Me.RestoreTimeout()
  383. End Try
  384. End Sub
  385. ''' <summary>
  386. ''' Turns off prompts and errors. It seems that the new systems come with prompts and errors off when
  387. ''' the instrument is started or reset so this is not needed.
  388. ''' </summary>
  389. ''' <remarks></remarks>
  390. <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
  391. Public Sub TurnPromptsErrorsOff()
  392. Dim synopsis As String = "Turning Prompts Off"
  393. ' flush the input buffer in case the instrument has some left overs.
  394. Me._discardUnreadData(True)
  395. Try
  396. ' turn off prompt transmissions
  397. Me.OnMessageAvailable(TraceEventType.Verbose, synopsis, "Instrument '{0}' turning off automatic sending of prompt messages. Ignoring errors.", Me.ResourceName)
  398. Me.WriteLine(TspSyntax.ShowPromptsCommand(False))
  399. Catch ex As Exception
  400. Me.OnMessageAvailable(TraceEventType.Verbose, "EXCEPTION occurred TURNING OFF AUTOMATIC SENDING OF PROMPT MESSASGES",
  401. "Exception occurred turning off automatic sending of prompt messages. Details: {0}. Exception ignored.", ex)
  402. End Try
  403. ' flush again in case turning off prompts added stuff to the buffer.
  404. Me._discardUnreadData(True)
  405. Try
  406. ' turn off error transmissions
  407. Me.OnMessageAvailable(TraceEventType.Verbose, synopsis, "Instrument '{0}' turning off automatic sending of error messages. Ignoring errors.", Me.ResourceName)
  408. Me.WriteLine(TspSyntax.ShowErrorsCommand(False))
  409. Catch ex As Exception
  410. Me.OnMessageAvailable(TraceEventType.Verbose, synopsis,
  411. "Exception occurred turning off automatic sending of error messages. Details: {1}. Exception ignored.",
  412. Me.ResourceName, ex)
  413. End Try
  414. ' flush again in case turning off errors added stuff to the buffer.
  415. Me._discardUnreadData(True)
  416. ' flush visa and device errors
  417. ' Me.FlashVisaAndDeviceErrors(False, synopsis, "before or while turning off prompts and errors.")
  418. Me.ReportVisaDeviceOperationOkay(False, synopsis, "before or while turning off prompts and errors.")
  419. End Sub
  420. #End Region
  421. #Region " TSP: DISPLAY "
  422. ''' <summary>
  423. ''' Clears the display
  424. ''' </summary>
  425. ''' <returns></returns>
  426. ''' <remarks>
  427. ''' Sets teh display to the user mode.
  428. ''' </remarks>
  429. Public Function ClearDisplay() As Boolean Implements ITspInstrument.ClearDisplay
  430. Me._displayStatus = DisplayScreens.User
  431. If Not Me.IsDisplayExists Then
  432. Return True
  433. End If
  434. Me.WriteLine("display.clear()")
  435. Return Me.ReportVisaDeviceOperationOkay(False, "Clear Display", "clearing display")
  436. End Function
  437. ''' <summary>
  438. ''' Clears the display if not in measurement mode and set measurement mode.
  439. ''' </summary>
  440. ''' <returns></returns>
  441. ''' <remarks>
  442. ''' Sets the display to the user mode.
  443. ''' </remarks>
  444. Public Function ClearDisplayMeasurement() As Boolean
  445. If Me.IsDisplayExists Then
  446. If (Me._displayStatus And DisplayScreens.Measurement) = 0 Then
  447. Me.ClearDisplay()
  448. End If
  449. End If
  450. Me._displayStatus = DisplayScreens.Measurement
  451. Return MyBase.LastOperationOkay
  452. End Function
  453. ''' <summary>
  454. ''' Displays message on line one of the display.
  455. ''' </summary>
  456. Public Function DisplayLine(ByVal lineNumber As Integer, ByVal format As String, ByVal ParamArray args() As Object) As Boolean Implements ITspInstrument.DisplayLine
  457. Return Me.DisplayLine(lineNumber, String.Format(Globalization.CultureInfo.CurrentCulture, format, args))
  458. End Function
  459. ''' <summary>
  460. ''' Displays a message on the display.
  461. ''' </summary>
  462. ''' <param name="value"></param>
  463. ''' <returns></returns>
  464. ''' <remarks></remarks>
  465. Public Function DisplayLine(ByVal lineNumber As Integer, ByVal value As String) As Boolean Implements ITspInstrument.DisplayLine
  466. Me._displayStatus = DisplayScreens.User Or DisplayScreens.Custom
  467. If Not Me.IsDisplayExists Then
  468. Return True
  469. End If
  470. ' ignore empty strings.
  471. If String.IsNullOrEmpty(value) Then
  472. Return True
  473. End If
  474. Dim length As Integer = 20
  475. If lineNumber < 1 Then
  476. lineNumber = 1
  477. ElseIf lineNumber > 2 Then
  478. lineNumber = 2
  479. End If
  480. If lineNumber = 2 Then
  481. length = 33
  482. End If
  483. If Me.WriteLine("display.setcursor({0}, 1)", lineNumber) Then
  484. If value.Length < length Then
  485. value = value.PadRight(length)
  486. End If
  487. If Me.WriteLine("display.settext('{0}')", value) Then
  488. End If
  489. Else
  490. Return False
  491. End If
  492. Return Me.ReportVisaDeviceOperationOkay(False, "Display Line", "displaying line {0}.", lineNumber)
  493. End Function
  494. Private _displayStatus As DisplayScreens
  495. ''' <summary>
  496. ''' Gets the <see cref="DisplayScreens">display screen and status</see>.
  497. ''' </summary>
  498. ''' <remarks></remarks>
  499. Public ReadOnly Property DisplayScreen() As DisplayScreens
  500. Get
  501. Return Me._displayStatus
  502. End Get
  503. End Property
  504. ''' <summary>
  505. ''' Displays the program title.
  506. ''' </summary>
  507. ''' <param name="title">Top row data.</param>
  508. ''' <param name="subtitle">Bottom row data.</param>
  509. ''' <returns></returns>
  510. ''' <remarks></remarks>
  511. Public Function DisplayTitle(ByVal title As String, ByVal subtitle As String) As Boolean
  512. If Not Me.DisplayLine(0, title) Then
  513. Me._displayStatus = DisplayScreens.User Or DisplayScreens.Title
  514. Return False
  515. End If
  516. If Not Me.DisplayLine(2, subtitle) Then
  517. Me._displayStatus = DisplayScreens.User Or DisplayScreens.Title
  518. Return False
  519. End If
  520. Return True
  521. End Function
  522. Private _isDisplayExists As Boolean?
  523. ''' <summary>
  524. ''' Gets the display existence indicator. Some TSP instruments (e.g., 3706) may have no display.
  525. ''' </summary>
  526. ''' <value></value>
  527. ''' <returns></returns>
  528. ''' <remarks></remarks>
  529. Public ReadOnly Property IsDisplayExists() As Boolean Implements ITspInstrument.IsDisplayExists
  530. Get
  531. If Not Me._isDisplayExists.HasValue Then
  532. Try
  533. ' detect the display
  534. Me._isDisplayExists = Not Me.IsNil("display")
  535. Catch ex As isr.Visa.BaseException
  536. ' throw an exception
  537. Me.OnMessageAvailable(TraceEventType.Error, "EXCEPTION OCCURRED CHECKING DISPLAY EXISTANCE.",
  538. "Exception occurred checking display existence. Details: {0}", ex)
  539. Me._isDisplayExists = False
  540. Finally
  541. End Try
  542. End If
  543. Return Me._isDisplayExists.Value
  544. End Get
  545. End Property
  546. ''' <summary>
  547. ''' Restores the instrument display to its main mode.
  548. ''' </summary>
  549. ''' <returns></returns>
  550. ''' <remarks></remarks>
  551. Public Function RestoreDisplay() As Boolean Implements ITspInstrument.RestoreDisplay
  552. Me._displayStatus = DisplayScreens.Default
  553. If Not Me.IsDisplayExists Then
  554. Return True
  555. End If
  556. ' Documentation error: Display Main equals 1, not 0. This code should work on
  557. ' other instruments.
  558. Me.WriteLine("display.screen = display.MAIN or 0")
  559. Return Me.ReportVisaDeviceOperationOkay(False, "Restore Display", "restoring display")
  560. End Function
  561. #End Region
  562. #Region " TSP: ERRORS "
  563. Private _showErrors As Nullable(Of Boolean)
  564. ''' <summary>Gets the condition for showing errors.
  565. ''' </summary>
  566. Public ReadOnly Property ShowErrors() As Nullable(Of Boolean) Implements ITspInstrument.ShowErrors
  567. Get
  568. Return Me._showErrors
  569. End Get
  570. End Property
  571. ''' <summary>Returns the condition for showing errors.
  572. ''' When true, the unit will automatically display the errors stored in the
  573. ''' error queue, and then clear the queue. Errors will be processed at the
  574. ''' end of executing a command message (just prior to issuing a prompt if
  575. ''' prompts are enabled).
  576. ''' When false, errors will not display. Errors will be left in the error
  577. ''' queue and must be explicitly read or cleared. The error prompt (TSP?)
  578. ''' is enabled.
  579. ''' </summary>
  580. ''' <param name="access"></param>
  581. ''' <returns></returns>
  582. ''' <remarks></remarks>
  583. Public Function ShowErrorsGetter(ByVal access As isr.Visa.ResourceAccessLevels) As Boolean Implements ITspInstrument.ShowErrorsGetter
  584. If (access = Visa.ResourceAccessLevels.Device) OrElse Not Me._showErrors.HasValue Then
  585. If Me.WriteQueryLine(TspSyntax.ShowErrorsQueryCommand) Then
  586. If Me.RaiseVisaOrDeviceException("failed getting error prompts status") Then
  587. Me._showErrors = 1 = Me.ReadInt32().Value
  588. End If
  589. End If
  590. Me.RaiseVisaOrDeviceException("failed getting error prompts status")
  591. End If
  592. Return Me._showErrors.Value
  593. End Function
  594. ''' <summary>Sets the condition for showing errors.
  595. ''' When true, the unit will automatically display the errors stored in the
  596. ''' error queue, and then clear the queue. Errors will be processed at the
  597. ''' end of executing a command message (just prior to issuing a prompt if
  598. ''' prompts are enabled).
  599. ''' When false, errors will not display. Errors will be left in the error
  600. ''' queue and must be explicitly read or cleared. The error prompt (TSP?)
  601. ''' is enabled.
  602. ''' </summary>
  603. ''' <param name="access"></param>
  604. ''' <param name="value"></param>
  605. ''' <returns></returns>
  606. ''' <remarks></remarks>
  607. Public Function ShowErrorsSetter(ByVal value As Boolean, ByVal access As isr.Visa.ResourceAccessLevels) As Boolean Implements ITspInstrument.ShowErrorsSetter
  608. If (access = Visa.ResourceAccessLevels.Device) OrElse (Not Me._showErrors.HasValue) OrElse (value <> showErrors.Value) Then
  609. ' now send the command. This will also update the status.
  610. If Me.WriteLine(TspSyntax.ShowErrorsCommand(value)) Then
  611. Me._showErrors = value
  612. End If
  613. Me.RaiseVisaOrDeviceException("failed setting error prompts status to {0}", value)
  614. End If
  615. Return Me._showErrors.Value
  616. End Function
  617. #End Region
  618. #Region " TSP: GLOBAL "
  619. ''' <summary>
  620. ''' Sends a collect garbage command.
  621. ''' </summary>
  622. Public Function CollectGarbage() As Boolean Implements ITspInstrument.CollectGarbage
  623. ' send the message
  624. Return Me.WriteLine(TspSyntax.CollectGarbageCommand)
  625. End Function
  626. ''' <summary>
  627. ''' Collects garbage on the specified node.
  628. ''' </summary>
  629. ''' <param name="nodeNumber">Specifies the node number.</param>
  630. ''' <returns></returns>
  631. ''' <remarks></remarks>
  632. Public Function CollectGarbage(ByVal nodeNumber As Integer) As Boolean Implements ITspInstrument.CollectGarbage
  633. ' send the message
  634. Return Me.WriteLine(TspSyntax.CollectNodeGarbage, nodeNumber)
  635. End Function
  636. #End Region
  637. #Region " TSP: NODE "
  638. ''' <summary>
  639. ''' Gets the error count on a remote node.
  640. ''' </summary>
  641. ''' <param name="nodeNumber"></param>
  642. ''' <returns></returns>
  643. ''' <remarks></remarks>
  644. Public Overloads Function ErrorQueueCount(ByVal nodeNumber As Integer) As Integer
  645. If nodeNumber <= 1 Then
  646. Return MyBase.ErrorQueueCount(Visa.ResourceAccessLevels.Device)
  647. Else
  648. Dim count As Integer? = Me.QueryInt32("print(string.format('%d',node[{0}].errorqueue.count)) waitcomplete()", nodeNumber)
  649. If Me.ReportVisaOperationOkay("Fetch error queue count", "Failed fetching error queue count from node {0}", nodeNumber) Then
  650. Return count.Value
  651. Else
  652. Return 0
  653. End If
  654. End If
  655. End Function
  656. ''' <summary>
  657. ''' Fetches the error queue.
  658. ''' </summary>
  659. ''' <param name="nodeNumber"></param>
  660. ''' <returns></returns>
  661. ''' <remarks>Error messages are formatted as follows:<para>
  662. ''' Error #,message,level=#.</para>
  663. ''' <list type="bullet">
  664. ''' <listheader><description>Error levels are:</description>
  665. ''' </listheader>
  666. ''' <item><description>0 - Informational.</description></item>
  667. ''' <item><description>10 - Informational.</description></item>
  668. ''' <item><description>30 - Serious.</description></item>
  669. ''' <item><description>40 - Critical.</description></item>
  670. ''' </list>
  671. ''' </remarks>
  672. Public Function DequeueErrorQueue(ByVal nodeNumber As Integer) As String
  673. If nodeNumber <= 1 Then
  674. Return MyBase.ErrorQueue(Visa.ResourceAccessLevels.Device)
  675. Else
  676. Dim errors As New System.Text.StringBuilder(2048)
  677. Do While Me.ErrorQueueCount(nodeNumber) > 0
  678. Dim message As String = Me.QueryPrintFormat(String.Format(Globalization.CultureInfo.CurrentCulture,
  679. "error %d,%s,level=%d,node{0}", nodeNumber),
  680. String.Format(Globalization.CultureInfo.CurrentCulture,
  681. "node[{0}].errorqueue.next()", nodeNumber))
  682. If Me.ReportVisaDeviceOperationOkay(True, "dequeue node error", "failed dequeuing errors from node {0}", nodeNumber) Then
  683. errors.AppendFormat(Globalization.CultureInfo.CurrentCulture,
  684. "{0},node={1}", message, nodeNumber)
  685. errors.AppendLine()
  686. Else
  687. errors.AppendFormat(Globalization.CultureInfo.CurrentCulture,
  688. "Error occurred fetching error queue element from node {0}", nodeNumber)
  689. errors.AppendLine()
  690. Return errors.ToString
  691. End If
  692. Loop
  693. Return errors.ToString
  694. End If
  695. End Function
  696. ''' <summary>
  697. ''' Dequeues errors on all nodes.
  698. ''' </summary>
  699. ''' <returns></returns>
  700. ''' <remarks></remarks>
  701. Public Function DequeueErrorQueue() As String
  702. Dim builder As New isr.Core.MyStringBuilder
  703. For Each node As NodeEntity In Me._nodeEntities
  704. If Me.ErrorQueueCount(node.Number) > 0 Then
  705. Dim errors As String = Me.DequeueErrorQueue(node.Number)
  706. If Not String.IsNullOrEmpty(errors) Then
  707. builder.AppendLine("Node #{0} errors: {1}", node.Number, errors)
  708. End If
  709. End If
  710. Next
  711. Return builder.ToString
  712. End Function
  713. ''' <summary>
  714. ''' Reports if a device error occurred as set the <see cref="LastOperationOkay">success condition</see>
  715. ''' Can only be used after receiving a full reply from the instrument.
  716. ''' </summary>
  717. ''' <param name="nodeNumber">Specifies the node number.</param>
  718. ''' <param name="synopsis">Specifies a synopsis for the warning if an error occurred.</param>
  719. ''' <param name="format">Specifies the report format.</param>
  720. ''' <param name="args">Specifies the report arguments.</param>
  721. ''' <returns>True if success</returns>
  722. ''' <remarks></remarks>
  723. Public Function ReportDeviceOperationOkay(ByVal nodeNumber As Integer, ByVal synopsis As String,
  724. ByVal format As String, ByVal ParamArray args() As Object) As Boolean Implements ITspInstrument.ReportDeviceOperationOkay
  725. MyBase.ReportVisaDeviceOperationOkay(False, synopsis, format, args)
  726. If nodeNumber > 1 AndAlso Me.ErrorQueueCount(nodeNumber) > 0 Then
  727. Me.LastOperationOkay = False
  728. Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{1}' encountered errors {0}. Details:{3}{2}{3}{4}",
  729. String.Format(Globalization.CultureInfo.CurrentCulture, format, args),
  730. Me.ResourceName,
  731. Me.DequeueErrorQueue(nodeNumber),
  732. Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
  733. End If
  734. Return Me.LastOperationOkay
  735. End Function
  736. ''' <summary>
  737. ''' Makes a script nil and returns true if the script was nilified.
  738. ''' Does not check if the script exists.
  739. ''' </summary>
  740. ''' <param name="nodeNumber">Specifies the remote node number.</param>
  741. ''' <param name="name">Specifies the script name</param>
  742. ''' <returns></returns>
  743. ''' <remarks>Assumes the script is known to exist.
  744. ''' Waits till completion.
  745. ''' </remarks>
  746. Private Function _nilifyScript(ByVal nodeNumber As Integer, ByVal name As String) As Boolean
  747. If String.IsNullOrEmpty(name) Then
  748. Return False
  749. End If
  750. Dim synopsis As String = "Nullifying Script"
  751. ' ignore errors as failure is handled below.
  752. Me.ExecuteCommandWaitComplete(nodeNumber, Me._nilifyTimeout, False, "{0} = nil", name)
  753. ' allow the next command to create an error if wait complete times out.
  754. If Me.IsNil(nodeNumber, name) Then
  755. Return True
  756. Else
  757. Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' script {1} still exists on node {2} after nil.{3}{4}",
  758. Me.ResourceName, name, nodeNumber,
  759. Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
  760. Return False
  761. End If
  762. End Function
  763. ''' <summary>
  764. ''' Makes a script nil and returns true if the script was nullified.
  765. ''' </summary>
  766. ''' <param name="nodeNumber">Specifies the remote node number.</param>
  767. ''' <param name="name">Specifies the script name</param>
  768. ''' <returns></returns>
  769. ''' <remarks></remarks>
  770. Public Function NilifyScript(ByVal nodeNumber As Integer, ByVal name As String) As Boolean Implements ITspInstrument.NilifyScript
  771. If String.IsNullOrEmpty(name) Then
  772. Return False
  773. End If
  774. If Me.IsNil(nodeNumber, name) Then
  775. Return True
  776. Else
  777. Return Me._nilifyScript(nodeNumber, name)
  778. End If
  779. End Function
  780. ''' <summary>
  781. ''' Sets the connect rule on the specified node.
  782. ''' </summary>
  783. ''' <param name="nodeNumber">Specifies the remote node number.</param>
  784. ''' <param name="value"></param>
  785. ''' <returns></returns>
  786. ''' <remarks></remarks>
  787. Public Function ConnectRuleSetter(ByVal nodeNumber As Integer, ByVal value As Integer) As Boolean Implements ITspInstrument.ConnectRuleSetter
  788. Return Me.WriteLine(TspSyntax.ConnectRuleSetter, nodeNumber, value)
  789. End Function
  790. ''' <summary>
  791. ''' Deletes the <paramref name="name">specified</paramref> script.
  792. ''' Also nilifies the script if delete command worked.
  793. ''' </summary>
  794. ''' <param name="nodeNumber">Specifies the remote node number.</param>
  795. ''' <param name="name">Specifies the script name</param>
  796. ''' <returns></returns>
  797. ''' <remarks></remarks>
  798. Public Function DeleteScript(ByVal nodeNumber As Integer, ByVal name As String, ByVal refreshScriptCatalog As Boolean) As Boolean Implements ITspInstrument.DeleteScript
  799. If String.IsNullOrEmpty(name) Then
  800. Return False
  801. End If
  802. If Me.SavedScriptExists(nodeNumber, name, refreshScriptCatalog) Then
  803. Return Me.DeleteSavedScript(nodeNumber, name)
  804. Else
  805. Return Me.NilifyScript(nodeNumber, name)
  806. End If
  807. End Function
  808. ''' <summary>
  809. ''' Deletes the <paramref name="name">specified</paramref> script.
  810. ''' Also nilifies the script if delete command worked.
  811. ''' </summary>
  812. ''' <param name="node">Specifies the node.</param>
  813. ''' <param name="name">Specifies the script name</param>
  814. ''' <returns></returns>
  815. ''' <remarks></remarks>
  816. Public Function DeleteScript(ByVal node As INodeEntity, ByVal name As String, ByVal refreshScriptCatalog As Boolean) As Boolean
  817. If node Is Nothing Then
  818. Throw New ArgumentNullException("node")
  819. End If
  820. If String.IsNullOrEmpty(name) Then
  821. Return False
  822. End If
  823. If node.IsController Then
  824. Return DeleteScript(name, refreshScriptCatalog)
  825. Else
  826. Return DeleteScript(node.Number, name, refreshScriptCatalog)
  827. End If
  828. End Function
  829. ''' <summary>
  830. ''' Deletes the <paramref name="name">specified</paramref> saved script.
  831. ''' Also nilifies the script if delete command worked.
  832. ''' Then checks if the script was deleted and if so returns true.
  833. ''' Otherwise, returns false.
  834. ''' </summary>
  835. ''' <param name="nodeNumber">Specifies the remote node number.</param>
  836. ''' <param name="name">Specifies the script name</param>
  837. ''' <returns></returns>
  838. ''' <remarks>Presumes the saved script exists.
  839. ''' Waits for operation completion.
  840. ''' </remarks>
  841. Public Function DeleteSavedScript(ByVal nodeNumber As Integer, ByVal name As String) As Boolean
  842. If String.IsNullOrEmpty(name) Then
  843. Return False
  844. End If
  845. Dim synopsis As String = "Deleting Saved Script"
  846. ' failure is handled below.
  847. Me.ExecuteCommandWaitComplete(nodeNumber, Me.DeleteTimeout, False, "script.delete('{0}')", name)
  848. ' make script nil
  849. If Me.NilifyScript(nodeNumber, name) Then
  850. ' make sure to re-check that script is gone.
  851. If Me.SavedScriptExists(nodeNumber, name, True) Then
  852. Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' saved script {1} still exists after nil on node {2}{3}{4}",
  853. Me.ResourceName, name, nodeNumber,
  854. Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
  855. Return False
  856. Else
  857. Return True
  858. End If
  859. Else
  860. Return False
  861. End If
  862. End Function
  863. ''' <summary>
  864. ''' Deletes the <paramref name="name">specified</paramref> saved script.
  865. ''' Also nilifies the script if delete command worked.
  866. ''' Returns true if the script was deleted.
  867. ''' </summary>
  868. ''' <param name="nodeNumber">Specifies the remote node number.</param>
  869. ''' <param name="name">Specifies the script name</param>
  870. ''' <returns></returns>
  871. ''' <remarks>
  872. ''' Waits for operation completion.
  873. ''' </remarks>
  874. Public Function DeleteSavedScript(ByVal nodeNumber As Integer, ByVal name As String, ByVal refreshScriptCatalog As Boolean) As Boolean Implements ITspInstrument.DeleteSavedScript
  875. If String.IsNullOrEmpty(name) Then
  876. Return False
  877. End If
  878. Dim synopsis As String = "Deleting Saved Script"
  879. If Me.SavedScriptExists(nodeNumber, name, refreshScriptCatalog) Then
  880. ' execute command but ignore errors as they are handled below.
  881. Me.ExecuteCommandWaitComplete(nodeNumber, Me.DeleteTimeout, False, "script.delete('{0}')", name)
  882. ' make script nil
  883. If Me.NilifyScript(nodeNumber, name) Then
  884. ' make sure to re-check that script is gone.
  885. If Me.SavedScriptExists(nodeNumber, name, True) Then
  886. Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' saved script {1} still exists after nil on node {2}{3}{4}",
  887. Me.ResourceName, name, nodeNumber,
  888. Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
  889. Return False
  890. Else
  891. Return True
  892. End If
  893. Else
  894. Return False
  895. End If
  896. Else
  897. Return True
  898. End If
  899. End Function
  900. ''' <summary>
  901. ''' Executes a command on the node.
  902. ''' </summary>
  903. ''' <param name="nodeNumber">Specifies the node number.</param>
  904. ''' <param name="isQuery">Specifies the condition indicating if the command is a query, which determines how errors are fetched.</param>
  905. ''' <param name="format">Specifies the command format.</param>
  906. ''' <param name="args">Specifies the command arguments.</param>
  907. ''' <returns></returns>
  908. ''' <remarks></remarks>
  909. Public Function ExecuteCommandWaitComplete(ByVal nodeNumber As Integer,
  910. ByVal timeout As Integer,
  911. ByVal isQuery As Boolean,
  912. ByVal format As String,
  913. ByVal ParamArray args() As Object) As Boolean
  914. Dim synopsis As String = "Execute node command"
  915. Dim command As String = String.Format(Globalization.CultureInfo.CurrentCulture, format, args)
  916. If Me.WriteLine(TspSyntax.ExecuteCommand, nodeNumber, command) Then
  917. IssueWaitComplete(0)
  918. Me.AwaitOperationCompleted(timeout, timeout \ 10 + 10)
  919. If isQuery Then
  920. If Not ReportVisaOperationOkay(synopsis, "executing '{0}' on node {1}", command, nodeNumber) Then
  921. Return False
  922. End If
  923. Else
  924. If Not ReportDeviceOperationOkay(nodeNumber, synopsis, "executing '{0}' on node {1}", command, nodeNumber) Then
  925. Return False
  926. End If
  927. End If
  928. Else
  929. Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' failed executing '{1}' on node {2}.{3}{4}",
  930. Me.ResourceName, command, nodeNumber,
  931. Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
  932. Return False
  933. End If
  934. Return True
  935. End Function
  936. ''' <summary>
  937. ''' Executes a command on the node.
  938. ''' </summary>
  939. ''' <param name="node">Specifies the node.</param>
  940. ''' <param name="isQuery">Specifies the condition indicating if the command is a query, which determines how errors are fetched.
  941. ''' While the remote command will not return values, the local node may.</param>
  942. ''' <param name="format">Specifies the command format.</param>
  943. ''' <param name="args">Specifies the command arguments.</param>
  944. ''' <returns></returns>
  945. ''' <remarks></remarks>
  946. Public Function ExecuteCommandWaitComplete(ByVal node As INodeEntity,
  947. ByVal timeout As Integer,
  948. ByVal isQuery As Boolean,
  949. ByVal format As String,
  950. ByVal ParamArray args() As Object) As Boolean
  951. If node Is Nothing Then
  952. Throw New ArgumentNullException("node")
  953. End If
  954. If node.IsController Then
  955. Dim synopsis As String = "Execute node command"
  956. Dim command As String = String.Format(Globalization.CultureInfo.CurrentCulture, format, args)
  957. If Me.WriteLine(format, args) Then
  958. IssueWaitComplete(0)
  959. Me.AwaitOperationCompleted(timeout, timeout \ 10 + 10)
  960. If isQuery Then
  961. If Not ReportVisaOperationOkay(synopsis, "executing '{0}' on node {1}", command, node.Number) Then
  962. Return False
  963. End If
  964. Else
  965. If Not ReportDeviceOperationOkay(node.Number, synopsis, "executing '{0}' on node {1}", command, node.Number) Then
  966. Return False
  967. End If
  968. End If
  969. Else
  970. Me.OnMessageAvailable(TraceEventType.Warning, synopsis, "Instrument '{0}' failed executing '{1}' on node {2}.{3}{4}",
  971. Me.ResourceName, command, node.Number,
  972. Environment.NewLine, isr.Core.StackTraceParser.UserCallStack(4, 8))
  973. Return False
  974. End If
  975. Return True
  976. Else
  977. Return Me.ExecuteCommandWaitComplete(node.Number, timeout, isQuery, format, args)
  978. End If
  979. End Function
  980. ''' <summary>
  981. ''' Executes a command on the remote node. This leaves an item in the input buffer that must be retried.
  982. ''' </summary>
  983. ''' <param name="nodeNumber">Specifies the remote node number.</param>
  984. ''' <param name="format">Specifies the command format.</param>
  985. ''' <param name="args">Specifies the command arguments.</param>
  986. ''' <returns></returns>
  987. ''' <remarks></remarks>
  988. Public Function ExecuteValueGetter(ByVal nodeNumber As Integer, ByVal format As String, ByVal ParamArray args() As Object) As Boolean Implements ITspInstrument.ExecuteValueGetter
  989. If String.IsNullOrEmpty(format) Then
  990. Throw New ArgumentNullException("format")
  991. Else
  992. Return Me.WriteLine(TspSyntax.ValueGetterCommand1, nodeNumber,
  993. String.Format(Globalization.CultureInfo.CurrentCulture, format, args))
  994. End If
  995. Return False
  996. End Function
  997. Private _lastFetchedSavedRemoteScripts As String
  998. ''' <summary>
  999. ''' Gets a comma-separated and comma-terminated list of the saved scripts
  1000. ''' that was fetched last from the remote node. A new script is fetched after save and delete.
  1001. ''' </summary>
  1002. ''' <value></value>
  1003. ''' <returns></returns>
  1004. ''' <remarks></remarks>
  1005. Public ReadOnly Property LastFetchedSavedRemoteScripts() As String Implements ITspInstrument.LastFetchedSavedRemoteScripts
  1006. Get
  1007. Return Me._lastFetchedSavedRemoteScripts
  1008. End Get
  1009. End Property
  1010. ''' <summary>
  1011. ''' Fetches the list of saved scripts and saves it in the <see cref="LastFetchedSavedScripts"></see>
  1012. ''' </summary>
  1013. ''' <returns></returns>
  1014. ''' <remarks></remarks>
  1015. <CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")>
  1016. Public Function FetchSavedScripts(ByVal nodeNumber As Integer) As Boolean Implements ITspInstrument.FetchSavedScripts
  1017. Dim synopsis As String = "Fetch Saved Scripts"
  1018. Try
  1019. Me.StoreTimeout(Me._saveTimeout)
  1020. Me._lastFetchedSavedRemoteScripts = ""
  1021. If Me.WriteQueryLine(TspSyntax.ValueGetterCommand2, nodeNumber, TspSyntax.ScriptCatalogGetterCommand, "names") Then
  1022. If Me.ReportVisaDeviceOperationOkay(True, "Fetch Node Saved Scripts", "Failed fetching catalog from node {0}", nodeNumber) Then
  1023. Me._lastFetchedSavedRemoteScripts = Me.ReadLineTrimEnd
  1024. Else
  1025. Return False
  1026. End If
  1027. If String.IsNullOrEmpty(Me._lastFetchedSavedRemoteScripts) Then
  1028. Me._lastFetchedSavedRemoteScripts = ""
  1029. End If
  1030. End If
  1031. Return ReportDeviceOperationOkay(nodeNumber, synopsis, "Failed fetching catalog from node {0}", nodeNumber)
  1032. Catch
  1033. Throw
  1034. Finally
  1035. MyBase.RestoreTimeout()
  1036. End Try
  1037. End

Large files files are truncated, but you can click here to view the full file