Option Explicit On
Imports System.Text

Public Class frmMain
  Private hChannel As Integer = HartDLL_Iface.INVALID_DRV_HANDLE
  Private hService As Integer = HartDLL_Iface.INVALID_SRV_HANDLE
  Private strConfiguration As HartDLL_Iface.T_strConfiguration
  Private strConnection As HartDLL_Iface.T_strConnection
  Private strConfirmation As HartDLL_Iface.T_strConfirmation
  Private strDataBuffer As HartDLL_Iface.T_strDataBuffer
  Private iActualComPort As Integer = 0
  Private bConnected As Boolean = False
  Private bConnectionFailed = False
  Private bComPortValid As Boolean = False
  Private byLastError As Byte



#Region "Event Procedures"
  Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim n As Integer

    'Allocate memory for unmanaged arrays
    ReDim strConnection.abyUniqueID(5) 'Size must match SizeConst!
    ReDim strConfirmation.aby_Data(64) 'Size must match SizeConst!
    ReDim strDataBuffer.aby_Data(64) 'Size must match SizeConst!
    'Initialize Combo Box
    cmbComPort.Items.Add("None")
    For n = 1 To 254
      cmbComPort.Items.Add("COM" + n.ToString())
    Next
    cmbComPort.SelectedIndex = 0
    SetLastError()
  End Sub

  Private Sub frmMain_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
    If hChannel <> HartDLL_Iface.INVALID_DRV_HANDLE Then
      HartDLL_Iface.BHDrv_CloseChannel(hChannel)
    End If
  End Sub

  Private Sub butExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butExit.Click
    Me.Close()
  End Sub

  Private Sub cmbComPort_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbComPort.SelectedIndexChanged
    SelectComPort(cmbComPort.SelectedIndex)
  End Sub

  Private Sub butConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butConnect.Click
    bConnectionFailed = False
    hService = HartDLL_Iface.BHDrv_ConnectByAddr(hChannel, _
                                                                       0, _
                                                  HartDLL_Iface.DRV_WAIT, _
                                                                       0)
    If hService <> HartDLL_Iface.INVALID_SRV_HANDLE Then
      HartDLL_Iface.BHDrv_FetchConnection(hService, strConnection)
      byLastError = strConnection.byError
      If byLastError = HartDLL_Iface.SRV_SUCCESSFUL Then
        SetConnected()
      Else
        SetNotConnected()
        bConnectionFailed = True
      End If
    Else
      byLastError = 255 'Unknown
    End If
    SetLastError()
  End Sub

  Private Sub butGetTag_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butGetTag.Click
    Dim sb As StringBuilder = New StringBuilder(8)

    txtLastError.Text = "..."
    txtLastError.Refresh()
    txtTagName.Text = "..."
    txtTagName.Refresh()
    DisableControls()
    hService = HartDLL_Iface.BHDrv_DoCommand(hChannel, 13, HartDLL_Iface.DRV_WAIT, strDataBuffer.aby_Data(0), 0, 1234, strConnection.abyUniqueID(0))
    If hService <> HartDLL_Iface.INVALID_SRV_HANDLE Then
      HartDLL_Iface.BHDrv_FetchConfirmation(hService, strConfirmation)
      byLastError = strConfirmation.byError
      If byLastError = HartDLL_Iface.SRV_SUCCESSFUL Then
        'Get the tag name
         HartDLL_Iface.BHDrv_PickPackedASCII(sb, 8, 0, strConfirmation.aby_Data(0))
         txtTagName.Text = sb.ToString()
      Else
        txtTagName.Text = "-/-"
      End If
    Else
      byLastError = 255 'Unknown
    End If
    SetLastError()
    EnableControls()
  End Sub

  Private Sub butGetPV_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butGetPV.Click
    txtLastError.Text = "..."
    txtLastError.Refresh()
    txtPV.Text = "..."
    txtPV.Refresh()
    DisableControls()
    hService = HartDLL_Iface.BHDrv_DoCommand(hChannel, 1, HartDLL_Iface.DRV_WAIT, strDataBuffer.aby_Data(0), 0, 1234, strConnection.abyUniqueID(0))
    If hService <> HartDLL_Iface.INVALID_SRV_HANDLE Then
      HartDLL_Iface.BHDrv_FetchConfirmation(hService, strConfirmation)
      byLastError = strConfirmation.byError
      If byLastError = HartDLL_Iface.SRV_SUCCESSFUL Then
        'Get the tag name
         txtPV.Text = HartDLL_Iface.BHDrv_PickFloat(1, strConfirmation.aby_Data(0), HartDLL_Iface.MSB_FIRST).ToString("###0.0###")
      Else
        txtPV.Text = "-/-"
      End If
    Else
      byLastError = 255 'Unknown
    End If
    SetLastError()
    EnableControls()
  End Sub

  Private Sub butWriteTagName_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butWriteTagName.Click
    Dim sb As StringBuilder = New StringBuilder(8)

    txtLastError.Text = "..."
    txtLastError.Refresh()
    txtTagName.Text = "..."
    txtTagName.Refresh()
    DisableControls()

    'Read Tag, Descriptor, Date
    hService = HartDLL_Iface.BHDrv_DoCommand(hChannel, 13, HartDLL_Iface.DRV_WAIT, strDataBuffer.aby_Data(0), 0, 1234, strConnection.abyUniqueID(0))
    If hService = HartDLL_Iface.INVALID_SRV_HANDLE Then
      byLastError = 255 'Unknown
      SetLastError()
      EnableControls()
      Exit Sub
    End If
    'Fetch result into buffer
    HartDLL_Iface.BHDrv_FetchConfirmation(hService, strConfirmation)
    byLastError = strConfirmation.byError
    If byLastError <> HartDLL_Iface.SRV_SUCCESSFUL Then
      SetLastError()
      EnableControls()
      Exit Sub
    End If
    'Indicate activity
    txtLastError.Text = "...."
    txtLastError.Refresh()
    txtTagName.Text = "...."
    txtTagName.Refresh()
    'Insert the new tag name
    sb.Insert(0, txtNewTagName.Text.ToUpper())
    If txtTagName.Text.Length < 8 Then
      sb.Append(" ", 8 - txtTagName.Text.Length)
    End If
    'Copy Confirmation Buffer to DataBuffer
    'This would be not necessary here but should show how to cope with the raw data
    strDataBuffer.aby_Data = strConfirmation.aby_Data
    'Store Tag Name to the buffer
    HartDLL_Iface.BHDrv_PutPackedASCII(sb, 8, 0, strDataBuffer.aby_Data(0))
    'Write Tag Descriptor Date
    hService = HartDLL_Iface.BHDrv_DoCommand(hChannel, 18, HartDLL_Iface.DRV_WAIT, strDataBuffer.aby_Data(0), 21, 4321, strConnection.abyUniqueID(0))
    If hService = HartDLL_Iface.INVALID_SRV_HANDLE Then
      byLastError = 255 'Unknown
      SetLastError()
      EnableControls()
      txtTagName.Text = "-/-"
      Exit Sub
    End If
    HartDLL_Iface.BHDrv_FetchConfirmation(hService, strConfirmation)
    byLastError = strConfirmation.byError
    If byLastError = HartDLL_Iface.SRV_SUCCESSFUL Then
      'Get the tag name
       HartDLL_Iface.BHDrv_PickPackedASCII(sb, 8, 0, strConfirmation.aby_Data(0))
       txtTagName.Text = sb.ToString()
    Else
      txtTagName.Text = "-/-"
    End If
    SetLastError()
    EnableControls()
  End Sub
