Imports System.IO Imports System.Reflection.Emit Imports System.Threading Imports System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock Imports System.Text Imports FlexCell Imports Newtonsoft.Json Imports System.Data.Common Imports System.Data.SQLite Imports System.Net Public Class Form1 #Region "初始化" ''' ''' 项目加载事件 ''' ''' ''' Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load Me.Text += "(" & Application.ProductVersion & ")" If Not String.IsNullOrEmpty(My.Settings.SerialPortName) Then My.Settings.Reload() ComboBox8.Text = My.Settings.SerialPortName ToolStripTextBox1.Text = My.Settings.SInTime End If '将 和执行文件同目录的CommandSetDic.flx文件拷贝到 C盘C: \NT2406_Tool 下 '判断C: \NT2406_Tool 存不存在 If Not IO.Directory.Exists(FileCPatrh) Then IO.Directory.CreateDirectory(FileCPatrh) End If ' 判断文件是否存在($"{Application.StartupPath }\CommandSetDic.flx") If IO.File.Exists($"{Application.StartupPath }\CommandSetDic.flx") Then '判断文件是否存在 If IO.File.Exists($"{FileCPatrh}\CommandSetDic.flx") Then Else '文件拷贝到C: \NT2406_Tool 下 IO.File.Copy($"{Application.StartupPath }\CommandSetDic.flx", $"{FileCPatrh}\CommandSetDic.flx", True) End If Else MessageBox.Show("CommandSetDic.flx 文件损坏") Me.Close() End If '(FileCPatrh & "\CommandSetDic.flx" InitSerialPortBaud() Grid_Format_initial() Show_Device_Setinfo_Info() ClearDeviceform() InitGrid_table() InitLoadProcessTable() InitCommandSetDic() ToolStripButton2.PerformClick() Timer2.Start() End Sub #End Region #Region "串口通信" ''' ''' 当前时间 ''' Private _nowTime As Date ''' ''' 最后时间 ''' Private _lastTime As Date ''' ''' 时间间隔 ''' Private _timeInterbval As TimeSpan ''' ''' 接收数据偏移量 ''' Private _recvOffset As Integer ''' ''' 接收数据缓存包 ''' Private _recvBuffer(254) As Byte ''' ''' 串口波特率 ''' Private _baudItme() As String = {"4800", "9600", "14400", "19200", "38400", "56000", "57600", "115200", "256000", "512000", "600000", "750000"} Public DbConnString As String = "Server=blv-cloud-db.mysql.rds.aliyuncs.com;Port=3307;Database=blv_productionlinetest;Uid=blv_rcu;Pwd=fnadiaJDIJ7546;charset=utf8;" Enum TableEnum ID = 0 测试时间 测试结果 测试信息 RTC时间 RTC星期 校准结果 稳定消抖时间_秒 背景值滤波长度_秒 传感器极大值 传感器极小值 预热时间_分 ADC_LEV_10 ADC_LEV_0 触发_消抖次数 释放_消抖次数 稳定阈值 报警点提前量 校准超时_秒 校准最小值_LEV_0 校准最小值_LEV_10 校准最小值_差值 校准最大值_LEV_0 校准最大值_LEV_10 校准最大值_差值 泄露恢复正常_条件1 泄露恢复正常_条件2 泄露恢复正常_条件1消抖时间_秒 泄露恢复正常_条件2消抖时间_分 设备生产时间 软件版本号 硬件版本号 设备类型ID 厂牌ID 机型ID UUID 状态机 实时值 背景值 基底值 差值 LEL百分比 稳定状态 基底值差值百分比1 基底值差值百分比2 温度 服务器key 服务器ClientId 设备key 设备ClientId MAX End Enum '获取表格枚举值名称 Private Function GetTableEnumName(tableEnum As TableEnum) As String Return [Enum].GetName(GetType(TableEnum), tableEnum) End Function ''' ''' 初始化串口波特率 ''' Private Sub InitSerialPortBaud() ComboBox9.Items.Clear() ComboBox9.Items.AddRange(_baudItme) If ComboBox9.Items.Count > 1 Then ComboBox9.SelectedIndex = 0 End Sub ''' ''' 选择串口 ''' ''' ''' Private Sub ComboBox8_DropDown(sender As Object, e As EventArgs) Handles ComboBox8.DropDown GetSerialPort() End Sub ''' ''' 串口通信 ''' ''' ''' Private Sub Button19_Click(sender As Object, e As EventArgs) Handles Button19.Click ' RichTextBox1.Text = Application.ProductName If String.IsNullOrWhiteSpace(ComboBox8.Text) Then MsgBox($"请先选择有效串口!") Exit Sub End If If String.IsNullOrWhiteSpace(ComboBox9.Text) Then MsgBox($"请先选择有效波特率!") Exit Sub End If SerialPortCommSwitch(ComboBox8.Text, ComboBox9.Text) End Sub ''' ''' 获取可用串口 ''' Private Sub GetSerialPort() Dim portNames As String() = Ports.SerialPort.GetPortNames '获得可用串口 Array.Sort(portNames) ComboBox8.Items.Clear() ComboBox8.Items.AddRange(portNames) End Sub ''' ''' 串口通讯开关 ''' ''' ''' Private Sub SerialPortCommSwitch(portName As String, portBaud As String) If SerialPort.IsOpen Then SerialPort.Close() CloseSerialPort() Else ConfigSerialPort(portName, portBaud) Try SerialPort.Open() OpenSerialPort() Catch ex As Exception 'Console.WriteLine($"串口打开失败,原因:{ex.Message}" & vbCrLf, Color.Red) MsgBox($"串口打开失败,原因:{ex.Message}") SerialPort.Close() CloseSerialPort() End Try End If End Sub ''' ''' 关闭串口 ''' Private Sub CloseSerialPort() ComboBox8.Enabled = True ComboBox9.Enabled = True Button19.Text = $"打开串口" Button19.ForeColor = Color.Green End Sub ''' ''' 配置串口 ''' ''' 串口名 ''' 串口波特率 Public Sub ConfigSerialPort(portName As String, portBaud As String) With SerialPort .PortName = portName '串口名 .BaudRate = CInt(portBaud) '波特率 .DataBits = 8 '数据位 .StopBits = Ports.StopBits.One '停止位 .Parity = Ports.Parity.Even '偶校验 .RtsEnable = True .ReceivedBytesThreshold = 1 End With End Sub ''' ''' 打开串口 ''' Private Sub OpenSerialPort() ComboBox8.Enabled = False ComboBox9.Enabled = False Button19.Text = $"关闭串口" Button19.ForeColor = Color.Red End Sub ''' ''' 发送485串口数据 ''' ''' ''' Private Function SendPortData(dataBuff() As Byte) Dim portData As String = ByteToString(dataBuff) Dim timeData As String Dim cutTime As String _nowTime = Now _timeInterbval = _nowTime - _lastTime _lastTime = _nowTime timeData = $"{Math.Round(_timeInterbval.TotalMilliseconds, 0)}" timeData = timeData.PadRight(6) cutTime = $"{Now:HH:mm:ss:fff}" Try SerialPort.Write(dataBuff, 0, dataBuff.Length) AppendTipText("Com-TX:", Color.Green) AppendTipText("(" & cutTime & "-", Color.Black) AppendTipText(timeData, Color.BlueViolet) AppendTipText("):", Color.Black) AppendTipText(portData & vbCrLf, Color.Green) Catch ex As Exception MsgBox($"串口发送错误!原因:{ex.Message}") AppendTipText($"串口发送错误!原因:{ex.Message}", Color.Red) Return False End Try Return True End Function Private Function SendPortData(dataBuff() As Byte, dataLen As Integer) Dim portData As String = ByteToString(dataBuff, dataLen) Dim timeData As String Dim cutTime As String _nowTime = Now _timeInterbval = _nowTime - _lastTime _lastTime = _nowTime timeData = $"{Math.Round(_timeInterbval.TotalMilliseconds, 0)}" timeData = timeData.PadRight(6) cutTime = $"{Now:HH:mm:ss:fff}" Try SerialPort.Write(dataBuff, 0, dataLen) AppendTipText("Com-TX:", Color.Green) AppendTipText("(" & cutTime & "-", Color.Black) AppendTipText(timeData, Color.BlueViolet) AppendTipText("):", Color.Black) AppendTipText(portData & vbCrLf, Color.Green) Catch ex As Exception MsgBox($"串口发送错误!原因:{ex.Message}") AppendTipText($"串口发送错误!原因:{ex.Message}", Color.Red) Return False End Try Return True End Function ''' ''' 接收485串口数据 ''' ''' ''' Private Sub SerialPort_DataReceived(sender As Object, e As Ports.SerialDataReceivedEventArgs) Handles SerialPort.DataReceived Static bytes As Integer _recvOffset = 0 Try Do bytes = SerialPort.BytesToRead If bytes <= 0 Then Exit Sub If bytes + _recvOffset >= 255 Then SerialPort.Read(_recvBuffer, _recvOffset, 255 - _recvOffset) ShowPortReceData(_recvBuffer) If IsRuningTest Then ProcessAnalyticalData(_recvBuffer) Else If AnalyticalData(_recvBuffer) = &H1 Then AppendTipText(Encoding.UTF8.GetString(_recvBuffer) & vbCrLf, Color.Green) End If End If _recvOffset = 0 Else SerialPort.Read(_recvBuffer, _recvOffset, bytes) _recvOffset += bytes End If Thread.Sleep(10) Loop While SerialPort.BytesToRead > 0 If _recvOffset > 0 Then Dim buf(_recvOffset - 1) As Byte Array.Copy(_recvBuffer, 0, buf, 0, buf.Length) ShowPortReceData(buf) If IsRuningTest Then ProcessAnalyticalData(_recvBuffer) Else If AnalyticalData(_recvBuffer) = &H1 Then AppendTipText(Encoding.UTF8.GetString(buf) & vbCrLf, Color.Green) End If End If End If Catch ex As Exception AppendTipText($"串口接收数据失败,原因:{ex.Message}", Color.Red) End Try End Sub '处理串口接收函数 Private Function ProcessAnalyticalData(databuff() As Byte) As Byte 'For Each node In SendNodeDic ' If IsRuningTest = False Then Return If databuff(0) = &HF0 Then If databuff(1) = &HF0 Then If databuff(2) = &HF0 Then If databuff(3) = &HF0 Then Dim temp_val As Integer = 0 '产品状态 Show_Device_Work_State(databuff(4)) '浓度状态 temp_val = databuff(5) temp_val <<= 8 temp_val += databuff(6) 'Show_Device_GasMol(temp_val) '寿命状态 temp_val = databuff(7) temp_val <<= 8 temp_val += databuff(8) 'Show_Device_Work_Time(temp_val) '设备时间 temp_val = databuff(9) temp_val <<= 8 temp_val += databuff(10) temp_val <<= 8 temp_val += databuff(11) temp_val <<= 8 temp_val += databuff(12) 'Show_Device_Present_Time(temp_val) Return &H0 Else Return &H1 End If Else Return &H1 End If Else Return &H1 End If ElseIf databuff(0) = &HAE Then '设置回复数据 'Select Case databuff(3) ' Case &H1 ' 'AppendTipText("设置成功" & vbCrLf, Color.Blue) ' Return &H0 ' Case &H2 ' Device_Read_Set_Info_Parsing(databuff) ' Return &H0 ' Case &H3 ' ' Device_Record_Info_Parsing(databuff) ' Return &H0 'End Select SendNodeDicParsing(databuff) Else Return &H1 End If Return &H1 End Function '枚举SendNodeDic 设置对应数据 Public isnotSendNode As Boolean = False Public IsSetTime As Boolean = False Public IsRtcTime As Boolean = False Private Sub SendNodeDicParsing(databuff() As Byte) Dim node As SendNode Dim nextNode As SendNode Dim l1, l2 As String Dim dt As Date Dim buff() As Byte Dim ndatabuff(databuff.Length - 1) As Byte '拷贝数据到新数组 Array.Copy(databuff, 0, ndatabuff, 0, ndatabuff.Length) For i = 0 To SendNodeDic.Count - 1 node = SendNodeDic(i).Item2 If node.SendStatus = SendNode.SendStatusEnum.Send Then If node.RecvStatus = SendNode.RecvStatusEnum.None Then If databuff(3) = 2 Then If databuff(3) = node.SendData(3) AndAlso databuff(4) = node.SendData(4) Then node.RecvRefresh(ndatabuff) If databuff(3) = 2 AndAlso databuff(4) = 2 Then If databuff(5) = 0 Then isnotSendNode = True 'IsRuningTest = False Else isnotSendNode = False End If If i = SendNodeDic.Count - 2 Then nextNode = SendNodeDic(i - 1).Item2 If nextNode.SendStatus = SendNode.SendStatusEnum.Send AndAlso nextNode.RecvStatus = SendNode.RecvStatusEnum.Recv AndAlso nextNode.SendData(3) = 1 AndAlso nextNode.SendData(4) = 8 Then l1 = CombineFourBytesToLong(nextNode.SendData(8), nextNode.SendData(7), nextNode.SendData(6), nextNode.SendData(5)) buff = node.RecvDataLisr(0) l2 = CombineFourBytesToLong(buff(61), buff(60), buff(59), buff(58)) If l1.Equals(l2) Then IsSetTime = False Else IsSetTime = True IsRuningTest = False End If End If End If End If If databuff(3) = 2 AndAlso databuff(4) = 1 Then If i = SendNodeDic.Count - 1 Then dt = Date.Parse($"20{Hex2(databuff(6))}-{Hex2(databuff(7))}-{Hex2(databuff(8))} {Hex2(databuff(9))}:{Hex2(databuff(10))}:{Hex2(databuff(11))}") Dim temp_val As Long = (Now - dt).TotalSeconds 'Console.WriteLine($"RTC时间差 {temp_val}") If RTC_Time.Year = dt.Year AndAlso RTC_Time.Month = dt.Month AndAlso RTC_Time.Day = dt.Day AndAlso RTC_Time.Hour = dt.Hour AndAlso RTC_Time.Minute = dt.Minute AndAlso RTC_Time.Second = dt.Second Then IsRtcTime = True IsRuningTest = False Else If temp_val <= Timediffe Then IsRtcTime = False Else IsRtcTime = True IsRuningTest = False End If End If End If End If End If Else If databuff(3) = node.SendData(3) Then '将数组转字符串比对两个数组是否相等 If ByteToString(ndatabuff, node.SendData.Length) = ByteToString(node.SendData, node.SendData.Length) Then Continue For End If node.RecvRefresh(ndatabuff) End If End If End If End If Next End Sub ''' ''' 显示串口回复数据 ''' ''' Private Sub ShowPortReceData(databuff() As Byte) Dim portData As String = ByteToString(databuff) Dim timeData As String Dim cutTime As String _nowTime = Now _timeInterbval = _nowTime - _lastTime _lastTime = _nowTime timeData = $"{Math.Round(_timeInterbval.TotalMilliseconds, 0)}" timeData = timeData.PadRight(6) cutTime = $"{Now:HH:mm:ss:fff}" AppendTipText("Com-RX:", Color.Blue) AppendTipText("(" & cutTime & "-", Color.Black) AppendTipText(timeData, Color.BlueViolet) AppendTipText("):", Color.Black) AppendTipText(portData & vbCrLf, Color.Blue) End Sub #End Region #Region "通讯记录" ''' ''' 清除记录 ''' ''' ''' Private Sub Button24_Click(sender As Object, e As EventArgs) Handles Button24.Click RichTextBox1.Clear() End Sub ''' ''' 添加记录文本和颜色 ''' ''' 需要添加的记录内容 ''' 需要设置的记录颜色 Public Sub AppendTextAndSetStyle(ByVal str As String, ByVal cor As Color) Dim selStart As Integer Dim selLength As Integer selStart = RichTextBox1.TextLength RichTextBox1.AppendText(str) selLength = RichTextBox1.TextLength - selStart RichTextBox1.Select(selStart, selLength) RichTextBox1.SelectionColor = cor End Sub ''' ''' 添加记录 ''' ''' ''' Public Sub AppendTipText(recordString As String, col As Color) If RichTextBox1.InvokeRequired Then RichTextBox1.Invoke(New Action(Sub() If RichTextBox1.Lines.Count >= 256 Then RichTextBox1.Clear() AppendTextAndSetStyle($"{recordString}", col) RichTextBox1.ScrollToCaret() End Sub)) Else If RichTextBox1.Lines.Count >= 256 Then RichTextBox1.Clear() AppendTextAndSetStyle($"{recordString}", col) RichTextBox1.ScrollToCaret() End If End Sub #End Region #Region "解析串口数据" ''' ''' 解析串口数据 ''' ''' Private Function AnalyticalData(databuff() As Byte) As Byte If databuff(0) = &HF0 Then If databuff(1) = &HF0 Then If databuff(2) = &HF0 Then If databuff(3) = &HF0 Then Dim temp_val As Integer = 0 '产品状态 Show_Device_Work_State(databuff(4)) '浓度状态 temp_val = databuff(5) temp_val <<= 8 temp_val += databuff(6) Show_Device_GasMol(temp_val) '寿命状态 temp_val = databuff(7) temp_val <<= 8 temp_val += databuff(8) Show_Device_Work_Time(temp_val) '设备时间 temp_val = databuff(9) temp_val <<= 8 temp_val += databuff(10) temp_val <<= 8 temp_val += databuff(11) temp_val <<= 8 temp_val += databuff(12) Show_Device_Present_Time(temp_val) Return &H0 Else Return &H1 End If Else Return &H1 End If Else Return &H1 End If ElseIf databuff(0) = &HAE Then '设置回复数据 Select Case databuff(3) Case &H1 AppendTipText("设置成功" & vbCrLf, Color.Blue) Return &H0 Case &H2 Device_Read_Set_Info_Parsing(databuff) Return &H0 Case &H3 Device_Record_Info_Parsing(databuff) Return &H0 End Select Else Return &H1 End If Return &H1 End Function ''' ''' Byte数组转字符串 ''' ''' ''' Public Function ByteToString(databuff() As Byte) Dim strData As String = String.Empty For i = 0 To databuff.Length - 1 strData &= $" {Hex(databuff(i)).PadLeft(2, "0"c)}" Next Return strData End Function Public Function ByteToString(databuff() As Byte, dataLen As Integer) Dim strData As String = String.Empty For i = 0 To dataLen - 1 strData &= $" {Hex(databuff(i)).PadLeft(2, "0"c)}" Next Return strData End Function #End Region #Region "设置读取信息" ''' ''' 读取核心参数信息-委托 ''' Delegate Sub RefreshState_Show(state As Byte) Delegate Sub RefreshVal_Show(state As Integer) Delegate Sub RefreBuff_Show(buff() As Byte) Public Sub Show_Device_Setinfo_Info() '稳定消抖时间 - 单位:s TextBox6.Text = "30" '背景值滤波长度 - 最大:300S TextBox13.Text = "300" '传感器极大值 TextBox7.Text = "3500" '传感器极小值 TextBox8.Text = "500" '预热时间 - 单位:分钟 TextBox14.Text = "3" 'LEV 10% 对应的ADC 值 TextBox1.Text = "2800" 'LEV 0% 对应的ADC 值 TextBox2.Text = "1000" '触发 - 消抖次数 TextBox3.Text = "150" '释放 - 消抖次数 TextBox4.Text = "150" '稳定阈值 TextBox5.Text = "30" '报警点提前量 TextBox11.Text = "100" '校准超时 - 单位:S TextBox12.Text = "180" '校准0% LEL 下限 TextBox15.Text = "100" '校准0% LEL 上限 TextBox16.Text = "2200" '校准10% LEL 下限 TextBox19.Text = "1000" '校准10% LEL 上限 TextBox20.Text = "3400" '校准差值 下限 TextBox17.Text = "1000" '校准差值 上限 TextBox18.Text = "2500" '泄露恢复至正常 条件1:稳定处于基准值的多少倍以内,且达到消抖次数多少秒 TextBox21.Text = "1.2" '基准倍数 TextBox22.Text = "5" '消抖时间 '泄露恢复至正常 条件2:稳定处于基准值的多少倍以内,且持续时间超过多少分钟 TextBox23.Text = "1.5" '基准倍数 TextBox24.Text = "120" '消抖时间 End Sub ''' ''' 显示开关状态 ''' ''' Public Sub Show_Device_Work_State(state As Byte) If InvokeRequired = True Then Dim dev As New RefreshState_Show(AddressOf Show_Device_Work_State) Me.Invoke(dev, New Object() {state}) Else Select Case state Case &H2F Lab_DeviceState.ForeColor = Color.Orange Lab_DeviceState.Text = "预热" Case &HB Lab_DeviceState.ForeColor = Color.Green Lab_DeviceState.Text = "正常" Case &H48 Lab_DeviceState.ForeColor = Color.Red Lab_DeviceState.Text = "报警" End Select End If End Sub ''' ''' 显示设备浓度 ''' ''' Public Sub Show_Device_GasMol(mol As Integer) If InvokeRequired = True Then Dim dev As New RefreshVal_Show(AddressOf Show_Device_GasMol) Me.Invoke(dev, New Object() {mol}) Else Lab_mol.ForeColor = Color.Black Lab_mol.Text = mol.ToString & " mV" End If End Sub ''' ''' 显示工作天数 ''' ''' Public Sub Show_Device_Work_Time(day As Integer) If InvokeRequired = True Then Dim dev As New RefreshVal_Show(AddressOf Show_Device_Work_Time) Me.Invoke(dev, New Object() {day}) Else Lab_WorkTime.ForeColor = Color.Black Lab_WorkTime.Text = day.ToString & " 天" End If End Sub ''' ''' 显示当前时间 ''' ''' Public Sub Show_Device_Present_Time(time As Integer) If InvokeRequired = True Then Dim dev As New RefreshVal_Show(AddressOf Show_Device_Present_Time) Me.Invoke(dev, New Object() {time}) Else Dim dateTimeOffset As DateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(time) Dim localTime As DateTime = dateTimeOffset.LocalDateTime Lab_DeviceTime.Text = localTime.ToString("yyyy-MM-dd HH:mm:ss") End If End Sub ''' ''' 将 Int32 转为 4 字节数组,低字节在前。 ''' Public Function IntTo4BytesLE(value As Integer) As Byte() Return BitConverter.GetBytes(value) ' BitConverter 在 Windows/Intel 就是 Little-Endian End Function ''' ''' Int转2个字节Byte ''' 高字节在前,低字节在后 ''' ''' ''' Public Function IntToByteHB(ByVal i As Integer) As Byte() Dim btemp() As Byte = {0, 0} Dim b() As Byte = BitConverter.GetBytes(i) btemp(0) = b(0) btemp(1) = b(1) Return btemp End Function ''' ''' 和校验取余数 ''' 求Byte数组的和校验取余数 ''' ''' Byte数组 ''' Public Function GetSumCheckMod(dataPacket As Byte()) As Byte Dim sum As Integer For idx = 0 To dataPacket.Length - 1 sum += dataPacket(idx) sum = sum And &HFF Next Dim sumMod As Byte = &HFF - sum Return sumMod End Function Public Function GetSumCheckMod(dataPacket As Byte(), dataLen As Integer) As Byte Dim sum As Integer For idx = 0 To dataLen - 1 sum += dataPacket(idx) sum = sum And &HFF Next Dim sumMod As Byte = &HFF - sum Return sumMod End Function Public Sub Show_Device_ReadRtc(buff() As Byte) If InvokeRequired = True Then Dim dev As New RefreBuff_Show(AddressOf Show_Device_ReadRtc) Me.Invoke(dev, New Object() {buff}) Else DateTimePicker1.Value = New DateTime(CInt($"20{Hex(buff(6))}"), CInt($"{Hex(buff(7))}"), CInt($"{Hex(buff(8))}"), CInt($"{Hex(buff(9))}"), CInt($"{Hex(buff(10))}"), CInt($"{Hex(buff(11))}")) End If End Sub Public Function ConvertUtcTimestampToDateTime(timestamp As Long) As DateTime ' 创建一个 DateTime 对象,表示从 Unix 时间戳转换而来的时间 Dim unixEpoch As New DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) ' 添加时间戳所表示的秒数 Dim convertedDateTime As DateTime = unixEpoch.AddSeconds(timestamp) ' 返回本地时间 Return convertedDateTime.ToLocalTime() End Function Public Sub Show_Device_SetInfo(buff() As Byte) If InvokeRequired = True Then Dim dev As New RefreBuff_Show(AddressOf Show_Device_SetInfo) Me.Invoke(dev, New Object() {buff}) Else Dim temp_val As Integer Dim temp_len As Integer = 6 '稳定消抖时间 - 单位:s temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox6.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '背景值滤波长度 - 最大:600S temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox13.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '传感器极大值 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox7.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '传感器极小值 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox8.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '预热时间 - 单位:分钟 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox14.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) 'LEV 10% 对应的ADC 值 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox1.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) 'LEV 0% 对应的ADC 值 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox2.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '触发 - 消抖次数 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox3.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '释放 - 消抖次数 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox4.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '稳定阈值 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox5.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '报警点提前量 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox11.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '校准超时 - 单位:S temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox12.Text = temp_val.ToString AppendTipText($"报警电压 : {temp_val}" & vbCrLf, Color.Blue) '校准0% LEL 下限 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox15.Text = temp_val.ToString AppendTipText($"校准0% LEL 下限 : {temp_val}" & vbCrLf, Color.Blue) '校准0% LEL 上限 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox16.Text = temp_val.ToString AppendTipText($"校准0% LEL 下限 : {temp_val}" & vbCrLf, Color.Blue) '校准10% LEL 下限 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox19.Text = temp_val.ToString AppendTipText($"校准10% LEL 下限 : {temp_val}" & vbCrLf, Color.Blue) '校准10% LEL 上限 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox20.Text = temp_val.ToString AppendTipText($"校准10% LEL 下限 : {temp_val}" & vbCrLf, Color.Blue) '校准差值 下限 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox17.Text = temp_val.ToString AppendTipText($"校准0% LEL 下限 : {temp_val}" & vbCrLf, Color.Blue) '校准差值 上限 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox18.Text = temp_val.ToString AppendTipText($"校准0% LEL 下限 : {temp_val}" & vbCrLf, Color.Blue) '泄露条件1 - 基准值的倍数 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 Dim temp_mult As Double = temp_val / 10 TextBox21.Text = temp_mult.ToString AppendTipText($"泄露条件1 - 基准值的 {temp_mult}倍数" & vbCrLf, Color.Blue) '泄露条件1 - 消抖时间 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox22.Text = temp_val.ToString AppendTipText($"泄露条件1 - 消抖时间: {temp_val}S" & vbCrLf, Color.Blue) '泄露条件2 - 基准值的倍数 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 temp_mult = temp_val / 10 TextBox23.Text = temp_mult.ToString AppendTipText($"泄露条件2 - 基准值的 {temp_mult}倍数" & vbCrLf, Color.Blue) '泄露条件2 - 消抖时间 temp_val = buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) temp_len += 2 TextBox24.Text = temp_val.ToString AppendTipText($"泄露条件2 - 消抖时间: {temp_val}Min" & vbCrLf, Color.Blue) '生产时间戳 temp_val = buff(temp_len + 3) temp_val <<= 8 temp_val = temp_val Or buff(temp_len + 2) temp_val <<= 8 temp_val = temp_val Or buff(temp_len + 1) temp_val <<= 8 temp_val = temp_val Or buff(temp_len) DateTimeP_RelDate.Value = ConvertUtcTimestampToDateTime(temp_val) AppendTipText($"生产时间 :" & DateTimeP_RelDate.Value & vbCrLf, Color.Blue) End If End Sub Public Sub Device_Read_Set_Info_Parsing(buff As Byte()) Select Case buff(4) Case &H1 If buff(5) = &H0 Then AppendTipText("读取RTC时间成功" & vbCrLf, Color.Blue) AppendTipText($"RTC: 20{Hex(buff(6))}-{Hex(buff(7))}-{Hex(buff(8))} {Hex(buff(9))}:{Hex(buff(10))}:{Hex(buff(11))} {Hex(buff(12))} " & vbCrLf, Color.Blue) Show_Device_ReadRtc(buff) Else AppendTipText("读取RTC时间失败" & vbCrLf, Color.Red) End If Case &H2 If buff(5) = &H0 Then AppendTipText("读取 设置参数 成功" & vbCrLf, Color.Blue) Show_Device_SetInfo(buff) Else AppendTipText("读取 设置参数 失败" & vbCrLf, Color.Blue) End If End Select End Sub Public Sub Device_LogInfo_Data_Parsing(data As Integer) If InvokeRequired = True Then Dim dev As New RefreshVal_Show(AddressOf Device_LogInfo_Data_Parsing) Me.Invoke(dev, New Object() {data}) Else TextBox9.Text = data.ToString() End If End Sub Public Sub Device_Log_Data_Parsing(buff As Byte()) If InvokeRequired = True Then Dim dev As New RefreBuff_Show(AddressOf Device_Log_Data_Parsing) Me.Invoke(dev, New Object() {buff}) Else If buff(0) = &H1A And buff(2) = &HE Then If GetSumCheckMod(buff, &HE) = &H0 Then Dim temp_rtc_tick As Integer Dim temp_val As Integer Dim log_temp_data As New LOG_Data_List log_temp_data.sn = buff(1) temp_rtc_tick = buff(4) temp_rtc_tick <<= 8 temp_rtc_tick = temp_rtc_tick Or buff(5) temp_rtc_tick <<= 8 temp_rtc_tick = temp_rtc_tick Or buff(6) temp_rtc_tick <<= 8 temp_rtc_tick = temp_rtc_tick Or buff(7) log_temp_data.time = ConvertUtcTimestampToDateTime(temp_rtc_tick) AppendTipText($"LOG :" & log_temp_data.time & vbCrLf, Color.Blue) log_temp_data.type = buff(8) Select Case buff(8) Case &H1 AppendTipText($"记录类型 - 浓度报警记录" & vbCrLf, Color.Blue) temp_rtc_tick = buff(9) temp_rtc_tick <<= 8 temp_rtc_tick = temp_rtc_tick Or buff(10) log_temp_data.parsing = $"浓度报警 {temp_rtc_tick} {buff(12)}% {buff(11)}℃" Case &H2 AppendTipText($"记录类型 - 浓度恢复记录" & vbCrLf, Color.Blue) temp_rtc_tick = buff(9) temp_rtc_tick <<= 8 temp_rtc_tick = temp_rtc_tick Or buff(10) log_temp_data.parsing = $"浓度恢复 {temp_rtc_tick} {buff(12)}% {buff(11)}℃" Case &H3 AppendTipText($"记录类型 - 产品故障记录" & vbCrLf, Color.Blue) log_temp_data.parsing = $"产品故障 {buff(9)} {buff(11)}℃" Case &H4 AppendTipText($"记录类型 - 产品故障恢复记录" & vbCrLf, Color.Blue) log_temp_data.parsing = $"产品故障恢复 {buff(9)} {buff(11)}℃" Case &H5 AppendTipText($"记录类型 - 产品上电记录" & vbCrLf, Color.Blue) log_temp_data.parsing = $"产品上电 " Case &H6 AppendTipText($"记录类型 - 产品断电记录" & vbCrLf, Color.Blue) log_temp_data.parsing = $"产品断电 " Case &H7 AppendTipText($"记录类型 - 传感器失效记录" & vbCrLf, Color.Blue) log_temp_data.parsing = $"传感器失效 " Case &H8 AppendTipText($"记录类型 - 传感器校准记录" & vbCrLf, Color.Blue) temp_rtc_tick = buff(9) temp_rtc_tick <<= 8 temp_rtc_tick = temp_rtc_tick Or buff(10) temp_val = buff(11) temp_val <<= 8 temp_val = temp_val Or buff(12) log_temp_data.parsing = $"传感器校准 LEL_0:{temp_rtc_tick} LEL_10:{temp_val}" End Select '将解析后的数据添加到列表中 Dim log_sn As Integer = CInt(TextBox10.Text) 'Console.WriteLine($"Log sn:{log_sn} - {Log_Data.Count}") If Log_Data.Count > log_sn Then Log_Data(log_sn) = log_temp_data Grid_Refresh_LOG_Data(Log_Data, log_sn + 1, Grid1) 'Console.WriteLine($"Refresh_LOG_Data ") Else Log_Data.Add(log_temp_data) Grid_ADD_LOG_Data(Log_Data, Grid1) 'Console.WriteLine($"Add new line ") End If End If End If End If End Sub Public Sub Device_Record_Info_Parsing(buff As Byte()) Select Case buff(4) Case &H0 If buff(5) = &H0 Then AppendTipText("读取成功" & vbCrLf, Color.Blue) Dim Log_num As Integer Dim log_addr As Integer Log_num = buff(6) Log_num <<= 8 Log_num += buff(7) log_addr = buff(8) log_addr <<= 8 log_addr += buff(9) log_addr <<= 8 log_addr += buff(10) log_addr <<= 8 log_addr += buff(11) AppendTipText($"日志数量:{Log_num} 日志地址:{Hex(log_addr)}" & vbCrLf, Color.Blue) Device_LogInfo_Data_Parsing(Log_num) Else AppendTipText("读取失败" & vbCrLf, Color.Blue) End If Case &H1 If buff(5) = &H0 Then AppendTipText("读取日志成功" & vbCrLf, Color.Blue) Dim log_data(100) As Byte Dim log_len As Byte = buff(1) - 7 Array.Copy(buff, 6, log_data, 0, log_len) AppendTipText("读取日志数据 :" & ByteToString(log_data, log_len) & vbCrLf, Color.Blue) Device_Log_Data_Parsing(log_data) Else AppendTipText("读取日志失败" & vbCrLf, Color.Blue) End If End Select End Sub Private Sub But_SetRTCTime_Click(sender As Object, e As EventArgs) Handles But_SetRTCTime.Click Dim send_data(20) As Byte send_data(0) = &HAE '包头 send_data(1) = 13 '长度 send_data(2) = &H0 '校验 send_data(3) = &H1 '命令 - 设置参数 send_data(4) = &H1 '参数内容 - 设置RTC时间 If CheckBox2.Checked = True Then '使用系统时间 send_data(5) = $"&H{Now.Date.Year Mod 100}" send_data(6) = $"&H{Now.Date.Month Mod 100}" send_data(7) = $"&H{Now.Date.Day Mod 100}" send_data(8) = $"&H{Now.Hour}" send_data(9) = $"&H{Now.Minute }" send_data(10) = $"&H{Now.Second }" send_data(11) = $"&H{Now.Date.DayOfWeek Mod 100}" Else '自定义时间 send_data(5) = $"&H{DateTimePicker1.Value.Year Mod 100}" send_data(6) = $"&H{DateTimePicker1.Value.Month Mod 100}" send_data(7) = $"&H{DateTimePicker1.Value.Day Mod 100}" send_data(8) = $"&H{DateTimePicker1.Value.Hour}" send_data(9) = $"&H{DateTimePicker1.Value.Minute }" send_data(10) = $"&H{DateTimePicker1.Value.Second }" send_data(11) = $"&H{DateTimePicker1.Value.DayOfWeek Mod 100}" End If send_data(12) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 13) SendPortData(send_data, 13) End Sub Public Function GetSetRTCTime() As Byte() Dim send_data(12) As Byte send_data(0) = &HAE '包头 send_data(1) = 13 '长度 send_data(2) = &H0 '校验 send_data(3) = &H1 '命令 - 设置参数 send_data(4) = &H1 '参数内容 - 设置RTC时间 RTC_Time = Now If CheckBox2.Checked = True Then '使用系统时间 send_data(5) = $"&H{RTC_Time.Date.Year Mod 100}" send_data(6) = $"&H{RTC_Time.Date.Month Mod 100}" send_data(7) = $"&H{RTC_Time.Date.Day Mod 100}" send_data(8) = $"&H{RTC_Time.Hour}" send_data(9) = $"&H{RTC_Time.Minute }" send_data(10) = $"&H{RTC_Time.Second }" send_data(11) = $"&H{RTC_Time.Date.DayOfWeek Mod 100}" Else '自定义时间 send_data(5) = $"&H{DateTimePicker1.Value.Year Mod 100}" send_data(6) = $"&H{DateTimePicker1.Value.Month Mod 100}" send_data(7) = $"&H{DateTimePicker1.Value.Day Mod 100}" send_data(8) = $"&H{DateTimePicker1.Value.Hour}" send_data(9) = $"&H{DateTimePicker1.Value.Minute }" send_data(10) = $"&H{DateTimePicker1.Value.Second }" send_data(11) = $"&H{DateTimePicker1.Value.DayOfWeek Mod 100}" End If send_data(12) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 13) Return send_data End Function Public Function GetSetUTCTime() As Byte() Dim send_data(9) As Byte send_data(0) = &HAE '包头 send_data(1) = 10 '长度 send_data(2) = &H0 '校验 send_data(3) = &H1 '命令 - 设置参数 send_data(4) = &H8 '参数内容 - 设置RTC时间 '获取到秒的UTC时间戳 Dim Utc As Integer = CInt((DateTime.Now - New DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds) '将UTC时间戳转换为字节数组 Dim UtcBytes As Byte() = BitConverter.GetBytes(Utc) send_data(5) = UtcBytes(0) send_data(6) = UtcBytes(1) send_data(7) = UtcBytes(2) send_data(8) = UtcBytes(3) send_data(9) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 10) Return send_data End Function Private Sub But_ReleaseDate_Click(sender As Object, e As EventArgs) Handles But_ReleaseDate.Click Dim send_data(100) As Byte Dim temp_len As Integer = 0 send_data(0) = &HAE '包头 send_data(1) = 29 '长度 send_data(2) = &H0 '校验 send_data(3) = &H1 '命令 - 设置参数 send_data(4) = &H2 '参数内容 - 设置出厂时间及参数信息 temp_len += 5 Dim unixEpoch As New DateTime(1970, 1, 1, 8, 0, 0, DateTimeKind.Utc) Dim utcTime As Integer Dim temp_buff() As Byte '稳定消抖时间 - 单位:S temp_buff = BitConverter.GetBytes(CInt(TextBox6.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '背景值滤波长度 - 最大:600S temp_buff = BitConverter.GetBytes(CInt(TextBox13.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '传感器极大值 - 最大:4095 temp_buff = BitConverter.GetBytes(CInt(TextBox7.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '传感器极小值 - 最大:3000 temp_buff = BitConverter.GetBytes(CInt(TextBox8.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '预热时间 - 单位:分钟 temp_buff = BitConverter.GetBytes(CInt(TextBox14.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 'LEV 10% 对应的ADC 值 temp_buff = BitConverter.GetBytes(CInt(TextBox1.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 'LEV 0% 对应的ADC 值 temp_buff = BitConverter.GetBytes(CInt(TextBox2.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '触发 - 消抖次数 temp_buff = BitConverter.GetBytes(CInt(TextBox3.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '释放 - 消抖次数 temp_buff = BitConverter.GetBytes(CInt(TextBox4.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '稳定阈值 temp_buff = BitConverter.GetBytes(CInt(TextBox5.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '报警点提前量 temp_buff = BitConverter.GetBytes(CInt(TextBox11.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '校准超时 - 单位:S temp_buff = BitConverter.GetBytes(CInt(TextBox12.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '校准0% LEL下限 - temp_buff = BitConverter.GetBytes(CInt(TextBox15.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '校准0% LEL上限 - temp_buff = BitConverter.GetBytes(CInt(TextBox16.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '校准10% LEL下限 - temp_buff = BitConverter.GetBytes(CInt(TextBox19.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '校准10% LEL上限 - temp_buff = BitConverter.GetBytes(CInt(TextBox20.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '校准差值下限 temp_buff = BitConverter.GetBytes(CInt(TextBox17.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '校准差值上限 temp_buff = BitConverter.GetBytes(CInt(TextBox18.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '恢复正常模式,条件1:基准倍数 扩大10倍进行数据下发 Dim temp_mult As Integer = (CDbl(TextBox21.Text) * 10) temp_buff = BitConverter.GetBytes(temp_mult) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '恢复正常模式,条件1:消抖时间 temp_buff = BitConverter.GetBytes(CInt(TextBox22.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '恢复正常模式,条件2:基准倍数 扩大10倍进行数据下发 temp_mult = (CDbl(TextBox23.Text) * 10) temp_buff = BitConverter.GetBytes(temp_mult) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '恢复正常模式,条件2:消抖时间 temp_buff = BitConverter.GetBytes(CInt(TextBox24.Text)) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 '设备出厂时间 utcTime = CInt((DateTimeP_RelDate.Value - unixEpoch).TotalSeconds) 'Console.WriteLine("DateTimeP_RelDate UTC时间: " & utcTime) temp_buff = BitConverter.GetBytes(utcTime) send_data(temp_len) = temp_buff(0) temp_len += 1 send_data(temp_len) = temp_buff(1) temp_len += 1 send_data(temp_len) = temp_buff(2) temp_len += 1 send_data(temp_len) = temp_buff(3) temp_len += 1 send_data(temp_len) = &HEA '包尾 temp_len += 1 send_data(1) = temp_len '长度 send_data(2) = GetSumCheckMod(send_data, temp_len) SendPortData(send_data, temp_len) End Sub Public Function Judge_Volt_Range(sender As Object, e As EventArgs) As Byte Dim rev As Byte Dim temp_obj As TextBox = sender If temp_obj.TextLength > 0 AndAlso CUInt(temp_obj.Text) > 4096 Then temp_obj.Text = 4095 MsgBox($"超出范围:{CUInt(temp_obj.Text)} 输入范围:0~4095") ElseIf temp_obj.TextLength = 0 Then temp_obj.Text = 0 End If Return rev End Function Public Function Judge_Debounce_Range(sender As Object, e As EventArgs) As Byte Dim rev As Byte Dim temp_obj As TextBox = sender If temp_obj.TextLength > 0 AndAlso CUInt(temp_obj.Text) > 5000 Then temp_obj.Text = 4999 MsgBox($"超出范围:{CUInt(temp_obj.Text)} 输入范围:0~4999") ElseIf temp_obj.TextLength = 0 Then temp_obj.Text = 0 End If Return rev End Function Private Sub TBox_Volt_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged, TextBox5.TextChanged, TextBox2.TextChanged, TextBox11.TextChanged, TextBox13.TextChanged, TextBox12.TextChanged, TextBox7.TextChanged, TextBox20.TextChanged, TextBox19.TextChanged, TextBox18.TextChanged, TextBox17.TextChanged, TextBox16.TextChanged, TextBox15.TextChanged, TextBox21.TextChanged, TextBox24.TextChanged, TextBox23.TextChanged, TextBox22.TextChanged Judge_Volt_Range(sender, e) End Sub Private Sub TBox_Debounce_TextChanged(sender As Object, e As EventArgs) Handles TextBox3.TextChanged, TextBox6.TextChanged, TextBox4.TextChanged, TextBox8.TextChanged, TextBox14.TextChanged Judge_Debounce_Range(sender, e) End Sub Private Sub But_QueryLogInfo_Click(sender As Object, e As EventArgs) Handles But_QueryLogInfo.Click Dim send_data(20) As Byte send_data(0) = &HAE '包头 send_data(1) = 8 '长度 send_data(2) = &H0 '校验 send_data(3) = &H3 '命令 - 读取日志信息 send_data(4) = &H0 '参数内容 - send_data(5) = &H0 send_data(6) = &H0 send_data(7) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 8) SendPortData(send_data, 8) End Sub Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged If CheckBox1.Checked = True Then CheckBox2.Checked = False Else CheckBox2.Checked = True End If End Sub Private Sub CheckBox2_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox2.CheckedChanged If CheckBox2.Checked = True Then CheckBox1.Checked = False Else CheckBox1.Checked = True End If End Sub ''' ''' 定期上报开关 ''' Dim periodic_reporting_switch As Byte ''' ''' 开启定时上报 ''' ''' ''' Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click Dim send_data(20) As Byte If periodic_reporting_switch = &H1 Then periodic_reporting_switch = &H0 Else periodic_reporting_switch = &H1 End If send_data(0) = &HAE '包头 send_data(1) = 8 '长度 send_data(2) = &H0 '校验 send_data(3) = &H1 '命令 - 读取日志信息 send_data(4) = &H4 '参数内容 - send_data(5) = periodic_reporting_switch send_data(6) = &H0 send_data(7) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 8) If SendPortData(send_data, 8) = True Then If periodic_reporting_switch = &H1 Then Button2.Text = "关闭上报" Button2.ForeColor = Color.Red Else Button2.Text = "开启上报" Button2.ForeColor = Color.Black End If End If End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Dim send_data(20) As Byte send_data(0) = &HAE '包头 send_data(1) = 8 '长度 send_data(2) = &H0 '校验 send_data(3) = &H2 '命令 - 读取日志信息 send_data(4) = &H1 '参数内容 - send_data(5) = &H0 send_data(6) = &H0 send_data(7) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 8) SendPortData(send_data, 8) End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' 4、读取校准信息 Dim send_data(20) As Byte send_data(0) = &HAE '包头 send_data(1) = 8 '长度 send_data(2) = &H0 '校验 send_data(3) = &H2 '命令 - 读取日志信息 send_data(4) = &H2 '参数内容 - send_data(5) = &H0 send_data(6) = &H0 send_data(7) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 8) SendPortData(send_data, 8) '' 读取软件版本号 UUID 'Dim send_data(20) As Byte 'send_data(0) = &HAE '包头 'send_data(1) = 8 '长度 'send_data(2) = &H0 '校验 'send_data(3) = &H2 '命令 - 读取软件版本号 'send_data(4) = &H3 '参数内容 - 'send_data(5) = &H0 'send_data(6) = &H0 'send_data(7) = &HEA '包尾 'send_data(2) = GetSumCheckMod(send_data, 8) 'SendPortData(send_data, 8) ' 5、读取实时状态信息 'Dim send_data(20) As Byte 'send_data(0) = &HAE '包头 'send_data(1) = 8 '长度 'send_data(2) = &H0 '校验 'send_data(3) = &H2 '命令 - 读取实时状态信息 'send_data(4) = &H4 '参数内容 - 'send_data(5) = &H0 'send_data(6) = &H0 'send_data(7) = &HEA '包尾 'send_data(2) = GetSumCheckMod(send_data, 8) 'SendPortData(send_data, 8) End Sub ''' ''' 调试信息输出开关 ''' ''' ''' Private Sub CheckBox3_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox3.CheckedChanged Dim send_data(20) As Byte send_data(0) = &HAE '包头 send_data(1) = 8 '长度 send_data(2) = &H0 '校验 send_data(3) = &H1 '命令 - 设置参数 send_data(4) = &H6 '参数内容 - 设置调试信息状态 If CheckBox3.Checked = True Then send_data(5) = &HFF '开启调试信息 Else send_data(5) = &H0 '关闭调试信息 End If send_data(6) = &H0 send_data(7) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 8) SendPortData(send_data, 8) End Sub Private Sub CheckBox4_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox4.CheckedChanged Dim send_data(20) As Byte send_data(0) = &HAE '包头 send_data(1) = 8 '长度 send_data(2) = &H0 '校验 send_data(3) = &H1 '命令 - 设置参数 send_data(4) = &H5 '参数内容 - 设置调试信息状态 If CheckBox4.Checked = True Then send_data(5) = &H1 '开启调试曲线信息 Else send_data(5) = &H0 '关闭调试曲线信息 End If send_data(6) = &H0 send_data(7) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 8) SendPortData(send_data, 8) End Sub ''' ''' 复位命令下发 ''' ''' ''' Private Sub Button7_Click(sender As Object, e As EventArgs) Handles Button7.Click Dim send_data(20) As Byte send_data(0) = &HAE '包头 send_data(1) = 8 '长度 send_data(2) = &H0 '校验 send_data(3) = &H1 '命令 - 设置参数 send_data(4) = &H7 '参数内容 - 复位 send_data(5) = &H1 '关闭调试信息 send_data(6) = &H0 send_data(7) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 8) SendPortData(send_data, 8) End Sub ''' ''' 指定查询日志内容 ''' ''' ''' Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click Dim send_data(20) As Byte Dim temp_buff() As Byte = BitConverter.GetBytes(CInt(TextBox10.Text)) send_data(0) = &HAE '包头 send_data(1) = 8 '长度 send_data(2) = &H0 '校验 send_data(3) = &H3 '命令 - 读取日志信息 send_data(4) = &H1 '参数内容 - send_data(5) = temp_buff(1) send_data(6) = temp_buff(0) send_data(7) = &HEA '包尾 send_data(2) = GetSumCheckMod(send_data, 8) SendPortData(send_data, 8) End Sub Dim g_Auto_Log_Query_Enable As Boolean = False Dim g_Auto_Log_Query_Cnt As Integer = 0 Dim g_Auto_Log_Query_WriteCnt As Integer = 0 Dim g_Auto_Log_Query_ReplyRev As Integer = 0 ''' ''' 一键查询日志内容 ''' ''' ''' Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click If g_Auto_Log_Query_Enable Then '当前处于正在查询日志,停止查询 Timer1.Interval = 10 Timer1.Enabled = False g_Auto_Log_Query_Cnt = 0 g_Auto_Log_Query_Enable = False Button6.ForeColor = Color.Black Button6.Text = "一键查询" Else '开启自动查询日志 Timer1.Interval = 10 Timer1.Enabled = True g_Auto_Log_Query_Cnt = 0 g_Auto_Log_Query_Enable = True TextBox10.Text = 0 Button6.ForeColor = Color.Red Button6.Text = "停止查询" End If End Sub ''' ''' ''' ''' ''' Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick g_Auto_Log_Query_Cnt += 1 If g_Auto_Log_Query_Cnt >= 10 Then g_Auto_Log_Query_Cnt = 0 'TextBox10.Text += 1 Dim temp_num As Integer = CInt(TextBox10.Text) Dim temp_sum As Integer = CInt(TextBox9.Text) If SerialPort.IsOpen Then temp_num += 1 TextBox10.Text = temp_num Button5.PerformClick() If temp_num >= temp_sum Then '查询结束 Timer1.Interval = 10 Timer1.Enabled = False g_Auto_Log_Query_Cnt = 0 g_Auto_Log_Query_Enable = False Button6.ForeColor = Color.Black Button6.Text = "一键查询" End If Else '当前处于正在查询日志,停止查询 Timer1.Interval = 10 Timer1.Enabled = False g_Auto_Log_Query_Cnt = 0 g_Auto_Log_Query_Enable = False Button6.ForeColor = Color.Black Button6.Text = "一键查询" MsgBox("请打开串口!") End If End If 'Console.WriteLine($"Timer1_Tick {g_Auto_Log_Query_Cnt}") End Sub ''' ''' 数据时间结构 ''' Class LOG_DATE Public year As Int32 Public month As Int32 Public day As Int32 Public hour As Int32 Public minute As Int32 Public second As Int32 Public milliscond As Int32 End Class Class LOG_Data_List Public original_data() As Byte Public sn As Byte Public time As DateTime Public type As Byte Public para_data() As Byte Public parsing As String End Class ''' ''' 解析表格排序 ''' Enum form_grid1 sn data_date data_parsing End Enum Dim Log_Data As New List(Of LOG_Data_List) Private Sub Grid_Format_initial() '新表格控件 With Grid1 .AutoRedraw = False '禁止刷 .Rows = 6 '返回或设置表格的行数 .Cols = 4 .DefaultFont = New Font("Tahoma", 8) '设置字体 .ExtendLastCol = True '设置扩展最后一列的列宽,让表格可以充满控件 .BackColor1 = Color.FromArgb(231, 235, 247) .GridColor = Color.FromArgb(148, 190, 231) .Cell(0, 1).Text = " 序号 " .Cell(0, 2).Text = " 时间 " .Cell(0, 3).Text = "内容" .Column(1).CellType = FlexCell.CellTypeEnum.TextBox .Column(2).CellType = FlexCell.CellTypeEnum.TextBox .Column(3).CellType = FlexCell.CellTypeEnum.TextBox .Column(1).AutoFit() .Column(2).AutoFit() .Column(3).AutoFit() .Column(1).Alignment = FlexCell.AlignmentEnum.CenterCenter .Column(2).Alignment = FlexCell.AlignmentEnum.CenterCenter '居中对齐 '.Column(3).Alignment = FlexCell.AlignmentEnum.LeftCenter '左对齐 .Column(3).Alignment = FlexCell.AlignmentEnum.CenterCenter '居中对齐 .SelectionMode = FlexCell.SelectionModeEnum.ByRow '整行选取 .DisplayRowNumber = True '开启行号 .AutoRedraw = True .Refresh() '加载数据 End With End Sub ''' ''' 将数据显示到表格中 ''' ''' Public Sub Grid_ADD_LOG_Data(data_list As List(Of LOG_Data_List), show_grid As FlexCell.Grid) Dim temp_num As Int32 Dim temp_string As String '将数据对应的序号填充到对应的行号中 If data_list.Count > show_grid.Rows - 1 Then 'Console.WriteLine("Grid - 添加新行") show_grid.AddItem(" ", True) '添加新行 End If temp_num = data_list.Count - 1 '获取当前数据列表中有多少条数据 temp_string = $"List Count:{temp_num} Rows:{show_grid.Rows}" 'Console.WriteLine(temp_string) 'show_grid.AddItem(" ", True) '添加新行 show_grid.Cell(data_list.Count, form_grid1.sn + 1).Text = data_list(temp_num).sn show_grid.Cell(data_list.Count, form_grid1.data_date + 1).Text = data_list(temp_num).time show_grid.Cell(data_list.Count, form_grid1.data_parsing + 1).Text = data_list(temp_num).parsing End Sub Public Sub Grid_Refresh_LOG_Data(data_list As List(Of LOG_Data_List), row As Integer, show_grid As FlexCell.Grid) Dim temp_num As Int32 Dim temp_string As String '将数据对应的序号填充到对应的行号中 If row > show_grid.Rows - 1 Then 'Console.WriteLine("Grid - 添加新行") show_grid.AddItem(" ", True) '添加新行 End If temp_num = row - 1 '获取当前数据列表中有多少条数据 temp_string = $"List Count:{temp_num} Rows:{show_grid.Rows}" 'Console.WriteLine(temp_string) show_grid.Cell(row, form_grid1.sn + 1).Text = data_list(temp_num).sn show_grid.Cell(row, form_grid1.data_date + 1).Text = data_list(temp_num).time show_grid.Cell(row, form_grid1.data_parsing + 1).Text = data_list(temp_num).parsing End Sub Public TextBox2check As Boolean Private Sub ToolStripTextBox2_TextChanged(sender As Object, e As EventArgs) Handles ToolStripTextBox2.TextChanged TextBox2check = True If String.IsNullOrEmpty(ToolStripTextBox2.Text.Trim) Then TextBox2check = False End If Dim str As String For i = 0 To ToolStripTextBox2.Text.Length - 1 str = ToolStripTextBox2.Text.Substring(i, 1) '判断 第i个字符 是否在 0到9 A到F 和空格 If Not ((str >= "0" And str <= "9") OrElse (str.ToUpper >= "A" And str.ToUpper <= "F") OrElse (str.Equals(" "))) Then ToolStripTextBox2.ForeColor = Color.Red TextBox2check = False ''Console.WriteLine($"【{str}】:{ (str >= "0" And str <= "9") }") ''Console.WriteLine($"【{str}】:{ (str.ToUpper >= "A" And str.ToUpper <= "F") }") ''Console.WriteLine($"【{str}】:{ str.Equals(" ")}") Else ToolStripTextBox2.ForeColor = Color.Black End If Next End Sub Public CommandSetDic As Dictionary(Of String, Byte()) Public Sub InitCommandSetDic() Dim str As String = ProcessTable.Cell(0, 0).Tag If String.IsNullOrEmpty(str) OrElse str.Length = 0 Then CommandSetDic = New Dictionary(Of String, Byte()) CommandSetDic.Add("开启上报", HexStringToByteArray("AE 08 59 01 04 01 00 EA")) CommandSetDic.Add("关闭上报", HexStringToByteArray("AE 08 5A 01 04 00 00 EA")) CommandSetDic.Add("读取RTC时间", HexStringToByteArray("AE 08 5C 02 01 00 00 EA")) CommandSetDic.Add("设置RTC时间", {}) CommandSetDic.Add("设置生产时间", {}) CommandSetDic.Add("延时", {2}) CommandSetDic.Add("获取服务器key", {0}) CommandSetDic.Add("设置设备key", {0}) CommandSetDic.Add("读取设备key", {"AE 08 54 02 09 00 00 EA"}) Else CommandSetDic = JsonConvert.DeserializeObject(Of Dictionary(Of String, Byte()))(str) End If SendNodeDic = New List(Of (String, SendNode)) End Sub Public FileCPatrh = $"{Application.StartupPath}\NT318" Public Sub SaveCommandSetDic() ProcessTable.Cell(0, 0).Tag = JsonConvert.SerializeObject(CommandSetDic) If Not IO.Directory.Exists(FileCPatrh & "\CommandSetDic") Then IO.Directory.CreateDirectory(FileCPatrh & "\CommandSetDic") End If ProcessTable.SaveFile(FileCPatrh & "\CommandSetDic.flx") '判断日文件夹在不在 If Not IO.Directory.Exists(FileCPatrh & "\Log") Then IO.Directory.CreateDirectory(FileCPatrh & "\Log") End If Grid_table.SaveFile(FileCPatrh & $"\Log\{Now.ToString("yyyyMMddHHmmss")}.flx") End Sub Public Sub InitLoadProcessTable(Optional isFile As Boolean = True) If isFile Then If IO.File.Exists(FileCPatrh & "\CommandSetDic.flx") Then ProcessTable.OpenFile(FileCPatrh & "\CommandSetDic.flx") Return End If End If ProcessTable.NewFile() ProcessTable.Cols = 5 ProcessTable.Rows = 1 ProcessTable.DisplayRowNumber = True ProcessTable.ExtendLastCol = True ProcessTable.Cell(0, 0).Text = "序号" ProcessTable.Cell(0, 1).Text = "勾选" ProcessTable.Cell(0, 2).Text = "命令别名" ProcessTable.Cell(0, 3).Text = "命令" ProcessTable.Cell(0, 4).Text = "发送状态" ProcessTable.Column(0).Width = 50 ProcessTable.Column(1).Width = 20 ProcessTable.Column(2).Width = 120 ProcessTable.Column(3).Width = 200 ProcessTable.Column(4).Width = 100 ProcessTable.Column(0).Alignment = AlignmentEnum.GeneralCenter ProcessTable.Column(1).Alignment = AlignmentEnum.GeneralCenter ProcessTable.Column(2).Alignment = AlignmentEnum.GeneralCenter ProcessTable.Column(3).Alignment = AlignmentEnum.GeneralCenter ProcessTable.Column(4).Alignment = AlignmentEnum.GeneralCenter ProcessTable.Column(1).CellType = CellTypeEnum.CheckBox ProcessTable.Column(2).CellType = CellTypeEnum.ComboBox ProcessTable.Column(3).Locked = True End Sub Public Sub InitGrid_table() With Grid_table .NewFile() .Rows = 1 .Cols = TableEnum.MAX .DisplayRowNumber = True .ExtendLastCol = True For i = 0 To TableEnum.MAX - 1 If i = 0 Then .Column(0).Width = 50 End If .Cell(0, i).Text = GetTableEnumName(i) .Column(i).Alignment = AlignmentEnum.GeneralCenter .Column(i).Locked = True Next End With End Sub Private Sub ToolStripButton1_Click(sender As Object, e As EventArgs) Handles ToolStripButton1.Click If String.IsNullOrEmpty(T_CommandAlias.Text.Trim) Then MsgBox("请输入命令别名") Return End If If String.IsNullOrEmpty(ToolStripTextBox2.Text.Trim) Then MsgBox("请输入命令") Return End If Dim CommandAlia As String = T_CommandAlias.Text.Trim Dim Command As String = ToolStripTextBox2.Text.Trim If CommandSetDic.ContainsKey(CommandAlia) Then '提示框提示用户是否需要覆盖 If MsgBox("该命令别名已存在,是否覆盖?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then CommandSetDic(CommandAlia) = HexStringToByteArray(Command) End If Else CommandSetDic.Add(CommandAlia, HexStringToByteArray(Command)) End If End Sub ''' ''' 将字符串按 UTF-8 编码转成 Byte 数组。 ''' Public Function StringToBytes(ByVal s As String) As Byte() Return System.Text.Encoding.UTF8.GetBytes(s) End Function '将16进制字符串转换为字节数组 Private Function HexStringToByteArray(hex As String) As Byte() Dim bytes As New List(Of Byte) hex = hex.Replace(" ", "").Trim.ToUpper() For i As Integer = 0 To hex.Length - 1 Step 2 Dim hexByte As String = hex.Substring(i, 2) bytes.Add(Convert.ToByte(hexByte, 16)) Next Return bytes.ToArray() End Function '将字节数组转换为16进制字符串 Private Function ByteArrayToHexString(bytes As Byte()) As String If bytes Is Nothing OrElse bytes.Length = 0 Then Return "" Dim hex As String = "" For Each b As Byte In bytes hex += b.ToString("X2") & " " Next Return hex.Trim() End Function Private Sub ProcessTable_ComboDropDown(Sender As Object, e As Grid.ComboDropDownEventArgs) Handles ProcessTable.ComboDropDown If e.Row = 0 Then Return If e.Col = 2 Then ProcessTable.ComboBox(e.Col).Items.Clear() ProcessTable.ComboBox(e.Col).Items.AddRange(CommandSetDic.Keys.ToArray()) End If End Sub Public SendNodeDic As List(Of (String, SendNode)) Public StartSendThread As Thread Public IsRuningTest As Boolean = False Public IsStopTest As Boolean = False Private Sub ToolStripButton3_Click(sender As Object, e As EventArgs) Handles ToolStripButton3.Click If ToolStripButton3.Text = "开始校时" Then If Not SerialPort.IsOpen Then MsgBox("串口未打开") Return End If ToolStripButton3.Text = "停止校时" ToolStripButton3.ForeColor = Color.Red IsRuningTest = True IsStopTest = False isnotSendNode = True IsSetTime = False IsRtcTime = False SendNodeDic.Clear() Label38.ForeColor = Color.Yellow If ProcessTable.Rows = 1 Then ' MsgBox("命令列表为空!!!") Label38.Text = "命令列表为空!!!" Label38.ForeColor = Color.Red Return End If For i = 1 To ProcessTable.Rows - 1 If ProcessTable.Cell(i, 1).Text = "1" Then ' ProcessTable.Rows = ProcessTable.Rows - 1 SendNodeDic.Add((ProcessTable.Cell(i, 2).Text, New SendNode())) End If Next Button24.PerformClick() '运行线程如果 线程不存在则新建线程并运行如果线程存在中则先终止再新启动 If StartSendThread Is Nothing OrElse StartSendThread.ThreadState = ThreadState.Stopped Then StartSendThread = New Thread(AddressOf StartSendThreadRuning) StartSendThread.Start() Else StartSendThread.Abort() StartSendThread = New Thread(AddressOf StartSendThreadRuning) StartSendThread.Start() End If Else ToolStripButton3.Text = "开始校时" ToolStripButton3.ForeColor = Color.Black IsRuningTest = False IsStopTest = True End If End Sub Delegate Sub delegateRefreshCaptureText(Textcolor As Color, Textstr As String) Public Sub RefreshCaptureText(Textcolor As Color, Textstr As String) If Me.InvokeRequired = True Then Dim dd As New delegateRefreshCaptureText(AddressOf RefreshCaptureText) Me.Invoke(dd, {Textcolor, Textstr}) Else If Textcolor = Color.Red Then Label38.Text = "失败" Label38.ForeColor = Textcolor Else If Textcolor = Color.Green Then If Textstr.Contains("校时完成") Then Label38.Text = "成功" Label38.ForeColor = Textcolor Else Label38.Text = "校时中" Label38.ForeColor = Color.Yellow End If End If End If 'Label38.Text = Textstr End If End Sub Public Sub RefreshCaptureRichText(Textcolor As Color, Textstr As String) If Me.InvokeRequired = True Then Dim dd As New delegateRefreshCaptureText(AddressOf RefreshCaptureRichText) Me.Invoke(dd, {Textcolor, Textstr}) Else RichTextBox1.Text = Textstr Label38.ForeColor = Textcolor End If End Sub Public Sub StartSendThreadRuning() ' SendPortData1() Dim result As String = String.Empty Dim nextnode As SendNode For Each node In SendNodeDic Console.WriteLine(node.Item1) If node.Item1.Equals("读取RTC时间") Then Console.WriteLine(node.Item1) End If If IsRuningTest = False Then Exit For If isnotSendNode = False Then RefreshCaptureText(Color.Red, "校时失败!!") IsRuningTest = False Exit For End If '循环等待节点接收状态改变 While node.Item2.RecvStatus = SendNode.RecvStatusEnum.None If IsRuningTest = False Then Exit For If node.Item1.Equals("延时") Then node.Item2.AddRecvData(CommandSetDic.Item("延时")) node.Item2.ResendRefresh() Thread.Sleep(CInt(CommandSetDic.Item("延时")(0)) * 1000) node.Item2.RecvRefresh(CommandSetDic.Item("延时")) Exit While End If If node.Item1.Equals("获取服务器key") Then node.Item2.AddRecvData({0}) node.Item2.ResendRefresh() AppendTipText($"Com-TX:( {Now:HH:mm:ss:fff}):获取服务器key" & vbCrLf, Color.Green) '从 后往前 遍历 SendNodeDic 列表 Dim ifnode As (String, SendNode) For i As Integer = SendNodeDic.Count - 1 To 0 Step -1 ifnode = SendNodeDic(i) If ifnode.Item1.Equals("读取软件版本号") AndAlso ifnode.Item2.RecvStatus = SendNode.RecvStatusEnum.Recv Then Exit For End If Next If Not IsNothing(ifnode) AndAlso ifnode.Item1.Equals("读取软件版本号") AndAlso ifnode.Item2.RecvStatus = SendNode.RecvStatusEnum.Recv Then Dim MachineType As Integer Dim Brandld As Integer Dim buff As Byte() = ifnode.Item2.RecvDataLisr(0) MachineType = CombineTwoBytesToDecimal(buff(7), buff(8)) Brandld = CombineTwoBytesToDecimal(buff(9), buff(10)) Dim uuid As String = "" For ni As Integer = 1 To buff(13) uuid += $"{Hex2(buff(13 + ni))} " Next uuid = uuid.Replace(" ", "") Dim apinode As Program = API_AllocationBarCode(uuid, MachineType, Brandld) If IsNothing(apinode) Then Else AppendTipText($"Com-TX:( {Now:HH:mm:ss:fff}):获取服务器ClientId:{apinode.Response.ClientId}key:{apinode.Response.SecretKey}" & vbCrLf, Color.Blue) node.Item2.RecvDatadic = apinode node.Item2.RecvRefresh({0}) End If Else IsRuningTest = False '退出流程 RefreshCaptureText(Color.Red, $"节点:{node.Item1} :执行失败!") Exit While End If End If If node.Item1.Equals("设置设备key") Then Dim ifnode As (String, SendNode) Dim Nfnode As (String, SendNode) For i As Integer = SendNodeDic.Count - 1 To 0 Step -1 If IsNothing(ifnode) Then ifnode = SendNodeDic(i) If ifnode.Item1.Equals("获取服务器key") AndAlso ifnode.Item2.RecvStatus = SendNode.RecvStatusEnum.Recv Then Else ifnode = Nothing End If End If If IsNothing(Nfnode) Then Nfnode = SendNodeDic(i) If Nfnode.Item1.Equals("读取设备key") AndAlso Nfnode.Item2.RecvStatus = SendNode.RecvStatusEnum.Recv Then Else Nfnode = Nothing End If End If Next If Not IsNothing(ifnode.Item2) AndAlso Not IsNothing(Nfnode.Item2) Then Dim devkey As Integer Dim devClientId As String Dim buff = Nfnode.Item2.RecvDataLisr(0) Dim src As Byte() = Slice(buff, 5, 4) devkey = BytesLE4ToInt(src) src = Slice(buff, 9, buff(1) - 10) devClientId = BytesToString(src).Trim Dim apinode As Program = ifnode.Item2.RecvDatadic If apinode.Response.SecretKey.Equals(devkey.ToString) AndAlso apinode.Response.ClientId.Equals(devClientId) Then AppendTipText($"Com-TX:( {Now:HH:mm:ss:fff}):获取服务器ClientId:{apinode.Response.ClientId}key:{apinode.Response.SecretKey}" & vbCrLf, Color.Blue) node.Item2.RecvRefresh({0}) Exit While End If End If End If '判断发送状态是否改变0:未发送,1:发送成功,2:发送失败 If node.Item2.SendStatus = SendNode.SendStatusEnum.None Then '发送数据并更新发送状态 result = SendPortData1(node.Item1, node.Item2) AppendTipText($"Com-TX:【{node.Item1}】", Color.Green) AppendTipText("(" & Now.ToString("yyyy-MM-dd HH:mm:ss") & "):", Color.Black) AppendTipText(ByteToString(node.Item2.SendData) & vbCrLf, Color.Green) If String.IsNullOrEmpty(result) Then result = $"节点:{node.Item1} :发送成功!" RefreshCaptureText(Color.Green, result) Else IsRuningTest = False '退出流程 RefreshCaptureText(Color.Red, result) End If Else '判断节点是否需要重新发送 If node.Item2.NeedResend() Then result = SendPortData1(node.Item1, node.Item2) AppendTipText("Com-TX:", Color.Green) AppendTipText("(" & Now.ToString("yyyy-MM-dd HH:mm:ss") & "):", Color.Black) AppendTipText(ByteToString(node.Item2.SendData) & vbCrLf, Color.Green) If String.IsNullOrEmpty(result) Then result = $"节点:{node.Item1} :重发[{ node.Item2.SendCount}] 送成功!" RefreshCaptureText(Color.Green, result) Else IsRuningTest = False '退出流程 RefreshCaptureText(Color.Red, result) End If Else If node.Item2.SendCount < 3 Then Else IsRuningTest = False '退出流程 RefreshCaptureText(Color.Red, $"节点:{node.Item1} :发送失败!") End If End If End If '延时(100) Thread.Sleep(100) End While Next '数据入库 Dim sresult As String = StoreTestDataInTheDatabase() If String.IsNullOrEmpty(sresult) Then If IsRuningTest = True Then RefreshCaptureText(Color.Green, "校时完成!") End If Else RefreshCaptureText(Color.Red, sresult) End If delToolStripButton3() End Sub Public Shared Function API_AllocationBarCode(Mcu_Uuid As String, MachineType As Integer, Brandld As Integer) As Program Dim jsonString As String = String.Empty Dim dic As New Dictionary(Of String, String) dic.Add("Mcu_Uuid", Mcu_Uuid) dic.Add("MachineType", MachineType) dic.Add("Brandld", Brandld) Dim jsonstr As String = JsonConvert.SerializeObject(dic) Try jsonString = PostData2("http://iot.uts-data.com:8086/api/Deviceinfoes/GetOrUpdateDevice", $"{jsonstr}") Catch ex As Exception MsgBox($"网络API调用错误,请联系管理员。") Return Nothing End Try ''Console.WriteLine(jsonString) If jsonString = Nothing Then Return Nothing End If Dim login As Program Try login = JsonConvert.DeserializeObject(Of Program)(jsonString) If Not IsNothing(login) AndAlso Not IsNothing(login.IsOk) Then If login.IsOk Then Return login Else Return Nothing End If Return Nothing Else Return Nothing End If Catch ex As Exception MsgBox($"Json数据转换错误,请联系管理员。详情 :Json data to AllocationAPI error") Return Nothing End Try End Function Public Shared Function PostData2(ByVal url As String, ByVal data As String) As String ServicePointManager.Expect100Continue = False Dim request As HttpWebRequest = WebRequest.Create(url) '//Post请求方式 request.Method = "POST" '内容类型 request.ContentType = "application/json" '将URL编码后的字符串转化为字节 Dim encoding As New UTF8Encoding() Dim bys As Byte() = encoding.GetBytes(data) '设置请求的 ContentLength request.ContentLength = bys.Length '获得请 求流 Dim newStream As Stream = request.GetRequestStream() newStream.Write(bys, 0, bys.Length) newStream.Close() '获得响应流 Dim sr As StreamReader = New StreamReader(request.GetResponse().GetResponseStream) Return sr.ReadToEnd End Function Public Shared Function PostData(ByVal url As String, ByVal data As String) As String ServicePointManager.Expect100Continue = False Dim request As HttpWebRequest = CType(WebRequest.Create(url), HttpWebRequest) '//Post请求方式 request.Method = "POST" '内容类型 request.ContentType = "application/x-www-form-urlencoded" '将URL编码后的字符串转化为字节 Dim encoding As New UTF8Encoding() Dim bys As Byte() = encoding.GetBytes(data) '设置请求的 ContentLength request.ContentLength = bys.Length '获得请 求流 Dim newStream As Stream = request.GetRequestStream() newStream.Write(bys, 0, bys.Length) newStream.Close() '获得响应流 Dim sr As StreamReader = New StreamReader(request.GetResponse().GetResponseStream) Return sr.ReadToEnd End Function Delegate Sub delegateToolStripButton3() Public Sub delToolStripButton3() If Me.InvokeRequired = True Then Dim dd As New delegateToolStripButton3(AddressOf delToolStripButton3) Me.Invoke(dd) Else ToolStripButton3.Text = "开始校时" ToolStripButton3.ForeColor = Color.Black IsRuningTest = False IsStopTest = True End If End Sub 'byte 转16进制字符串 Public Function Hex2(ByVal b As Byte) As String Return b.ToString("X2") End Function '测试数据入库 Public Function StoreTestDataInTheDatabase() As String '判断测试是主动停止还是被动停止 Dim result As String = String.Empty If IsStopTest = True Then result = "测试被停止!" Return result End If Dim dic As New Dictionary(Of String, String) Dim buff() As Byte dic.Add("测试时间", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")) dic.Add("测试结果", "1") dic.Add("测试信息", "成功") If IsSetTime = True Then dic.Item("测试结果") = "0" dic.Item("测试信息") = $"失败:设置生产时间失败!" result = $"失败:设置生产时间失败!" RefreshCaptureText(Color.Red, "失败:设置生产时间失败!") End If If IsRtcTime = True Then dic.Item("测试结果") = "0" dic.Item("测试信息") = $"失败:设备RTC时钟故障" result = $"失败:设备RTC时钟故障" RefreshCaptureText(Color.Red, "失败:设备RTC时钟故障") End If Dim node As (String, SendNode) For i = 0 To SendNodeDic.Count - 1 node = SendNodeDic(i) If node.Item1.Equals("延时") Then Continue For End If If node.Item1.Equals("获取服务器key") Then '[服务器key] Text, ' ' [服务器ClientId] TEXT, Dim apinode As Program = node.Item2.RecvDatadic dic.Add("服务器key", apinode.Response.SecretKey) dic.Add("服务器ClientId", apinode.Response.ClientId) Continue For End If If node.Item2.SendStatus = SendNode.SendStatusEnum.Send Then If &H2 = node.Item2.SendData(3) Then '判断接收状态是否为成功 If node.Item2.RecvStatus = SendNode.RecvStatusEnum.Recv Then buff = node.Item2.RecvDataLisr(0) If node.Item2.SendData(3) = buff(3) AndAlso node.Item2.SendData(4) = buff(4) Then Try Select Case buff(4) Case 1 '读取RTC时间 'AppendTipText($"RTC: 20{Hex(buff(6))}-{Hex(buff(7))}-{Hex(buff(8))} {Hex(buff(9))}:{Hex(buff(10))}:{Hex(buff(11))} {Hex(buff(12))} " & vbCrLf, Color.Blue) dic.Add("RTC时间", $"20{Hex2(buff(6))}-{Hex2(buff(7))}-{Hex2(buff(8))} {Hex2(buff(9))}:{Hex2(buff(10))}:{Hex2(buff(11))}") dic.Add("RTC星期", $"{Hex(buff(12))}") Case 2 '读取设置参数信息 '00 - 读取校准结果:0x00:校准成功, 其他值: 校准失败 ' 1E 00 稳定消抖时间 - 单位:s '2C 01 背景值滤波长度 - 单位:s ' FA 0F 传感器极大值 ' 0A 00 传感器极小值 ' 03 00 预热时间 - 单位:分钟 '34 08 LEV 10% 对应的ADC 值 ' 20 03 LEV 0% 对应的ADC 值 ' 96 00 触发 - 消抖次数 ' 96 00 释放 - 消抖次数 ' 64 00 稳定阈值 ' 32 00 报警点提前量 ' B0 4 校准超时 - 单位: S '14 00 LEV 0% 校准最小值 ' AC 0D LEV 0% 校准最大值 ' F4 1 LEV 10% 校准最小值 ' FA 0F LEV 10% 校准最大值 ' 14 00 差值 校准最小值 ' FA 0F 差值 校准最大值 ' C8 0 泄露恢复正常 判定条件1: 处于基准的XX倍数以内 '05 00 泄露恢复正常 判定条件1:处于基准的XX倍数以内的消抖时间 单位: 秒 '84 03 泄露恢复正常 判定条件2:处于基准的XX倍数以内 '78 00 泄露恢复正常 判定条件2:处于基准的XX倍数以内的消抖时间 单位: 分钟 'DC 63 E6 67 设备生产时间 If dic.ContainsKey("校准结果") Then Select Case buff(5) Case 0 dic("校准结果") = $"{(buff(5))}_OK" Case 1 dic("校准结果") = $"{(buff(5))}_未校准" Case 2 dic("校准结果") = $"{(buff(5))}_校验错误" End Select dic("温度校准算法选择") = CombineTwoBytesToDecimal(buff(6), buff(7)) dic("回差") = CombineTwoBytesToDecimal(buff(8), buff(9)) dic("传感器极大值") = CombineTwoBytesToDecimal(buff(10), buff(11)) dic("传感器极小值") = CombineTwoBytesToDecimal(buff(12), buff(13)) dic("预热时间_分") = CombineTwoBytesToDecimal(buff(14), buff(15)) dic("ADC_LEV_10") = CombineTwoBytesToDecimal(buff(16), buff(17)) dic("ADC_LEV_0") = CombineTwoBytesToDecimal(buff(18), buff(19)) dic("触发_消抖次数") = CombineTwoBytesToDecimal(buff(20), buff(21)) dic("释放_消抖次数") = CombineTwoBytesToDecimal(buff(22), buff(23)) dic("稳定阈值") = CombineTwoBytesToDecimal(buff(24), buff(25)) dic("报警点提前量") = CombineTwoBytesToDecimal(buff(26), buff(27)) dic("校准超时_秒") = CombineTwoBytesToDecimal(buff(28), buff(29)) dic("IHIOT_心跳包上报间隔") = CombineTwoBytesToDecimal(buff(30), buff(31)) dic("OSD显示模式") = CombineTwoBytesToDecimal(buff(32), buff(33)) dic("检测故障最小值") = CombineTwoBytesToDecimal(buff(34), buff(35)) dic("检测故障最大值") = CombineTwoBytesToDecimal(buff(36), buff(37)) dic("校准最小值_LEV_0") = CombineTwoBytesToDecimal(buff(38), buff(39)) dic("校准最大值_LEV_0") = CombineTwoBytesToDecimal(buff(40), buff(41)) dic("校准最小值_LEV_10") = CombineTwoBytesToDecimal(buff(42), buff(43)) dic("校准最大值_LEV_10") = CombineTwoBytesToDecimal(buff(44), buff(45)) dic("校准最小值_差值") = CombineTwoBytesToDecimal(buff(46), buff(47)) dic("校准最大值_差值") = CombineTwoBytesToDecimal(buff(48), buff(49)) dic("自定义LEV_10_对应的ADC") = CombineTwoBytesToDecimal(buff(50), buff(51)) dic("自定义LEV_0_对应的ADC") = CombineTwoBytesToDecimal(buff(52), buff(53)) dic("泄露恢复正常_条件2") = CombineTwoBytesToDecimal(buff(54), buff(55)) dic("泄露恢复正常_条件2消抖时间_分") = CombineTwoBytesToDecimal(buff(56), buff(57)) dic("设备生产时间") = CombineFourBytesToLong(buff(61), buff(60), buff(59), buff(58)) Else dic.Add("校准结果", $"{(buff(5))}") dic("温度校准算法选择") = CombineTwoBytesToDecimal(buff(6), buff(7)) dic("回差") = CombineTwoBytesToDecimal(buff(8), buff(9)) dic("传感器极大值") = CombineTwoBytesToDecimal(buff(10), buff(11)) dic("传感器极小值") = CombineTwoBytesToDecimal(buff(12), buff(13)) dic("预热时间_分") = CombineTwoBytesToDecimal(buff(14), buff(15)) dic("ADC_LEV_10") = CombineTwoBytesToDecimal(buff(16), buff(17)) dic("ADC_LEV_0") = CombineTwoBytesToDecimal(buff(18), buff(19)) dic("触发_消抖次数") = CombineTwoBytesToDecimal(buff(20), buff(21)) dic("释放_消抖次数") = CombineTwoBytesToDecimal(buff(22), buff(23)) dic("稳定阈值") = CombineTwoBytesToDecimal(buff(24), buff(25)) dic("报警点提前量") = CombineTwoBytesToDecimal(buff(26), buff(27)) dic("校准超时_秒") = CombineTwoBytesToDecimal(buff(28), buff(29)) dic("IHIOT_心跳包上报间隔") = CombineTwoBytesToDecimal(buff(30), buff(31)) dic("OSD显示模式") = CombineTwoBytesToDecimal(buff(32), buff(33)) dic("检测故障最小值") = CombineTwoBytesToDecimal(buff(34), buff(35)) dic("检测故障最大值") = CombineTwoBytesToDecimal(buff(36), buff(37)) dic("校准最小值_LEV_0") = CombineTwoBytesToDecimal(buff(38), buff(39)) dic("校准最大值_LEV_0") = CombineTwoBytesToDecimal(buff(40), buff(41)) dic("校准最小值_LEV_10") = CombineTwoBytesToDecimal(buff(42), buff(43)) dic("校准最大值_LEV_10") = CombineTwoBytesToDecimal(buff(44), buff(45)) dic("校准最小值_差值") = CombineTwoBytesToDecimal(buff(46), buff(47)) dic("校准最大值_差值") = CombineTwoBytesToDecimal(buff(48), buff(49)) dic("自定义LEV_10_对应的ADC") = CombineTwoBytesToDecimal(buff(50), buff(51)) dic("自定义LEV_0_对应的ADC") = CombineTwoBytesToDecimal(buff(52), buff(53)) dic("泄露恢复正常_条件2") = CombineTwoBytesToDecimal(buff(54), buff(55)) dic("泄露恢复正常_条件2消抖时间_分") = CombineTwoBytesToDecimal(buff(56), buff(57)) dic("设备生产时间") = CombineFourBytesToLong(buff(61), buff(60), buff(59), buff(58)) End If Case 3 '读取软件版本号 '04 软件版本号 '03 硬件板本号 ' 78 00 3E 00 0F 80 13 11 0C 80 UUID dic.Add("软件版本号", $"{Hex(buff(5))}") dic.Add("硬件版本号", $"{Hex(buff(6))}") dic.Add("设备类型ID", CombineTwoBytesToDecimal(buff(7), buff(8))) dic.Add("厂牌ID", CombineTwoBytesToDecimal(buff(9), buff(10))) dic.Add("机型ID", CombineTwoBytesToDecimal(buff(11), buff(12))) Dim uuid As String = "" For ni As Integer = 1 To buff(13) uuid += $"{Hex2(buff(13 + ni))} " Next dic.Add("UUID", $"{uuid}") Case 4 '读取实时状态 ' 02 00 状态机 - 正常监控 类型int16_t ' C6 1 实时值 - 类型int16_t ' C9 1 背景值 - 类型int16_t ' C6 1 基底值 - 类型int16_t ' FD FF 差值 - 类型int16_t ' 00 00 LEL百分比 - 类型int16_t ' 01 00 稳定状态 - 类型int16_t ' 0E A2 基底值差值百分比1 - 类型int16_t ' 3B A4 基底值+差值百分比2 - 类型int16_t ' 4C 00 温度 - 类型int16_t dic.Add("状态机", ReadTheStatus(CombineTwoBytesToDecimal(buff(5), buff(6)))) dic.Add("实时值", CombineTwoBytesToDecimal(buff(7), buff(8))) dic.Add("背景值", CombineTwoBytesToDecimal(buff(9), buff(10))) dic.Add("基底值", CombineTwoBytesToDecimal(buff(11), buff(12))) dic.Add("差值", CombineTwoBytesToDecimaShort(buff(13), buff(14))) dic.Add("LEL百分比", CombineTwoBytesToDecimal(buff(15), buff(16))) dic.Add("稳定状态", CombineTwoBytesToDecimal(buff(17), buff(18))) dic.Add("基底值差值百分比1", CombineTwoBytesToDecimal(buff(20), buff(19))) dic.Add("基底值差值百分比2", CombineTwoBytesToDecimal(buff(22), buff(21))) dic.Add("温度", CombineTwoBytesToDecimal(buff(23), buff(24))) Case 9 '读设备 key '[服务器key] Text, ' [服务器ClientId] TEXT, Dim src As Byte() = Slice(buff, 5, 4) If dic.ContainsKey("设备ClientId") Then dic.Item("设备ClientId") = BytesLE4ToInt(src) Else dic.Add("设备ClientId", BytesLE4ToInt(src)) End If src = Slice(buff, 9, buff(1) - 10) If dic.ContainsKey("设备key") Then dic.Item("设备key") = BytesToString(src) Else dic.Add("设备key", BytesToString(src)) End If Case Else dic.Item("测试结果") = "0" dic.Item("测试信息") = $"节点:{node.Item1} :接收数据未找到对应解析方式!" result = $"节点:{node.Item1} :接收数据未找到对应解析方式!" Exit For End Select Catch ex As Exception dic.Item("测试结果") = "0" dic.Item("测试信息") = $"节点:{node.Item1} :接收数据异常!" result = $"节点:{node.Item1} :接收数据异常!" Exit For End Try Else dic.Item("测试结果") = "0" dic.Item("测试信息") = $"节点:{node.Item1} :接收数据异常!" result = $"节点:{node.Item1} :接收数据异常!" Exit For End If Else '接收失败 dic.Item("测试结果") = "0" dic.Item("测试信息") = $"节点:{node.Item1} :接收失败!" result = $"节点:{node.Item1} :接收失败!" Exit For End If End If Else If node.Item2.SendStatus = SendNode.SendStatusEnum.None Then dic.Item("测试结果") = "0" dic.Item("测试信息") = $"失败 :设备无校准参数信息!" result = $"失败 :设备无校准参数信息!" ElseIf node.Item2.SendStatus = SendNode.SendStatusEnum.Timeout Then dic.Item("测试结果") = "0" dic.Item("测试信息") = $"节点:{node.Item1} :发送失败!" result = $"节点:{node.Item1} :发送失败!" End If Exit For End If Next Dim nstr As String = JsonConvert.SerializeObject(dic) '入库 WriteToTable(dic) Dim localConn As New DbConnectionStringBuilder localConn.Add("Data Source", Sqlitedbpath) Using db As New DbExecutor(DbExecutor.DbTypeEnum.Sqlite, localConn.ToString()) Try db.Open() Dim caint = db.ExecuteNonQuery(db.CmdHelper.Insert(SqliteTableName, dic)) If caint = 0 Then result = "Sqlite入库失败!" End If db.Close() Catch ex As Exception result = $"Sqlite入库失败!{ex.Message}" End Try db.Close() ' Return True End Using Using db As New DbExecutor(DbExecutor.DbTypeEnum.Mysql, DbConnString) Try db.Open() Dim caint = db.ExecuteNonQuery(db.CmdHelper.Insert(SqliteTableName, dic)) If caint = 0 Then result = "Mysql入库失败!" End If db.Close() Catch ex As Exception result = $"Mysql入库失败!{ex.Message}" End Try db.Close() ' Return True End Using Return result End Function ''' ''' 将 Byte 数组按 UTF-8 编码转成字符串。 ''' Public Function BytesToString(buf As Byte()) As String If buf Is Nothing Then Return "" Return System.Text.Encoding.UTF8.GetString(buf) End Function ''' ''' 从原数组截取部分数据为新数组。 ''' ''' 源数组 ''' 起始索引(0 起算) ''' 要截取的长度 Public Function Slice(Of T)(source As T(), start As Integer, length As Integer) As T() If source Is Nothing Then Return Nothing If start < 0 OrElse length <= 0 OrElse start + length > source.Length Then Return New T(-1) {} Dim dest(length - 1) As T Array.Copy(source, start, dest, 0, length) Return dest End Function ''' ''' 将 Byte 数组按指定编码转成字符串。 ''' 缺省编码为 UTF-8。 ''' ''' 源数组 ''' 编码,省略则 UTF-8 Public Function BytesToString(bytes As Byte(), Optional encoding As Text.Encoding = Nothing) As String If bytes Is Nothing OrElse bytes.Length = 0 Then Return "" If encoding Is Nothing Then encoding = System.Text.Encoding.UTF8 Return encoding.GetString(bytes) End Function Public Function BytesLE4ToInt(buf As Byte()) As Integer If buf Is Nothing OrElse buf.Length < 4 Then Return 0 Return buf(0) Or (buf(1) << 8) Or (buf(2) << 16) Or (buf(3) << 24) End Function '创建slqit Public Sqlitedbpath As String = FileCPatrh & "\SQlitedb\test.db" Public SqliteTableName As String = "NT318" Public Function ClearDeviceform() As Boolean Dim localConn As New DbConnectionStringBuilder localConn.Add("Data Source", Sqlitedbpath) 'localConn.Add("Password", "123456") Dim LocalConnString = localConn.ToString() '判断有没有文件夹 If Not Directory.Exists(FileCPatrh & "\SQlitedb\") Then Directory.CreateDirectory(FileCPatrh & "\SQlitedb\") End If Dim selectstr As String = $"CREATE TABLE IF NOT EXISTS {SqliteTableName} ( id INTEGER PRIMARY KEY AUTOINCREMENT, -- 替代 BIGINT AUTO_INCREMENT `测试时间` TEXT NOT NULL, -- DATETIME → TEXT (ISO-8601) `测试结果` INTEGER NOT NULL, `测试信息` TEXT NOT NULL, `软件版本号` TEXT NOT NULL, `硬件版本号` TEXT NOT NULL, `设备类型ID` INTEGER NOT NULL, `厂牌ID` INTEGER NOT NULL, `机型ID` INTEGER NOT NULL, `UUID` TEXT NOT NULL, `设备key` TEXT NOT NULL, `设备ClientId` INTEGER NOT NULL, `服务器key` TEXT NOT NULL, `服务器ClientId` INTEGER NOT NULL, `状态机` TEXT NOT NULL, `实时值` INTEGER NOT NULL, `背景值` INTEGER NOT NULL, `基底值` INTEGER NOT NULL, `差值` INTEGER NOT NULL, `LEL百分比` INTEGER NOT NULL, `稳定状态` INTEGER NOT NULL, `基底值差值百分比1` INTEGER NOT NULL, `基底值差值百分比2` INTEGER NOT NULL, `温度` INTEGER NOT NULL, `校准结果` INTEGER NOT NULL, `温度校准算法选择` INTEGER NOT NULL, `回差` INTEGER NOT NULL, `传感器极大值` INTEGER NOT NULL, `传感器极小值` INTEGER NOT NULL, `预热时间_分` INTEGER NOT NULL, `ADC_LEV_10` INTEGER NOT NULL, `ADC_LEV_0` INTEGER NOT NULL, `触发_消抖次数` INTEGER NOT NULL, `释放_消抖次数` INTEGER NOT NULL, `稳定阈值` INTEGER NOT NULL, `报警点提前量` INTEGER NOT NULL, `校准超时_秒` INTEGER NOT NULL, `IHIOT_心跳包上报间隔` INTEGER NOT NULL, `OSD显示模式` INTEGER NOT NULL, `检测故障最小值` INTEGER NOT NULL, `检测故障最大值` INTEGER NOT NULL, `校准最小值_LEV_0` INTEGER NOT NULL, `校准最大值_LEV_0` INTEGER NOT NULL, `校准最小值_LEV_10` INTEGER NOT NULL, `校准最大值_LEV_10` INTEGER NOT NULL, `校准最小值_差值` INTEGER NOT NULL, `校准最大值_差值` INTEGER NOT NULL, `自定义LEV_10_对应的ADC` INTEGER NOT NULL, `自定义LEV_0_对应的ADC` INTEGER NOT NULL, `泄露恢复正常_条件2` INTEGER NOT NULL, `泄露恢复正常_条件2消抖时间_分` INTEGER NOT NULL, `设备生产时间` TEXT NOT NULL, `RTC时间` TEXT NOT NULL, `RTC星期` INTEGER NOT NULL, created_at TEXT DEFAULT (datetime('now')) );" Dim dt As DataTable Try Using db As New DbExecutor(DbExecutor.DbTypeEnum.Sqlite, LocalConnString) db.Open() 'Try ' 'Dim vselectstr = $"DELETE FROM {Tftp_Log};" ' 'db.ExecuteNonQuery(vselectstr) 'Catch ex As Exception 'End Try dt = db.ExecuteDataTable(selectstr) db.Close() If IsNothing(dt) Then MsgBox($"数据表创建失败!!!{vbCrLf }") Return False Else Return True End If Return True End Using Catch ex As Exception MsgBox($"数据表创建失败!!!{vbCrLf }原因:{vbCrLf }{ex.Message }") Return False End Try End Function Delegate Sub DelegateWriteToTable(dic As Dictionary(Of String, String)) '写入到表格 Private Sub WriteToTable(dic As Dictionary(Of String, String)) If Me.InvokeRequired = True Then Dim dd As New DelegateWriteToTable(AddressOf WriteToTable) Me.Invoke(dd, {dic}) Else Grid_table.AddItem("") Dim con As Integer = 0 Dim str As String = String.Empty For i = 1 To Grid_table.Cols - 1 str = Grid_table.Cell(0, i).Text If dic.ContainsKey(str) Then Grid_table.Cell(Grid_table.Rows - 1, i).Text = dic(str) Else con += 1 End If Next If dic.Item("测试结果") = "1" Then Grid_table.Range(Grid_table.Rows - 1, 1, Grid_table.Rows - 1, Grid_table.Cols - 1).ForeColor = Color.Green Grid_table.Range(Grid_table.Rows - 1, 1, Grid_table.Rows - 1, Grid_table.Cols - 1).FontBold = True Else Grid_table.Range(Grid_table.Rows - 1, 1, Grid_table.Rows - 1, Grid_table.Cols - 1).ForeColor = Color.Red Grid_table.Range(Grid_table.Rows - 1, 1, Grid_table.Rows - 1, Grid_table.Cols - 1).FontBold = True End If End If End Sub '计算将4个字节合成 Long UTC秒值并转为时间戳 Private Function CombineFourBytesToLong(ByVal b1 As Byte, ByVal b2 As Byte, ByVal b3 As Byte, ByVal b4 As Byte) As String '将4个字节合成 Long UTC秒值并转为时间戳 Dim temp_val As Long = b1 * 256 * 256 * 256 + b2 * 256 * 256 + b3 * 256 + b4 '计算UTC时间 Return $"{DateAndTime.DateSerial(1970, 1, 1).AddSeconds(temp_val).ToString("yyyy-MM-dd HH:mm:ss")}" End Function '将2个字节 合成十进制数 Private Function CombineTwoBytesToDecimal(ByVal b1 As Byte, ByVal b2 As Byte) As Integer Return b2 * 256 + b1 End Function Private Function CombineTwoBytesToDecimaShort(ByVal b1 As Byte, ByVal b2 As Byte) As Short Dim s As Short = b2 s = s << 8 s += b1 Return s End Function '获取校准结果 Private Function ReadTheCalibrationResult(Statebyte As Byte) As String If Statebyte = 0 Then Return "0_校准成功" Else Return $"{Statebyte}_校准失败" End If End Function '获取状态机状态 Private Function ReadTheStatus(Statebyte As Byte) As String ' 状态机 '#define DevAPP_PowerOn_Start 0x00 //设备状态 - 上电启动 '#define DevAPP_Preheat 0x01 //设备状态 - 预热 '#define DevAPP_Normal_Operation 0x02 //设备状态 - 正常监控 '#define DevAPP_Leak_Detected 0x03 //设备状态 - 检测到泄露 '#define DevAPP_Alarm 0x04 //设备状态 - 报警 '#define DevAPP_Malfunction 0x05 //设备状态 - 故障 '#define DevAPP_Expiration_Of_Life 0x06 //设备状态 - 寿命到期 '#define DevAPP_Calibration_Mode 0x07 //设备状态 - 校准模式 '#define DevAPP_Uncalibrated 0x08 //设备状态 - 未校准 '#define DevApp_Equipment_Outage 0x09 //设备状态 - 220V电源断开 '#define DevApp_SelfCheck_Mode 0x0A //设备状态 - 自检模式 '#define DevApp_Pairing_Mode 0x0B //设备状态 - 无线配对模式 Select Case Statebyte Case &H0 Return $"{Hex(Statebyte)}_上电启动" Case &H1 Return $"{Hex(Statebyte)}_预热" Case &H2 Return $"{Hex(Statebyte)}_正常监控" Case &H3 Return $"{Hex(Statebyte)}_检测到泄露" Case &H4 Return $"{Hex(Statebyte)}_报警" Case &H5 Return $"{Hex(Statebyte)}_故障" Case &H6 Return $"{Hex(Statebyte)}_寿命到期" Case &H7 Return $"{Hex(Statebyte)}_校准模式" Case &H8 Return $"{Hex(Statebyte)}_未校准" Case &H9 Return $"{Hex(Statebyte)}_220V电源断开" Case &HA Return $"{Hex(Statebyte)}_自检模式" Case &HB Return $"{Hex(Statebyte)}_无线配对模式" End Select End Function Private Function SendPortData1(Name As String, node As SendNode) As String Dim sendBytes As Byte() Dim result As String = String.Empty Try '获取发送内容 sendBytes = GetSendPortData1(Name) If sendBytes Is Nothing OrElse sendBytes.Length = 0 Then result = $"节点:{Name} :发送数据为空!" ' RefreshCaptureText(Color.Red, result) End If '设置发送节点发送的数据 node.SetSendData(sendBytes) SerialPort.Write(node.SendData, 0, node.SendData.Length) '发送刷新对应数值 node.ResendRefresh() 'RefreshCaptureText(Color.Green, result) Catch ex As Exception result = $"发送:【{Name}】失败!{vbCrLf}详情:{vbCrLf}{ex.Message}" 'RefreshCaptureText(Color.Red, result) End Try Return result End Function '获取发送内容 Public RTC_Time As Date Private Function GetSendPortData1(name As String) As Byte() Dim sendBytes As Byte() If name.Equals("设置RTC时间") Then sendBytes = GetSetRTCTime() ElseIf name.Equals("设置生产时间") Then sendBytes = GetSetUTCTime() ElseIf name.Equals("设置设备key") Then sendBytes = SetDeviceKey() ElseIf CommandSetDic.ContainsKey(name) Then sendBytes = CommandSetDic.Item(name) End If Return sendBytes End Function Private Function SetDeviceKey() As Byte() Dim li As New List(Of Byte) li.Add(&HAE) li.Add(&H0) '长度 li.Add(&H0) '校验 li.Add(&H1) '命令 - 设置参数 li.Add(&H9) '参数内容 - 设置RTC时间 Dim ifnode As (String, SendNode) For i As Integer = SendNodeDic.Count - 1 To 0 Step -1 ifnode = SendNodeDic(i) If ifnode.Item1.Equals("获取服务器key") AndAlso ifnode.Item2.RecvStatus = SendNode.RecvStatusEnum.Recv Then Exit For End If Next If Not IsNothing(ifnode) AndAlso ifnode.Item1.Equals("获取服务器key") AndAlso ifnode.Item2.RecvStatus = SendNode.RecvStatusEnum.Recv Then Dim apinode As Program = ifnode.Item2.RecvDatadic li.AddRange(IntTo4BytesLE(apinode.Response.ClientId)) li.AddRange(StringToBytes(apinode.Response.SecretKey)) li.Add(&HEA) li(1) = li.Count li(2) = GetSumCheckMod(li.ToArray, li.Count) Return li.ToArray Else Return Nothing End If End Function Private Sub ToolStripButton2_Click(sender As Object, e As EventArgs) Handles ToolStripButton2.Click Dim isvisible As Boolean = False If ToolStripButton2.Text.Equals(">>") Then '弹窗获取密码 Dim password As String = InputBox("请输入密码:", "密码验证") If Not password.Trim.Equals("Cc2025OK") Then Return End If isvisible = True ToolStripButton2.Text = "<<" Else isvisible = False ToolStripButton2.Text = ">>" End If GroupBox1.Visible = isvisible ToolStripLabel1.Visible = isvisible T_CommandAlias.Visible = isvisible ToolStripLabel2.Visible = isvisible ToolStripTextBox2.Visible = isvisible ToolStripButton1.Visible = isvisible ToolStripComboBox1.Visible = isvisible SplitContainer4.Panel1Collapsed = Not isvisible ComboBox9.Visible = isvisible LblSerialPortBaud.Visible = isvisible ToolStripButton4.Visible = isvisible ToolStripButton5.Visible = isvisible ToolStripButton6.Visible = isvisible ToolStripLabel3.Visible = isvisible ToolStripTextBox1.Visible = isvisible '设置TabControl1 的第1、2个选项卡 显示状态为隐藏或显示 If (isvisible) Then TabPage1.Parent = TabControl1 TabPage2.Parent = TabControl1 Else TabPage1.Parent = Nothing TabPage2.Parent = Nothing End If For i As Integer = 0 To Grid_table.Cols - 1 If i > 6 Then Grid_table.Column(i).Visible = isvisible End If Next End Sub Private Sub ToolStripComboBox1_DropDown(sender As Object, e As EventArgs) Handles ToolStripComboBox1.DropDown If IsNothing(CommandSetDic) OrElse CommandSetDic.Count = 0 Then Return ToolStripComboBox1.Items.Clear() ToolStripComboBox1.Items.AddRange(CommandSetDic.Keys.ToArray()) End Sub Private Sub ProcessTable_CellChange(Sender As Object, e As Grid.CellChangeEventArgs) Handles ProcessTable.CellChange 'ProcessTable.Cell(0, 0).Text = "序号" 'ProcessTable.Cell(0, 1).Text = "勾选" 'ProcessTable.Cell(0, 2).Text = "命令别名" 'ProcessTable.Cell(0, 3).Text = "命令" 'ProcessTable.Cell(0, 4).Text = "发送状态" If e.Row = 0 Then Return Select Case e.Col Case 2 If CommandSetDic.ContainsKey(ProcessTable.Cell(e.Row, 2).Text.Trim) Then Dim strbuf() As Byte = CommandSetDic(ProcessTable.Cell(e.Row, 2).Text.Trim) Dim str As String = ByteArrayToHexString(strbuf) ProcessTable.Cell(e.Row, 3).Text = str Else MsgBox("命令别名不存在,请先添加别名和对应命令到命令集,再调用!!") ProcessTable.Cell(e.Row, 2).Text = "" End If End Select End Sub Private Sub ToolStripButton5_Click(sender As Object, e As EventArgs) Handles ToolStripButton5.Click If ProcessTable.ActiveCell.Row < 1 Then ProcessTable.AddItem("") Else ProcessTable.InsertRow(ProcessTable.ActiveCell.Row, 1) End If End Sub Private Sub ToolStripButton6_Click(sender As Object, e As EventArgs) Handles ToolStripButton6.Click If ProcessTable.ActiveCell.Row < 1 Then ProcessTable.Row(ProcessTable.Rows - 1).Delete() Else ProcessTable.Row(ProcessTable.ActiveCell.Row).Delete() End If End Sub Private Sub ToolStripButton4_Click(sender As Object, e As EventArgs) Handles ToolStripButton4.Click InitLoadProcessTable(False) End Sub Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed My.Settings.SerialPortName = ComboBox8.Text My.Settings.SInTime = ToolStripTextBox1.Text My.Settings.Save() Timer2.Stop() Timer1.Stop() SaveCommandSetDic() End Sub Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick Label39.Text = Now.ToString("yyyy-MM-dd") Label40.Text = Now.ToString("HH:mm:ss") Select Case Now.DayOfWeek Case 0, 7 Label41.Text = "星期日" Case 1 Label41.Text = "星期一" Case 2 Label41.Text = "星期二" Case 3 Label41.Text = "星期三" Case 4 Label41.Text = "星期四" Case 5 Label41.Text = "星期五" Case 6 Label41.Text = "星期六" End Select 'Label41.Text = $"星期{ Now.DayOfWeek }" End Sub Public Timediffe As Integer = 2 Private Sub ToolStripTextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles ToolStripTextBox1.KeyPress '限制输入只能为数字 If e.KeyChar < "0"c OrElse e.KeyChar > "9"c Then e.Handled = True End If End Sub Private Sub ToolStripTextBox1_TextChanged(sender As Object, e As EventArgs) Handles ToolStripTextBox1.TextChanged If Integer.TryParse(ToolStripTextBox1.Text, Timediffe) Then Else ToolStripTextBox1.Text = "2" Timediffe = 2 End If End Sub #End Region End Class Public Class SendNode '发送时间 Public Property SendTime As DateTime '发送数据 Public Property SendData As Byte() '重发次数 Public Property SendCount As Integer '重发间隔 Public Property SendInterval As Integer '超时时间 Public Property SendTimeout As Integer '发送状态 0:未发送 1:已发送 Public Property SendStatus As Integer '接收状态 Public Property RecvStatus As Integer '接收数据 Public Property RecvDataLisr As List(Of Byte()) Public Property RecvDatadic As Object Sub New() RecvDataLisr = New List(Of Byte()) End Sub '发送状态枚举值 Enum SendStatusEnum '未发送 None = 0 '已发送 Send = 1 '发送超时 Timeout = 2 End Enum '接收状态枚举值 Enum RecvStatusEnum '未接收 None = 0 '已接收 Recv = 1 '接收超时 Timeout = 2 End Enum Sub New(Mysenddata() As Byte) SendData = Mysenddata SendInterval = 0 SendTimeout = 1000 RecvStatus = 0 SendStatus = 0 RecvDataLisr = New List(Of Byte()) End Sub '设置发送数据 Sub SetSendData(Mysenddata() As Byte) SendData = Mysenddata SendInterval = 0 SendTimeout = 1000 RecvStatus = 0 SendStatus = 0 End Sub '接收数据并添加到接收列表 Sub AddRecvData(RecvData() As Byte) If RecvDataLisr Is Nothing Then RecvDataLisr = New List(Of Byte()) End If RecvDataLisr.Add(RecvData) End Sub '判断需不需要重发 False 不需要重发 True 需要重发 Function NeedResend() As Boolean '如果接收状态为已加收, 则不需要重发 If SendStatus = 1 AndAlso RecvStatus = 1 Then Return False Else '如果发送状态为已发送,则判断是否超时,如果超时则返回True,否则返回False If SendStatus = 1 Then '判断是否到达最大重发次数 If SendCount < 3 Then If SendTime.AddMilliseconds(SendTimeout) < Now Then Return True Else Return False End If Else RecvStatus = RecvStatusEnum.Timeout SendStatus = SendStatusEnum.Timeout Return False End If Else Return True End If End If End Function '重发刷新对应数值 Sub ResendRefresh() SendStatus = 1 SendCount += 1 SendTime = Now End Sub '发送刷新对应数值 Sub SendRefresh() SendStatus = 1 SendTime = Now SendCount = 0 End Sub '接收刷新对应数值 Sub RecvRefresh(Mysenddata() As Byte) AddRecvData(Mysenddata) RecvStatus = 1 End Sub End Class