#End Region

#Region "Helpers"
  Private Sub SelectComPort(ByVal iComPort As Integer)
    If iComPort = iActualComPort Then
      Exit Sub
    End If
    SetNotConnected()
    bConnectionFailed = False
    iActualComPort = iComPort
    'Close channel if it was open
    If hChannel <> HartDLL_Iface.INVALID_DRV_HANDLE Then
      HartDLL_Iface.BHDrv_CloseChannel(hChannel)
      hChannel = HartDLL_Iface.INVALID_DRV_HANDLE
    End If
    If iComPort = 0 Then
      SetLastError()
      Exit Sub
    End If
    hChannel = HartDLL_Iface.BHDrv_OpenChannel(iComPort)
    If hChannel <> HartDLL_Iface.INVALID_DRV_HANDLE Then
      bComPortValid = True
      butConnect.Enabled = True
      'Set the desired confuguration
      HartDLL_Iface.BHDrv_GetConfiguration(hChannel, strConfiguration)
      strConfiguration.byNumRetries = 0
      strConfiguration.byRetryIfBusy = 1
      HartDLL_Iface.BHDrv_SetConfiguration(hChannel, strConfiguration)
      SetLastError()
    Else
      butConnect.Enabled = False
      bComPortValid = False
      SetLastError()
    End If
  End Sub

  Private Sub SetConnected()
    grpReadDeviceData.Enabled = True
    grpWriteDeviceData.Enabled = True
    bConnected = True
  End Sub

  Private Sub SetNotConnected()
    grpReadDeviceData.Enabled = False
    grpWriteDeviceData.Enabled = False
    txtTagName.Text = "-/-"
    txtPV.Text = "-/-"
    bConnected = False
  End Sub

  Private Sub SetLastError()
    If cmbComPort.SelectedIndex = 0 Then
      txtLastError.Text = "No Port Selected"
      Exit Sub
    End If
    If bComPortValid <> True Then
      txtLastError.Text = "Invalid Port!"
      Exit Sub
    End If
    If bConnectionFailed = True Then
      txtLastError.Text = "Connection Failed!"
      Exit Sub
    End If
    If bConnected <> True Then
      txtLastError.Text = "Not Connected"
      Exit Sub
    End If
    Select Case byLastError
      Case HartDLL_Iface.SRV_SUCCESSFUL
        txtLastError.Text = "Success"
        Exit Sub
      Case HartDLL_Iface.SRV_NO_DEV_RESP
        txtLastError.Text = "No Device Response"
        Exit Sub
      Case HartDLL_Iface.SRV_INVALID_HANDLE
        txtLastError.Text = "Invalid Handle"
        Exit Sub
      Case HartDLL_Iface.SRV_IN_PROGRESS
        txtLastError.Text = "Service in Progress"
        Exit Sub
      Case HartDLL_Iface.SRV_EMPTY
        txtLastError.Text = "Service Empty"
        Exit Sub
      Case HartDLL_Iface.SRV_COMM_ERR
        txtLastError.Text = "Communication Error"
        Exit Sub
      Case Else
        txtLastError.Text = "Unknown Error"
        Exit Sub
    End Select
  End Sub

  Private Sub DisableControls()
    butConnect.Enabled = False
    butConnect.Refresh()
    butGetTag.Enabled = False
    butGetTag.Refresh()
    butGetPV.Enabled = False
    butGetPV.Refresh()
    butWriteTagName.Enabled = False
    butWriteTagName.Refresh()
  End Sub

  Private Sub EnableControls()
    butConnect.Enabled = True
    butGetTag.Enabled = True
    butGetPV.Enabled = True
    butWriteTagName.Enabled = True
  End Sub
#End Region

End Class
