1377 lines
60 KiB
VB.net
1377 lines
60 KiB
VB.net
Imports System.Net
|
||
Imports System.Text
|
||
Imports BLV_Studio.GridModel.DeviceEventModel
|
||
Imports BLV_Studio.TestForm1
|
||
|
||
Public Class TableCompile
|
||
|
||
Public _sceneIndex As UShort
|
||
Public _actionIndex As UShort
|
||
''' <summary>
|
||
''' 别名转换所使用的编码格式,默认方式GBK
|
||
''' </summary>8
|
||
Public Property AliasEncoding As Text.Encoding
|
||
Sub New()
|
||
AliasEncoding = Encoding.GetEncoding("GBK")
|
||
_actionIndex = 1
|
||
_sceneIndex = 1
|
||
End Sub
|
||
Public Function FillConfigInfo(configInfo As ConfigInfoStuct, Name As String) As List(Of Byte)
|
||
Dim resultDatas As New List(Of Byte())
|
||
Dim cmd As Byte = &H1
|
||
Dim buf As List(Of Byte) = New List(Of Byte)
|
||
|
||
'填充配置信息
|
||
'configInfo.Author = Account '配置发布作者
|
||
'configInfo.ConfigToolVersion = Application.ProductVersion '配置软件版本号’
|
||
'configInfo.ReleaseDate = date_now '发布日期
|
||
'configInfo.HotelName = _project.HotelName '项目名称’
|
||
'configInfo.HotelCode = _project.HotelCode '项目代号
|
||
'configInfo.HotelGroupName = _project.VerdorName '项目分组
|
||
'configInfo.RoomTypeName = _project.RoomType(g_CurrentTreeNodeRoomTypeItemIndex).structRoomType_Name '房型别名
|
||
'configInfo.CfgFileVersion = _project.RoomType(g_CurrentTreeNodeRoomTypeItemIndex).structRoomType_ConfigVersion + 1 '配置版本号加一
|
||
Dim arrayCopyLenght As Integer = 0
|
||
|
||
'命令
|
||
buf.Add(cmd)
|
||
|
||
'发布作者 P0~31
|
||
Dim bytesAuthor() As Byte = AliasEncoding.GetBytes(configInfo.Author.Trim)
|
||
Dim bytesAuthor_32bytes(31) As Byte
|
||
|
||
If bytesAuthor.Length <= 32 Then
|
||
arrayCopyLenght = bytesAuthor.Length
|
||
Else
|
||
arrayCopyLenght = 32
|
||
End If
|
||
Array.Copy(bytesAuthor, bytesAuthor_32bytes, arrayCopyLenght)
|
||
|
||
buf.AddRange(bytesAuthor_32bytes)
|
||
|
||
|
||
'软件版本号 P32~35
|
||
'Dim strConfigToolsVersion As String = Replace(configInfo.ConfigToolVersion, ".", "", 1, 4)
|
||
'Dim byetConfigToolsVersion() As Byte = System.Text.Encoding.UTF8.GetBytes(strConfigToolsVersion)
|
||
Dim ByteConfigToolsVersion() As String = configInfo.ConfigToolVersion.Split(".")
|
||
Dim byetConfigToolsVersion(3) As Byte
|
||
byetConfigToolsVersion(0) = Val(ByteConfigToolsVersion(0))
|
||
byetConfigToolsVersion(1) = Val(ByteConfigToolsVersion(1))
|
||
byetConfigToolsVersion(2) = Val(ByteConfigToolsVersion(2))
|
||
byetConfigToolsVersion(3) = Val(ByteConfigToolsVersion(3))
|
||
|
||
buf.AddRange(byetConfigToolsVersion)
|
||
|
||
'配置发布日期 P36~42
|
||
'Dim strReleaseDate As String = Format(configInfo.ReleaseDate, "yyyyMMddHHmmss")
|
||
'Dim byteReleaseDate() = System.Text.Encoding.UTF8.GetBytes(strReleaseDate)
|
||
Dim byteReleaseDate(6) As Byte '
|
||
byteReleaseDate(0) = configInfo.ReleaseDate.Year \ 256 'yy H
|
||
byteReleaseDate(1) = configInfo.ReleaseDate.Year Mod 256 'yy L
|
||
byteReleaseDate(2) = configInfo.ReleaseDate.Month 'Month
|
||
byteReleaseDate(3) = configInfo.ReleaseDate.Day 'd
|
||
byteReleaseDate(4) = configInfo.ReleaseDate.Hour 'h
|
||
byteReleaseDate(5) = configInfo.ReleaseDate.Minute 'm
|
||
byteReleaseDate(6) = configInfo.ReleaseDate.Second 's
|
||
|
||
buf.AddRange(byteReleaseDate)
|
||
|
||
'项目名称 P43~74
|
||
Dim byteHotelName() As Byte = AliasEncoding.GetBytes(configInfo.HotelName.Trim)
|
||
Dim byteHotelName_32Bytes(31) As Byte
|
||
|
||
If byteHotelName.Length <= 32 Then
|
||
arrayCopyLenght = byteHotelName.Length
|
||
Else
|
||
arrayCopyLenght = 32
|
||
End If
|
||
Array.Copy(byteHotelName, byteHotelName_32Bytes, arrayCopyLenght)
|
||
|
||
buf.AddRange(byteHotelName_32Bytes)
|
||
|
||
|
||
'项目编号 P75~78
|
||
Dim byteHotelCode() As Byte = iByte4(configInfo.HotelCode)
|
||
|
||
buf.AddRange(byteHotelCode)
|
||
|
||
'项目分组 P79~110
|
||
Dim byteHoteGroupName() As Byte = AliasEncoding.GetBytes(configInfo.HotelGroupName.Trim)
|
||
Dim byteHoteGroupName_32Bytes(31) As Byte
|
||
|
||
If byteHoteGroupName.Length <= 32 Then
|
||
arrayCopyLenght = byteHoteGroupName.Length
|
||
Else
|
||
arrayCopyLenght = 32
|
||
End If
|
||
Array.Copy(byteHoteGroupName, byteHoteGroupName_32Bytes, arrayCopyLenght)
|
||
|
||
buf.AddRange(byteHoteGroupName_32Bytes)
|
||
|
||
'房型别名 P111~142
|
||
Dim byteRoomTypeName() As Byte = AliasEncoding.GetBytes(configInfo.RoomTypeName.Trim)
|
||
Dim byteRoomTypeName_32Bytes(31) As Byte
|
||
|
||
If byteRoomTypeName.Length <= 32 Then
|
||
arrayCopyLenght = byteRoomTypeName.Length
|
||
Else
|
||
arrayCopyLenght = 32
|
||
End If
|
||
Array.Copy(byteRoomTypeName, byteRoomTypeName_32Bytes, arrayCopyLenght)
|
||
|
||
buf.AddRange(byteRoomTypeName_32Bytes)
|
||
|
||
|
||
'配置版本号 P143~146
|
||
'Dim byteConfigFileVersion() As Byte = iByte4(configInfo.CfgFileVersion)
|
||
'buf.AddRange(byteConfigFileVersion)
|
||
|
||
'Momo 2022-09-06 配置版本号只有3位 P143~145
|
||
Dim byteConfigFileVersion() As Byte = iByte3(configInfo.CfgFileVersion)
|
||
buf.AddRange(byteConfigFileVersion)
|
||
|
||
'配置机型 P146~P209 MCU机型名称 64
|
||
Dim tmpModelName As String = Name.Trim
|
||
'MsgBox(tmpModelName)
|
||
Dim byteModelName() As Byte = AliasEncoding.GetBytes(tmpModelName)
|
||
Dim byteModelName_64Bytes(63) As Byte
|
||
|
||
If byteModelName.Length <= 64 Then
|
||
arrayCopyLenght = byteModelName.Length
|
||
Else
|
||
arrayCopyLenght = 64
|
||
End If
|
||
Array.Copy(byteModelName, byteModelName_64Bytes, arrayCopyLenght)
|
||
|
||
buf.AddRange(byteModelName_64Bytes)
|
||
|
||
|
||
'完成配置数据添加
|
||
Return buf 'resultDatas
|
||
End Function
|
||
''' <summary>
|
||
''' Integer 类型转 4 字节 byte数组,高字节在前
|
||
''' </summary>
|
||
''' <param name="i"></param>
|
||
''' <returns></returns>
|
||
Public Function iByte4(ByVal i As Integer) As Byte()
|
||
Dim btemp() As Byte = {0, 0, 0, 0}
|
||
Dim b() As Byte = BitConverter.GetBytes(i)
|
||
btemp(3) = b(3)
|
||
btemp(2) = b(2)
|
||
btemp(1) = b(1)
|
||
btemp(0) = b(0)
|
||
Return btemp
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' Integer 类型转 3 字节 byte数组,高字节在前
|
||
''' </summary>
|
||
''' <param name="i"></param>
|
||
''' <returns></returns>
|
||
Public Function iByte3(ByVal i As Integer) As Byte()
|
||
Dim btemp() As Byte = {0, 0, 0}
|
||
Dim b() As Byte = BitConverter.GetBytes(i)
|
||
btemp(2) = b(2)
|
||
btemp(1) = b(1)
|
||
btemp(0) = b(0)
|
||
Return btemp
|
||
End Function
|
||
|
||
|
||
|
||
|
||
|
||
'' <summary>
|
||
'' 填充设备存在
|
||
'' </summary>
|
||
'' <returns></returns>
|
||
Public Function FillDeviceExistsData(ByRef DeviceModuleDic As Dictionary(Of String, DeviceModel), SwitchConfig As Dictionary(Of String, Dictionary(Of Integer, String))) As List(Of Byte())
|
||
Dim resultDatas As New List(Of Byte())
|
||
Dim cmd As Byte = &H3
|
||
Dim buf As List(Of Byte)
|
||
|
||
For Each Fnode In DeviceModuleDic.Values
|
||
|
||
' 配置RCU模型设备存在数据
|
||
If String.IsNullOrEmpty(Fnode.Desc.DevInterface) Then
|
||
buf = New List(Of Byte)
|
||
buf.Add(cmd)
|
||
Dim tmpBuffer() As Byte = FillRCUModelDeviceExsist(Fnode)
|
||
buf.AddRange(tmpBuffer)
|
||
resultDatas.Add(buf.ToArray)
|
||
'PrintInfo(" 主机模型 编译完成,长度:" & tmpBuffer.Count & " Bytes")
|
||
Else
|
||
Dim tmpBufferLst As List(Of Byte()) = FillExternalModelDeviceExsist(Fnode, DeviceModuleDic.Values(0))
|
||
Dim tmpOutData As Byte()
|
||
For i = 0 To tmpBufferLst.Count - 1
|
||
tmpOutData = tmpBufferLst(i).ToArray
|
||
resultDatas.Add(tmpOutData.ToArray)
|
||
Next
|
||
End If
|
||
|
||
For Each Ccnode In Fnode.Config
|
||
If Not IsNothing(Ccnode.CFG_Type) AndAlso Ccnode.CFG_Type.Equals("DeviceExists") Then
|
||
buf = New List(Of Byte)
|
||
Console.WriteLine(Ccnode.Name)
|
||
buf.Add(cmd)
|
||
Dim tmpBuffer() As Byte = FillModeDeviceExsist(Ccnode, Fnode)
|
||
buf.AddRange(tmpBuffer)
|
||
resultDatas.Add(buf.ToArray)
|
||
'PrintInfo(" 设备存在 编译完成,长度:" & tmpBuffer.Count & " Bytes")
|
||
End If
|
||
Next
|
||
|
||
|
||
|
||
'For Each Cnode In Fnode.Nodes
|
||
' If Cnode.Name.Equals("DI") Then
|
||
' '485外设 03 加到每个设备组数据块前面
|
||
' 'Dim tmpBufferLst As List(Of Byte()) = FillExternalModelDeviceExsist(node, OutDevlist)
|
||
|
||
' 'Dim tmpOutData As Byte()
|
||
' 'For i = 0 To tmpBufferLst.Count - 1
|
||
' ' tmpOutData = tmpBufferLst(i).ToArray
|
||
' ' Console.WriteLine("FillDeviceExistsData.outBuff( " & i & ": " & BitConverter.ToString(tmpOutData).Replace("-", " "))
|
||
' ' resultDatas.Add(tmpOutData.ToArray)
|
||
' ' 'PrintInfo(" 编译完成,长度:" & tmpOutData.Count & " Bytes")
|
||
' 'Next
|
||
' 'Continue For
|
||
' End If
|
||
'Next
|
||
|
||
Next
|
||
Return resultDatas
|
||
End Function
|
||
|
||
|
||
|
||
|
||
|
||
|
||
Private Function FillExternalModelDeviceExsist(pNode As DeviceModel, hostNode As DeviceModel) As List(Of Byte())
|
||
Dim outDataLst As New List(Of Byte()) '输出数据列表
|
||
Dim strObjGroupNodesTypedataAndProtocol As String = ""
|
||
|
||
Dim baudData(3) As Byte '波特率(4字节)
|
||
Dim retryTimeData(1) As Byte '重发次数(2字节)
|
||
Dim keepParam(59) As Byte '保留字段(32字节) -> 2022-05-28 V3.1 32bytes->64Bytes
|
||
Dim ipadd(3) As Byte
|
||
Dim ObjGroupNodesInOutDic As New Dictionary(Of String, List(Of Byte)) '键值对,用于保存合并后的数据,Val = 设备组编译后的byte数组
|
||
Dim ObjGroupNodesInputCnt As New Dictionary(Of String, UInt16) '键值对,用于保存合并后的输入回路数,Val = 设备组编译后的byte数组
|
||
Dim ObjGroupNodesoutputCnt As New Dictionary(Of String, UInt16) '键值对,用于保存合并后的输出回路数,Val = 设备组编译后的byte数组
|
||
|
||
Dim ObjGroupNodesInpuSettings As New Dictionary(Of String, List(Of Byte)) '用于保存合并后输入设定数组
|
||
Dim ObjGroupNodesOutputAliases As New Dictionary(Of String, List(Of Byte)) '用于保存合并后输出别名数组
|
||
|
||
'添加设备组公共信息
|
||
Dim Baudrate() As String = FindAttributeValueUnderModel(pNode, "设备存在", "波特率").Split(" ")
|
||
baudData = BitConverter.GetBytes(CInt(Baudrate(1)))
|
||
retryTimeData = BitConverter.GetBytes(CShort(FindAttributeValueUnderModel(pNode, "设备存在", "重发时间")))
|
||
Dim tmpAddr As Byte = CInt(FindAttributeValueUnderModel(pNode, "设备存在", "拨码地址")) '设备地址(1字节)
|
||
Dim hostAddr As Byte = CInt(FindNodeValueUnderModel(hostNode, "RS485", pNode.Desc.DevInterface)) '设备地址(1字节)
|
||
For Each cnode In pNode.Nodes
|
||
strObjGroupNodesTypedataAndProtocol = cnode.DEV_TYPE_DATA & "," & cnode.PROTOCOL_VER
|
||
If ObjGroupNodesInOutDic.ContainsKey(strObjGroupNodesTypedataAndProtocol) = False Then
|
||
'添加输出合并设备键值对’
|
||
ObjGroupNodesInOutDic.Add(strObjGroupNodesTypedataAndProtocol, New List(Of Byte))
|
||
ObjGroupNodesInputCnt.Add(strObjGroupNodesTypedataAndProtocol, 0) '输入回路数 = 0
|
||
ObjGroupNodesoutputCnt.Add(strObjGroupNodesTypedataAndProtocol, 0) '输出回路数 = 0
|
||
ObjGroupNodesInpuSettings.Add(strObjGroupNodesTypedataAndProtocol, New List(Of Byte))
|
||
ObjGroupNodesOutputAliases.Add(strObjGroupNodesTypedataAndProtocol, New List(Of Byte))
|
||
|
||
With ObjGroupNodesInOutDic(strObjGroupNodesTypedataAndProtocol)
|
||
.Add(&H3) '设备存在,每个数据块前面都加上 &H03
|
||
.Add(CByte(cnode.DEV_TYPE_DATA)) '设备类型(1字节)
|
||
|
||
.Add(tmpAddr)
|
||
'PrintInfo(" *** 设备地址:" & tmpAddr.ToString)
|
||
|
||
.Add(hostAddr) '485端口(1字节)
|
||
.AddRange(baudData) '波特率(4字节)
|
||
.Add(CByte(cnode.PROTOCOL_VER)) '协议版本(1字节)
|
||
.Add(CInt(FindAttributeValueUnderModel(pNode, "设备存在", "重发次数"))) '重发次数(1字节)
|
||
.AddRange(retryTimeData) '重发间隔(2字节)
|
||
If cnode.DEV_TYPE_DATA.Equals("42") Then
|
||
Dim ipAddr As IPAddress = IPAddress.Parse(FindAttributeValueUnderModel(pNode, "设备存在", "中控IP地址")) '设备地址(1字节)
|
||
ipadd = ipAddr.GetAddressBytes()
|
||
' PrintInfo(" 中控IP地址 IPadd :" & ipAddr.ToString)
|
||
ElseIf cnode.DEV_TYPE_DATA.Equals("43") Then
|
||
Dim ipAddr As IPAddress = IPAddress.Parse(FindAttributeValueUnderModel(pNode, "设备存在", "域控IP地址")) '设备地址(1字节)
|
||
ipadd = ipAddr.GetAddressBytes()
|
||
' PrintInfo(" 域控IP地址 IPadd :" & ipAddr.ToString)
|
||
End If
|
||
.AddRange(ipadd)
|
||
.AddRange(keepParam)
|
||
End With
|
||
|
||
End If
|
||
|
||
'遍历设备
|
||
For Each objNode In cnode.Nodes
|
||
|
||
Select Case objNode.Interface
|
||
Case "DI"
|
||
ObjGroupNodesInputCnt(strObjGroupNodesTypedataAndProtocol) += 1 '输入回路数+1
|
||
ObjGroupNodesInpuSettings(strObjGroupNodesTypedataAndProtocol).AddRange(GetDeviceObjectSetting())'输入回路设定’
|
||
Case "DO"
|
||
Dim tmpDevAlias As String = String.Empty
|
||
If Not String.IsNullOrEmpty(objNode.DefaultAliasName) Then
|
||
tmpDevAlias = objNode.DefaultAliasName
|
||
End If
|
||
|
||
|
||
'If String.IsNullOrEmpty(tmpDevAlias) Then Continue For '未命名别名的输出设备不参与编译
|
||
Dim aliasData() As Byte = AliasEncoding.GetBytes(tmpDevAlias)
|
||
ReDim Preserve aliasData(31) 'caocong 2022-06-07 修改别名长度16Byte -> 32Byte
|
||
ObjGroupNodesoutputCnt(strObjGroupNodesTypedataAndProtocol) += 1 '输出回路数+1’
|
||
ObjGroupNodesOutputAliases(strObjGroupNodesTypedataAndProtocol).AddRange(aliasData) '输出回路别名’
|
||
Case Else
|
||
Continue For
|
||
End Select
|
||
Next
|
||
|
||
|
||
|
||
Next
|
||
|
||
|
||
|
||
|
||
|
||
'遍历合并后的设备组(保存于键值对中)
|
||
For Each strKey As String In ObjGroupNodesInOutDic.Keys
|
||
Dim inputCnt As UInt16 = ObjGroupNodesInputCnt(strKey)
|
||
Dim outputCnt As UInt16 = ObjGroupNodesoutputCnt(strKey)
|
||
|
||
Dim arryInputSetting As Byte() = ObjGroupNodesInpuSettings(strKey).ToArray
|
||
Dim arryOutputSetting As Byte() = ObjGroupNodesOutputAliases(strKey).ToArray
|
||
|
||
ObjGroupNodesInOutDic(strKey).AddRange(BitConverter.GetBytes(inputCnt))
|
||
ObjGroupNodesInOutDic(strKey).AddRange(BitConverter.GetBytes(outputCnt))
|
||
|
||
ObjGroupNodesInOutDic(strKey).AddRange(arryInputSetting) '所有输入回路设置(n*4字节)
|
||
ObjGroupNodesInOutDic(strKey).AddRange(arryOutputSetting) '所有输出回路别名(n*16字节)
|
||
|
||
outDataLst.Add(ObjGroupNodesInOutDic(strKey).ToArray)
|
||
Next
|
||
Dim tmpOutData As Byte()
|
||
For i = 0 To outDataLst.Count - 1
|
||
tmpOutData = outDataLst(i).ToArray
|
||
Console.WriteLine($"设备编译数据:{ByteToString(tmpOutData.ToArray)}")
|
||
Next
|
||
|
||
|
||
Return outDataLst
|
||
|
||
End Function
|
||
Private Function FindAttributeValueUnderModel(pNode As DeviceModel, groupName As String, attributeName As String) As String
|
||
For Each cnode In pNode.Config
|
||
If cnode.Name.Equals(groupName) Then
|
||
For Each ccnode In cnode.Attributes
|
||
If ccnode.Name.Equals(attributeName) Then
|
||
Return ccnode.DataDefault
|
||
End If
|
||
Next
|
||
|
||
End If
|
||
Next
|
||
End Function
|
||
Private Function FindNodeValueUnderModel(pNode As DeviceModel, groupName As String, attributeName As String) As String
|
||
For Each cnode In pNode.Nodes
|
||
If cnode.Name.Equals(groupName) Then
|
||
For Each ccnode In cnode.Nodes
|
||
If ccnode.Interface.Equals(attributeName) Then
|
||
Return ccnode.LoopAddr
|
||
End If
|
||
Next
|
||
|
||
End If
|
||
Next
|
||
End Function
|
||
''' <summary>
|
||
''' 根据连接在485设备下的模型节点信息,配置设备存在数据
|
||
''' </summary>
|
||
''' <param name="pNode">模型节点</param>
|
||
''' <returns></returns>
|
||
'Private Function FillExternalModelDeviceExsist(pNode As DeviceChildNodeClass, ByRef OutDevlist As List(Of Dictionary(Of String, String))) As List(Of Byte())
|
||
' 'If pNode.RowType <> RowNode.RowTypeEnum.ExternalModel Then Throw New Exception($"行号:{pNode.RowListIndex} 不为外接设备类型")
|
||
' '返回参数
|
||
' Dim outDataLst As New List(Of Byte()) '输出数据列表
|
||
' '公共参数
|
||
' ' Dim pTag As DeviceObjectRowNodeTag = pNode.ParentNode.Tag
|
||
' Dim baudData(3) As Byte '波特率(4字节)
|
||
' Dim retryTimeData(1) As Byte '重发次数(2字节)
|
||
' Dim keepParam(59) As Byte '保留字段(32字节) -> 2022-05-28 V3.1 32bytes->64Bytes
|
||
' Dim ipadd(3) As Byte
|
||
' '键值对,用于保存合并后设备数据
|
||
' Dim ObjGroupNodesInOutDic As New Dictionary(Of String, List(Of Byte)) '键值对,用于保存合并后的数据,Val = 设备组编译后的byte数组
|
||
' Dim strObjGroupNodesTypedataAndProtocol As String = "" '键值对的Key 即:key = DevTypeData,ProtocolVer
|
||
|
||
' Dim ObjGroupNodesInputCnt As New Dictionary(Of String, UInt16) '键值对,用于保存合并后的输入回路数,Val = 设备组编译后的byte数组
|
||
' Dim ObjGroupNodesoutputCnt As New Dictionary(Of String, UInt16) '键值对,用于保存合并后的输出回路数,Val = 设备组编译后的byte数组
|
||
|
||
' Dim ObjGroupNodesInpuSettings As New Dictionary(Of String, List(Of Byte)) '用于保存合并后输入设定数组
|
||
' Dim ObjGroupNodesOutputAliases As New Dictionary(Of String, List(Of Byte)) '用于保存合并后输出别名数组
|
||
|
||
' Dim strObjGroupNodesInterface As String = ""
|
||
|
||
' '2022-05-23 Momo V3.0 找到外设设备(RowType=26)后,再遍历设备组(RowType=8)
|
||
' 'To be code here !
|
||
' 'OutDevlist.Add(System.Text.Encoding.Default.GetBytes(Str))
|
||
' For i = 0 To pNode.Nodes.Count - 1
|
||
' Dim objGroupNode = pNode.Nodes(i)
|
||
' 'If objGroupNode.RowType <> RowNode.RowTypeEnum.DeviceGroup Then Continue For '找到模型外设组
|
||
' 'If objGroupNode.Compile = False Then Continue For '判断是否enable action’
|
||
' strObjGroupNodesTypedataAndProtocol = pNode.Nodes.Count & "," & i
|
||
' strObjGroupNodesInterface = objGroupNode.Interface
|
||
' 'PrintInfo(" 开始遍历:" & objGroupNode.Text & " (" & strObjGroupNodesTypedataAndProtocol & "," & strObjGroupNodesInterface & ")")
|
||
' 'OutDevlist.AddRange(System.Text.Encoding.Default.GetBytes(pNode.Text))
|
||
' 'OutDevlist.AddRange(System.Text.Encoding.Default.GetBytes(strObjGroupNodesTypedataAndProtocol & "," & strObjGroupNodesInterface))
|
||
|
||
' 'Console.WriteLine($"{pNode.Text}:{}")
|
||
' '如果键值对不存在就增加键值对
|
||
' If ObjGroupNodesInOutDic.ContainsKey(strObjGroupNodesTypedataAndProtocol) = False Then
|
||
' ObjGroupNodesInputCnt.Add(strObjGroupNodesTypedataAndProtocol, 0) '输入回路数 = 0
|
||
' ObjGroupNodesoutputCnt.Add(strObjGroupNodesTypedataAndProtocol, 0) '输出回路数 = 0
|
||
' ObjGroupNodesInpuSettings.Add(strObjGroupNodesTypedataAndProtocol, New List(Of Byte))
|
||
' ObjGroupNodesOutputAliases.Add(strObjGroupNodesTypedataAndProtocol, New List(Of Byte))
|
||
|
||
' '添加输出合并设备键值对’
|
||
' ObjGroupNodesInOutDic.Add(strObjGroupNodesTypedataAndProtocol, New List(Of Byte))
|
||
|
||
' '添加设备组公共信息
|
||
' baudData = BitConverter.GetBytes(CInt(FindAttributeValueUnderModel(pNode, "设备存在", "波特率")))
|
||
' retryTimeData = BitConverter.GetBytes(CShort(FindAttributeValueUnderModel(pNode, "设备存在", "重发时间")))
|
||
|
||
' Dim tmpAddr As Byte = CInt(FindAttributeValueUnderModel(pNode, "设备存在", "拨码地址")) '设备地址(1字节)
|
||
' 'Dim ipAddr As IPAddress = IPAddress.Parse(FindAttributeValueUnderModel(pNode, "设备存在", "中控IP地址")) '设备地址(1字节)
|
||
' 'ipadd = ipAddr.GetAddressBytes()
|
||
' With ObjGroupNodesInOutDic(strObjGroupNodesTypedataAndProtocol)
|
||
' .Add(&H3) '设备存在,每个数据块前面都加上 &H03
|
||
' .Add(CByte(objGroupNode.DEV_TYPE_DATA)) '设备类型(1字节)
|
||
|
||
' .Add(tmpAddr)
|
||
' PrintInfo(" *** 设备地址:" & tmpAddr.ToString)
|
||
|
||
' .Add(CByte(pTag.Device.LoopAddr)) '485端口(1字节)
|
||
' .AddRange(baudData) '波特率(4字节)
|
||
' .Add(CByte(objGroupNode.PROTOCOL_VER)) '协议版本(1字节)
|
||
' .Add(CInt(FindAttributeValueUnderModel(pNode, "设备存在", "重发次数"))) '重发次数(1字节)
|
||
' .AddRange(retryTimeData) '重发间隔(2字节)
|
||
' If objGroupNode.DEV_TYPE_DATA.Equals("42") Then
|
||
' Dim ipAddr As IPAddress = IPAddress.Parse(FindAttributeValueUnderModel(pNode, "设备存在", "中控IP地址")) '设备地址(1字节)
|
||
' ipadd = ipAddr.GetAddressBytes()
|
||
' PrintInfo(" 中控IP地址 IPadd :" & ipAddr.ToString)
|
||
' ElseIf objGroupNode.DEV_TYPE_DATA.Equals("43") Then
|
||
' Dim ipAddr As IPAddress = IPAddress.Parse(FindAttributeValueUnderModel(pNode, "设备存在", "域控IP地址")) '设备地址(1字节)
|
||
' ipadd = ipAddr.GetAddressBytes()
|
||
' PrintInfo(" 域控IP地址 IPadd :" & ipAddr.ToString)
|
||
' End If
|
||
' .AddRange(ipadd)
|
||
' .AddRange(keepParam)
|
||
' End With
|
||
' 'OutDevlist.AddRange(ObjGroupNodesInOutDic(strObjGroupNodesTypedataAndProtocol))
|
||
' 'Momo 2022-10-31 把编译后的485公共参数打印出来
|
||
' 'Dim tmpData As Byte() = ObjGroupNodesInOutDic(strObjGroupNodesTypedataAndProtocol).ToArray
|
||
' 'Dim tmpStr As String = BitConverter.ToString(tmpData).Replace("-", " ")
|
||
' 'PrintInfo(" *** 编译数据:" & tmpStr)
|
||
|
||
|
||
|
||
|
||
|
||
' 'Dim tmpData As Byte() = ObjGroupNodesInOutDic(strObjGroupNodesTypedataAndProtocol).ToArray
|
||
' 'Console.WriteLine(BitConverter.ToString(tmpData).Replace("-", " "))
|
||
' End If
|
||
|
||
' '遍历设备
|
||
' For Each objNode As RowNode In objGroupNode.Nodes
|
||
' If objNode.RowType <> RowNode.RowTypeEnum.DeviceObject Then Continue For '设备
|
||
' If objNode.Compile = False Then Continue For '判断是否enable action’
|
||
' Select Case objNode.Interface
|
||
' Case "DI"
|
||
' ObjGroupNodesInputCnt(strObjGroupNodesTypedataAndProtocol) += 1 '输入回路数+1
|
||
' ObjGroupNodesInpuSettings(strObjGroupNodesTypedataAndProtocol).AddRange(GetDeviceObjectSetting(objNode))'输入回路设定’
|
||
' Case "DO"
|
||
' Dim tmpDevAlias As String = objNode.DeviceAlias
|
||
' 'If String.IsNullOrEmpty(tmpDevAlias) Then Continue For '未命名别名的输出设备不参与编译
|
||
' Dim aliasData() As Byte = AliasEncoding.GetBytes(tmpDevAlias)
|
||
' ReDim Preserve aliasData(31) 'caocong 2022-06-07 修改别名长度16Byte -> 32Byte
|
||
' ObjGroupNodesoutputCnt(strObjGroupNodesTypedataAndProtocol) += 1 '输出回路数+1’
|
||
' ObjGroupNodesOutputAliases(strObjGroupNodesTypedataAndProtocol).AddRange(aliasData) '输出回路别名’
|
||
' Case Else
|
||
' Continue For
|
||
' End Select
|
||
' Next
|
||
' Next
|
||
' 'PrintInfo(" 设备组遍历结束,合并后设备组数据如下:")
|
||
|
||
' ''遍历合并后的设备组(保存于键值对中)
|
||
' 'For Each strKey As String In ObjGroupNodesInOutDic.Keys
|
||
' ' Dim inputCnt As UInt16 = ObjGroupNodesInputCnt(strKey)
|
||
' ' Dim outputCnt As UInt16 = ObjGroupNodesoutputCnt(strKey)
|
||
|
||
' ' Dim arryInputSetting As Byte() = ObjGroupNodesInpuSettings(strKey).ToArray
|
||
' ' Dim arryOutputSetting As Byte() = ObjGroupNodesOutputAliases(strKey).ToArray
|
||
|
||
' ' ObjGroupNodesInOutDic(strKey).AddRange(BitConverter.GetBytes(inputCnt))
|
||
' ' ObjGroupNodesInOutDic(strKey).AddRange(BitConverter.GetBytes(outputCnt))
|
||
|
||
' ' ObjGroupNodesInOutDic(strKey).AddRange(arryInputSetting) '所有输入回路设置(n*4字节)
|
||
' ' ObjGroupNodesInOutDic(strKey).AddRange(arryOutputSetting) '所有输出回路别名(n*16字节)
|
||
|
||
' ' PrintInfo(" DevType and Protocol:" & strKey)
|
||
' ' PrintInfo(" Input :" & inputCnt & ", Len=" & arryInputSetting.Length)
|
||
' ' PrintInfo(" Output:" & outputCnt & ", Len=" & arryOutputSetting.Length)
|
||
|
||
' ' 'Dim tmpData As Byte() = ObjGroupNodesInOutDic(strKey).ToArray
|
||
' ' 'Console.WriteLine("strKey=" & strKey & " : " & BitConverter.ToString(tmpData).Replace("-", " "))
|
||
' ' 'OutDevlist.AddRange(ObjGroupNodesInOutDic(strKey).ToArray)
|
||
' ' 'OutDevlist.AddRange({&HD, &HA})
|
||
' ' outDataLst.Add(ObjGroupNodesInOutDic(strKey).ToArray)
|
||
' 'Next
|
||
|
||
' ''' OLD CODE --------------------------------------
|
||
' ''Dim oobjectGroupsBuf As New List(Of Byte) ' 设备组buff,所有设备组buff 组成一个外设的buff
|
||
' ''Dim tag As ModelRowNodeTag = pNode.Tag
|
||
|
||
' '''V3.0以前:整个设备共用DevTypeData,V3.0以后:以设备组的DEV_TYPE_DATA为准
|
||
' ''oobjectGroupsBuf.Add(tag.Desc.DevTypeData) '设备类型(1字节)
|
||
' ''oobjectGroupsBuf.Add(CInt(FindAttributeValueUnderModel(pNode, "设备存在", "拨码地址"))) '设备地址(1字节)
|
||
|
||
' ''Dim pTag As DeviceObjectRowNodeTag = pNode.ParentNode.Tag
|
||
' ''oobjectGroupsBuf.Add(pTag.Device.LoopAddr) '485端口(1字节)
|
||
|
||
' ''Dim baudData() As Byte = BitConverter.GetBytes(CInt(FindAttributeValueUnderModel(pNode, "设备存在", "波特率")))
|
||
' ''oobjectGroupsBuf.AddRange(baudData) '波特率(4字节)
|
||
|
||
' '''V3.0以前:整个设备共用ProtocolVer,V3.0以后:以设备组的ProtocolVer为准
|
||
' ''oobjectGroupsBuf.Add(tag.Desc.ProtocolVer) '协议版本(1字节)
|
||
|
||
' ''oobjectGroupsBuf.Add(CInt(FindAttributeValueUnderModel(pNode, "设备存在", "重发次数"))) '重发次数(1字节)
|
||
|
||
' ''Dim retryTimeData() As Byte = BitConverter.GetBytes(CShort(FindAttributeValueUnderModel(pNode, "设备存在", "重发时间")))
|
||
' ''oobjectGroupsBuf.AddRange(retryTimeData) '重发间隔(2字节)
|
||
|
||
' ''Dim keepParam(31) As Byte '保留字段(32字节)
|
||
' ''oobjectGroupsBuf.AddRange(keepParam)
|
||
|
||
' ''Dim inputCount, outputCount As UShort
|
||
' ''Dim inputSettings As New List(Of Byte)
|
||
' ''Dim outputAliases As New List(Of Byte)
|
||
' '''Dim inputGroupNode As RowNode = FindModelDeviceGroupUnderModel(pNode, "DI")
|
||
' '''Dim outputGroupNode As RowNode = FindModelDeviceGroupUnderModel(pNode, "DO")
|
||
' ''Dim inputGroupNode As RowNode = FindModelDeviceGroupUnderModel_By_Interface(pNode, "DI")
|
||
' ''Dim outputGroupNode As RowNode = FindModelDeviceGroupUnderModel_By_Interface(pNode, "DO")
|
||
|
||
' ''If inputGroupNode Is Nothing Then
|
||
' '' inputCount = 0
|
||
' ''Else
|
||
' '' For Each node As RowNode In inputGroupNode.Nodes
|
||
' '' If node.RowType <> RowNode.RowTypeEnum.DeviceObject Then Continue For
|
||
' '' If node.Compile = False Then Continue For
|
||
' '' inputCount += 1
|
||
' '' inputSettings.AddRange(GetDeviceObjectSetting(node))
|
||
' '' Next
|
||
' ''End If
|
||
|
||
' ''If outputGroupNode Is Nothing Then
|
||
' '' outputCount = 0
|
||
' ''Else
|
||
' '' For Each node As RowNode In outputGroupNode.Nodes
|
||
' '' If node.RowType <> RowNode.RowTypeEnum.DeviceObject Then Continue For
|
||
' '' If node.Compile = False Then Continue For
|
||
' '' outputCount += 1
|
||
|
||
' '' Dim aliasData() As Byte = AliasEncoding.GetBytes(node.DeviceAlias)
|
||
' '' ReDim Preserve aliasData(15)
|
||
' '' outputAliases.AddRange(aliasData)
|
||
' '' Next
|
||
' ''End If
|
||
|
||
' ''buf.AddRange(BitConverter.GetBytes(inputCount)) '输入回路数(2字节)
|
||
' ''buf.AddRange(BitConverter.GetBytes(outputCount)) '输出回路数(2字节)
|
||
' ''buf.AddRange(inputSettings.ToArray) '所有输入回路设置(n*4字节)
|
||
' ''buf.AddRange(outputAliases.ToArray) '所有输出回路别名(n*16字节)
|
||
|
||
' ''PrintInfo(" InputCount = " & inputCount)
|
||
' ''PrintInfo(" OutputCount = " & outputCount)
|
||
|
||
' Return outDataLst
|
||
'End Function
|
||
|
||
|
||
|
||
''' <summary>
|
||
''' 配置RCU模型设备存在数据
|
||
''' </summary>
|
||
''' <param name="pNode">模型节点</param>
|
||
''' <returns></returns>
|
||
Private Function FillRCUModelDeviceExsist(pNode As DeviceModel) As Byte()
|
||
' If pNode.RowType <> RowNode.RowTypeEnum.Model Then Throw New Exception($"行号:{pNode.RowListIndex} 不为RCU模型类型")
|
||
Dim buf As New List(Of Byte)
|
||
|
||
'Dim tag As ModelRowNodeTag = pNode.Tag
|
||
buf.Add(pNode.Desc.DevTypeData) '设备类型(1字节)
|
||
buf.Add(&H0) '设备地址(1字节)
|
||
buf.Add(&H0) '485端口(1字节)
|
||
|
||
Dim baudrate As Integer = 0
|
||
buf.AddRange(BitConverter.GetBytes(baudrate)) '波特率(4字节)
|
||
|
||
buf.Add(pNode.Desc.ProtocolVer) '协议版本(1字节)
|
||
buf.Add(&H0) '重发次数(1字节)
|
||
|
||
Dim retryInterval As Short = 0
|
||
buf.AddRange(BitConverter.GetBytes(retryInterval)) '重发间隔(2字节)
|
||
|
||
Dim keepParam(63) As Byte
|
||
buf.AddRange(keepParam) '保留字段(32字节) -> 2022-05-28 V3.1 32bytes->64Bytes
|
||
|
||
Dim inputCount As Short = 0
|
||
Dim outputCount As Short = 0
|
||
buf.AddRange(BitConverter.GetBytes(inputCount)) '输入回路数(2字节)
|
||
buf.AddRange(BitConverter.GetBytes(outputCount)) '输出回路数(2字节)
|
||
|
||
'所有输入回路设置(n*4字节)
|
||
|
||
'所有输出回路别名(n*16字节)
|
||
|
||
Return buf.ToArray
|
||
End Function
|
||
|
||
|
||
''' <summary>
|
||
''' 根据RCU模型的设备存在属性组,配置设备存在数据
|
||
''' </summary>
|
||
''' <param name="pNode">模型节点</param>
|
||
''' <returns></returns>
|
||
Private Function FillModeDeviceExsist(Ccnode As DeviceModelConfigGroup, pNode As DeviceModel) As Byte()
|
||
'If pNode.RowType <> RowNode.RowTypeEnum.ModelAttributes_DeviceExists Then Throw New Exception($"行号:{pNode.RowListIndex} 不为设备存在模型属性类型")
|
||
|
||
Dim buf As New List(Of Byte)
|
||
Dim Cbuf(10) As Byte
|
||
For Each node In Ccnode.Attributes
|
||
|
||
Select Case node.Name
|
||
Case "DeviceType"
|
||
Cbuf(0) = node.DataDefault
|
||
Case "DeviceAddr"
|
||
Cbuf(1) = node.DataDefault
|
||
Case "DevicePort"
|
||
Cbuf(2) = node.DataRangeValue
|
||
Case "DeviceBaud"
|
||
Dim baudData() As Byte = BitConverter.GetBytes(CInt(node.DataDefault))
|
||
Cbuf(3) = baudData(0)
|
||
Cbuf(4) = baudData(1)
|
||
Cbuf(5) = baudData(2)
|
||
Cbuf(6) = baudData(3)
|
||
Case "DeviceVer"
|
||
Cbuf(7) = node.DataDefault
|
||
Case "DeviceRetryNum"
|
||
Cbuf(8) = node.DataDefault
|
||
Case "DeviceRetryTime"
|
||
Dim retryTimeData() As Byte = BitConverter.GetBytes(CShort(node.DataDefault))
|
||
Cbuf(9) = retryTimeData(0)
|
||
Cbuf(10) = retryTimeData(1)
|
||
Case Else
|
||
Continue For
|
||
End Select
|
||
|
||
Next
|
||
|
||
|
||
|
||
buf.AddRange(Cbuf)
|
||
Dim keepParam(63) As Byte '保留字段(32字节) -> 2022-05-28 V3.1 32bytes->64Bytes
|
||
buf.AddRange(keepParam)
|
||
|
||
Dim index As Integer = Ccnode.Name.IndexOf("设备组信息")
|
||
Dim type As String = Ccnode.Name.Substring(0, index)
|
||
Dim inputCount, outputCount As UShort
|
||
Dim inputSettings As New List(Of Byte)
|
||
Dim outputAliases As New List(Of Byte)
|
||
Dim inputGroupNode As DeviceChildNodeClass = Nothing
|
||
Dim outputGroupNode As DeviceChildNodeClass = Nothing
|
||
|
||
Select Case type '
|
||
Case "DI"
|
||
inputGroupNode = FindModelDeviceGroupUnderModel(pNode, "DI")
|
||
Case Else
|
||
outputGroupNode = FindModelDeviceGroupUnderModel(pNode, type)
|
||
End Select
|
||
|
||
If inputGroupNode Is Nothing Then
|
||
inputCount = 0
|
||
Else
|
||
For Each node In inputGroupNode.Nodes
|
||
'If node.RowType <> RowNode.RowTypeEnum.DeviceObject Then Continue For
|
||
'If node.Compile = False Then Continue For
|
||
inputCount += 1
|
||
inputSettings.AddRange(GetDeviceObjectSetting())
|
||
Next
|
||
End If
|
||
|
||
If outputGroupNode Is Nothing Then
|
||
outputCount = 0
|
||
Else
|
||
|
||
For Each node In outputGroupNode.Nodes
|
||
'If node.RowType <> RowNode.RowTypeEnum.DeviceObject Then Continue For
|
||
'If node.Compile = False Then Continue For
|
||
outputCount += 1
|
||
Dim aliasData() As Byte
|
||
'Momo 2022-05-03 增加DeviceAlias非空判断,避免报错
|
||
If String.IsNullOrEmpty(node.Name) = False Then
|
||
|
||
aliasData = AliasEncoding.GetBytes(node.Name)
|
||
|
||
End If
|
||
ReDim Preserve aliasData(31) 'caocong 2022-06-07 修改别名长度16Byte -> 32Byte
|
||
outputAliases.AddRange(aliasData)
|
||
Console.WriteLine($"{node.DefaultAliasName}{vbCrLf}")
|
||
|
||
Next
|
||
Console.WriteLine($"{outputGroupNode.Name}:{outputGroupNode.Nodes.Count }:{outputAliases.Count }{vbCrLf}")
|
||
End If
|
||
|
||
buf.AddRange(BitConverter.GetBytes(inputCount)) '输入回路数(2字节)
|
||
buf.AddRange(BitConverter.GetBytes(outputCount)) '输出回路数(2字节)
|
||
buf.AddRange(inputSettings.ToArray) '所有输入回路设置(n*4字节)
|
||
buf.AddRange(outputAliases.ToArray) '所有输出回路别名(n*16字节)
|
||
|
||
|
||
''输入回路设置(n*4)
|
||
'If inputCount > 0 Then
|
||
' For Each node As RowNode In inputGroupNode.Nodes
|
||
' '查询设备节点
|
||
' If node.RowType <> RowNode.RowTypeEnum.DeviceObject Then Continue For
|
||
|
||
' buf.AddRange(GetDeviceObjectSetting(node))
|
||
' Next
|
||
'End If
|
||
|
||
''所有输出回路别名(n*16字节)
|
||
'If outputCount > 0 Then
|
||
' For Each node As RowNode In outputGroupNode.Nodes
|
||
' Dim aliasData() As Byte = AliasEncoding.GetBytes(node.DeviceAlias)
|
||
' ReDim Preserve aliasData(15)
|
||
' buf.AddRange(aliasData)
|
||
' Next
|
||
'End If
|
||
|
||
Return buf.ToArray
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' 在模型节点下查询指定名称的设备组节点
|
||
''' </summary>
|
||
''' <param name="pNode">模型节点</param>
|
||
''' <returns></returns>
|
||
Private Function FindModelDeviceGroupUnderModel(pNode As DeviceModel, name As String) As DeviceChildNodeClass
|
||
Dim resultNode As DeviceChildNodeClass = Nothing
|
||
''2022-05-14 2.0.2.0 版本以前:匹配节点名称与“DI”‘DO’字符串,来确定是否返回端点
|
||
''外设有继电器时,继电器名称为“Relay”,Interface为“DO”,此方法会范围“0”
|
||
For Each node In pNode.Nodes
|
||
'If node.RowType <> RowNode.RowTypeEnum.DeviceGroup Then Continue For
|
||
If String.Compare(node.Name, name, True) <> 0 Then Continue For
|
||
resultNode = node
|
||
Exit For
|
||
Next
|
||
|
||
Return resultNode
|
||
End Function
|
||
|
||
|
||
''' <summary>
|
||
''' 获取输入类型设备对象的回路设置
|
||
''' </summary>
|
||
''' <param name="pNode"></param>
|
||
''' <returns></returns>
|
||
Private Function GetDeviceObjectSetting() As Byte()
|
||
|
||
Dim buf() As Byte = {1, 2, 2, 0}
|
||
'For Each node As RowNode In pNode.Nodes
|
||
' '查询设备属性集合
|
||
' If node.RowType <> RowNode.RowTypeEnum.DeviceAttributes Then Continue For
|
||
|
||
' '获取设备属性值
|
||
' Dim index As Integer = 0
|
||
' Dim tag As AttributeRowNodeTag
|
||
' For Each n As RowNode In node.Nodes
|
||
' tag = n.Tag
|
||
' buf(index) = tag.ValueData
|
||
|
||
' index += 1
|
||
' If index >= 4 Then Exit For
|
||
' Next
|
||
'Next
|
||
Return buf
|
||
End Function
|
||
''' <summary>
|
||
''' 填充数据帧
|
||
''' </summary>
|
||
''' <param name="data">包含帧类型和帧参数</param>
|
||
''' <returns></returns>
|
||
Public Function FillDataFrames(data As List(Of Byte())) As List(Of Byte())
|
||
Dim result As New List(Of Byte())
|
||
Dim index As Short = 1
|
||
Dim count As Short = data.Count
|
||
|
||
Dim frameBuf As List(Of Byte)
|
||
|
||
Dim num As Integer = 0
|
||
For Each buf As Byte() In data
|
||
num = num + buf.Length
|
||
|
||
frameBuf = New List(Of Byte)
|
||
|
||
'包头(2位)
|
||
frameBuf.Add(&HCC)
|
||
frameBuf.Add(&HC0)
|
||
|
||
'长度(2位)
|
||
Dim length As Short = buf.Length + 10
|
||
frameBuf.AddRange(BitConverter.GetBytes(length))
|
||
|
||
'CRC校验(2位)
|
||
frameBuf.AddRange(New Byte() {0, 0})
|
||
|
||
'帧号(2位)
|
||
frameBuf.AddRange(BitConverter.GetBytes(index))
|
||
|
||
'帧总数(2位)
|
||
frameBuf.AddRange(BitConverter.GetBytes(count))
|
||
|
||
''帧类型(1位)
|
||
'frameBuf.Add(type)
|
||
|
||
'帧参数(不定长)
|
||
frameBuf.AddRange(buf)
|
||
|
||
|
||
|
||
|
||
Dim crc() As Byte = GetCRC16CheckSum(frameBuf.ToArray, frameBuf.Count)
|
||
frameBuf(4) = crc(0)
|
||
frameBuf(5) = crc(1)
|
||
|
||
index += 1
|
||
result.Add(frameBuf.ToArray)
|
||
Next
|
||
'Dim themore As Integer = num Mod 4
|
||
|
||
'Console.WriteLine(num)
|
||
'For isnum As Integer = 1 To (4 - themore)
|
||
' result(result.Count -1).Add({0})
|
||
'Next
|
||
Return result
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' CRC16校验
|
||
''' </summary>
|
||
''' <param name="dataBuff"></param>
|
||
''' <param name="length"></param>
|
||
''' <returns></returns>
|
||
Public Function GetCRC16CheckSum(dataBuff() As Byte, length As Integer) As Byte()
|
||
Dim crc16 As UInteger
|
||
Dim crcBytes() As Byte
|
||
|
||
crc16 = &HFFFF
|
||
For i = 0 To length - 1
|
||
crc16 = crc16 And &HFFFF
|
||
crc16 = crc16 Xor dataBuff(i)
|
||
For bit = 0 To 7
|
||
crc16 = IIf((crc16 And 1) = 0, crc16 >> 1, (crc16 >> 1) Xor &HA001)
|
||
Next
|
||
Next
|
||
crc16 = crc16 And &HFFFF
|
||
crcBytes = BitConverter.GetBytes(UShort.Parse(crc16))
|
||
Return crcBytes
|
||
End Function
|
||
''' <summary>
|
||
''' 获取设备对象下的所有动作编译数据(所有的设备对象动作数据)
|
||
''' </summary>
|
||
''' <returns></returns>
|
||
Public Function FillDeviceObject(ByRef DeviceModuleDic As Dictionary(Of String, DeviceModel), SwitchConfig As Dictionary(Of String, Dictionary(Of Integer, String)), Grid1 As FlexCell.Grid) As List(Of Byte())
|
||
Dim lst As New List(Of Byte())
|
||
Dim tmpDataCount As Integer = 0
|
||
|
||
'PrintInfo("开始编译设备对象")
|
||
Dim devMode As DeviceModel
|
||
|
||
Dim t_row As Integer = -1
|
||
Dim t_col As Integer = -1
|
||
Dim DevGroupName As String = String.Empty
|
||
Dim Setval As String = String.Empty
|
||
Dim ConfigGroup As DeviceModelConfigGroup
|
||
Dim DeviceAlias As String = String.Empty
|
||
Dim hread() As Byte
|
||
|
||
Dim keepBuf(31) As Byte
|
||
For Each node In SwitchConfig
|
||
|
||
If node.Value.Count - 2 > 0 Then
|
||
|
||
|
||
Dim hreadname() As String = SwitchConfig.Keys(0).Split(":")
|
||
Dim chainame() As String = node.Key.Split(":")
|
||
|
||
If chainame(0).Equals(hreadname(0)) Then
|
||
devMode = DeviceModuleDic.Item("HostDevice")
|
||
'获取头部节点
|
||
hread = GetActionGroupHread(devMode)
|
||
|
||
Else
|
||
|
||
'devMode = DeviceModuleDic.Item(nodename)
|
||
devMode = DeviceModuleDic.Item("HostDevice")
|
||
'获取头部节点
|
||
Dim nodename As String = $"{chainame(0)}:{chainame(1)}"
|
||
Dim DcdevMode As DeviceModel = DeviceModuleDic.Item(nodename)
|
||
hread = GetdevGroupHread(DcdevMode, chainame(1))
|
||
End If
|
||
|
||
|
||
Dim strEventNum As UShort = 1
|
||
Dim eventNum() As Byte = BitConverter.GetBytes(strEventNum)
|
||
Dim keepParam(31) As Byte '保留字段(32字节) -> 2022-05-28 V3.1 32bytes
|
||
Dim condition As Byte
|
||
Dim aliasbuf(31) As Byte
|
||
Dim sceneNum() As Byte
|
||
Dim ncbuf As New List(Of Byte())
|
||
Integer.TryParse(chainame(chainame.Length - 1), t_row)
|
||
Dim devLoop() As Byte = BitConverter.GetBytes(CShort(t_row))
|
||
For Each Cnode In node.Value
|
||
If Cnode.Key < ComboDropDownCol.max Then Continue For
|
||
If chainame(0).Equals(hreadname(0)) Then
|
||
|
||
condition = GetExecModeDataUnderCondtion(Cnode.Value)
|
||
|
||
'DeviceAlias = Grid1.Cell(ComboDropDownON.LightingCircuit2, Cnode.Key).Text
|
||
If String.IsNullOrEmpty(DeviceAlias) = False Then
|
||
Dim cbuf() As Byte = AliasEncoding.GetBytes(DeviceAlias)
|
||
If cbuf.Length > aliasbuf.Length Then
|
||
Array.Copy(cbuf, 0, aliasbuf, 0, aliasbuf.Length)
|
||
Else
|
||
Array.Copy(cbuf, 0, aliasbuf, 0, cbuf.Length)
|
||
End If
|
||
End If
|
||
|
||
|
||
sceneNum = BitConverter.GetBytes(_sceneIndex)
|
||
|
||
|
||
|
||
Integer.TryParse(Grid1.Cell(ComboDropDownON.LightingCircuit1, Cnode.Key).Text, t_col)
|
||
DevGroupName = Grid1.Cell(ComboDropDownON.LightingCircuit0, Cnode.Key - t_col + 1).Text
|
||
Dim databuff() As Byte = GetActionData(DevGroupName, devMode, t_col, Cnode.Value)
|
||
If IsNothing(databuff) Then Continue For
|
||
|
||
ncbuf.Add(databuff)
|
||
Else
|
||
condition = GetExecModeDataUnderCondtion(Cnode.Value)
|
||
|
||
'DeviceAlias = Grid1.Cell(ComboDropDownON.LightingCircuit2, Cnode.Key).Text
|
||
If String.IsNullOrEmpty(DeviceAlias) = False Then
|
||
Dim cbuf() As Byte = AliasEncoding.GetBytes(DeviceAlias)
|
||
If cbuf.Length > aliasbuf.Length Then
|
||
Array.Copy(cbuf, 0, aliasbuf, 0, aliasbuf.Length)
|
||
Else
|
||
Array.Copy(cbuf, 0, aliasbuf, 0, cbuf.Length)
|
||
End If
|
||
End If
|
||
|
||
|
||
sceneNum = BitConverter.GetBytes(_sceneIndex)
|
||
|
||
|
||
|
||
Integer.TryParse(Grid1.Cell(ComboDropDownON.LightingCircuit1, Cnode.Key).Text, t_col)
|
||
DevGroupName = Grid1.Cell(ComboDropDownON.LightingCircuit0, Cnode.Key - t_col + 1).Text
|
||
Dim databuff() As Byte = GetActionData(DevGroupName, devMode, t_col, Cnode.Value)
|
||
If IsNothing(databuff) Then Continue For
|
||
ncbuf.Add(databuff)
|
||
End If
|
||
Next
|
||
|
||
|
||
If ncbuf.Count > 0 Then
|
||
Dim li As New List(Of Byte)
|
||
li.AddRange(hread) '获取头部节点 3
|
||
|
||
li.AddRange(BitConverter.GetBytes(_actionIndex)) '动作编号 2
|
||
_actionIndex += 1
|
||
li.AddRange(devLoop) '设备回路 2
|
||
|
||
li.AddRange(eventNum) '添加事件编号 2
|
||
li.AddRange(GetConditionDataUnderConditionGroup) '获取执行模式 8
|
||
li.AddRange(keepParam) '条件保留32Byte 32
|
||
li.Add(condition) '获取执行条件编译数据 1
|
||
li.AddRange(aliasbuf) '32字节,事件条件别名 2022-06-07 caocong 32
|
||
|
||
li.AddRange(sceneNum) '2字节,场景编k号 2
|
||
li.AddRange(keepBuf) '30位保留字段 32
|
||
Dim valCount As UShort = node.Value.Count - 2
|
||
|
||
li.Add(valCount) '获取执行动作数量 2
|
||
For Each buf In ncbuf '32
|
||
li.AddRange(buf) '获取动作数据
|
||
Next
|
||
|
||
lst.Add(li.ToArray)
|
||
Console.WriteLine($"UDP收到的数据:{ByteToString(li.ToArray)}")
|
||
End If
|
||
_sceneIndex += 1
|
||
End If
|
||
|
||
Next
|
||
|
||
Return lst
|
||
|
||
End Function
|
||
|
||
|
||
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 GetDevicegroupChildNodeConfid(devMode As DeviceModel) As DeviceModelConfigGroup
|
||
|
||
For Each ModuleFre In devMode.Config
|
||
If ModuleFre.Name.Equals("DI") Then
|
||
Return ModuleFre
|
||
Exit For
|
||
End If
|
||
Next
|
||
|
||
|
||
End Function
|
||
|
||
Public Function GetdevGroupHread(devMode As DeviceModel, Addrstr As String) As Byte()
|
||
Dim buf = New List(Of Byte)
|
||
'命令参数
|
||
Dim cmd As Byte = &H4
|
||
Dim devType As Byte
|
||
'模型的拨码地址
|
||
Dim devAddr As Byte = Addrstr
|
||
Dim DevGroupName = $"DI"
|
||
For Each cnode In devMode.Nodes
|
||
If cnode.Name.Equals(DevGroupName) Then
|
||
devType = cnode.DEV_TYPE_DATA
|
||
End If
|
||
Next
|
||
buf.Add(cmd) '命令参数
|
||
|
||
buf.Add(devType) '设备类型
|
||
|
||
buf.Add(devAddr) '设备地址
|
||
|
||
Return buf.ToArray
|
||
End Function
|
||
|
||
Public Function GetActionGroupHread(devMode As DeviceModel) As Byte()
|
||
Dim buf = New List(Of Byte)
|
||
'命令参数
|
||
Dim cmd As Byte = &H4
|
||
Dim devType As Byte
|
||
'模型的拨码地址
|
||
Dim devAddr As Byte
|
||
Dim DevGroupName = $"DI设备组信息"
|
||
'模型的设备类型
|
||
For Each cnode In devMode.Config
|
||
If cnode.Name.Equals(DevGroupName) Then
|
||
For Each node In cnode.Attributes
|
||
Select Case node.Name
|
||
Case "DeviceType"
|
||
devType = node.DataDefault
|
||
Case "DeviceAddr"
|
||
devAddr = node.DataDefault
|
||
|
||
Case Else
|
||
Continue For
|
||
End Select
|
||
Next
|
||
End If
|
||
Next
|
||
buf.Add(cmd) '命令参数
|
||
|
||
buf.Add(devType) '设备类型
|
||
|
||
buf.Add(devAddr) '设备地址
|
||
|
||
Return buf.ToArray
|
||
End Function
|
||
|
||
Public Function GetActionGroupBody(FDeviceLoop As Integer, Count As Integer, DeviceAlias As String, DevGroupName As String, devMode As DeviceModel, DeviceLoop As Integer, straction As String) As Byte()
|
||
Dim buf = New List(Of Byte)
|
||
Dim devLoop() As Byte = BitConverter.GetBytes(CShort(FDeviceLoop))
|
||
buf.AddRange(BitConverter.GetBytes(_actionIndex)) '动作编号
|
||
buf.AddRange(devLoop) '设备回路
|
||
|
||
Dim strEventNum As UShort = 1
|
||
Dim eventNum() As Byte = BitConverter.GetBytes(strEventNum)
|
||
Dim sceneNum() As Byte = BitConverter.GetBytes(_sceneIndex)
|
||
buf.AddRange(eventNum) '添加事件编号
|
||
Dim keepParam(31) As Byte '保留字段(32字节) -> 2022-05-28 V3.1 32bytes
|
||
buf.AddRange({GetExecModeDataUnderCondtion(straction)}) '获取执行条件编译数据
|
||
buf.AddRange(keepParam) '条件保留32Byte
|
||
buf.AddRange(GetConditionDataUnderConditionGroup) '获取执行模式
|
||
|
||
|
||
Dim aliasbuf(31) As Byte
|
||
If String.IsNullOrEmpty(DeviceAlias) = False Then
|
||
Dim cbuf() As Byte = AliasEncoding.GetBytes(DeviceAlias)
|
||
If cbuf.Length > aliasbuf.Length Then
|
||
Array.Copy(cbuf, 0, aliasbuf, 0, aliasbuf.Length)
|
||
Else
|
||
Array.Copy(cbuf, 0, aliasbuf, 0, cbuf.Length)
|
||
End If
|
||
End If
|
||
buf.AddRange(aliasbuf) '32字节,事件条件别名 2022-06-07 caocong
|
||
|
||
|
||
buf.AddRange(sceneNum) '2字节,场景编号
|
||
Dim keepBuf(31) As Byte
|
||
buf.AddRange(keepBuf) '30位保留字段
|
||
|
||
buf.AddRange(BitConverter.GetBytes(Count)) '获取执行动作数量
|
||
|
||
Dim ncbuf() As Byte = GetActionData(DevGroupName, devMode, DeviceLoop, straction)
|
||
If IsNothing(ncbuf) Then Return Nothing
|
||
buf.AddRange(ncbuf) '获取动作数据
|
||
Return buf.ToArray
|
||
End Function
|
||
|
||
|
||
|
||
|
||
''' <summary>
|
||
''' 从动作行节点获取动作数据
|
||
''' </summary>
|
||
''' <param name="node"></param>
|
||
''' <returns></returns>
|
||
Private Function GetActionData(DevGroupName As String, devMode As DeviceModel, DeviceLoop As Integer, straction As String) As Byte()
|
||
' If node.RowType <> RowNode.RowTypeEnum.DeviceEventAction Then Throw New Exception($"行号:{node.RowListIndex},文本:{node.Text}不为动作节点")
|
||
|
||
Dim buf(7) As Byte
|
||
Dim gDevGroupName = $"{DevGroupName}设备组信息"
|
||
Dim devType As Byte
|
||
'模型的拨码地址
|
||
Dim devAddr As Byte
|
||
'模型的设备类型
|
||
For Each cnode In devMode.Config
|
||
If cnode.Name.Equals(gDevGroupName) Then
|
||
For Each ccnode In cnode.Attributes
|
||
Select Case ccnode.Name
|
||
Case "DeviceType"
|
||
devType = ccnode.DataDefault
|
||
Case "DeviceAddr"
|
||
devAddr = ccnode.DataDefault
|
||
'Case "DevicePort"
|
||
' Cbuf(2) = node.DataRangeValue
|
||
'Case "DeviceBaud"
|
||
' Dim baudData() As Byte = BitConverter.GetBytes(CInt(node.DataDefault))
|
||
' Cbuf(3) = baudData(0)
|
||
' Cbuf(4) = baudData(1)
|
||
' Cbuf(5) = baudData(2)
|
||
' Cbuf(6) = baudData(3)
|
||
'Case "DeviceVer"
|
||
' Cbuf(7) = node.DataDefault
|
||
'Case "DeviceRetryNum"
|
||
' Cbuf(8) = node.DataDefault
|
||
'Case "DeviceRetryTime"
|
||
' Dim retryTimeData() As Byte = BitConverter.GetBytes(CShort(node.DataDefault))
|
||
' Cbuf(9) = retryTimeData(0)
|
||
' Cbuf(10) = retryTimeData(1)
|
||
Case Else
|
||
Continue For
|
||
End Select
|
||
Next
|
||
End If
|
||
Next
|
||
|
||
|
||
|
||
|
||
'设备类型,外接设备设备类型(主机特殊处理)
|
||
buf(0) = devType
|
||
|
||
'设备地址,选择对象的设备拨码地址(主机特殊处理)
|
||
buf(1) = devAddr
|
||
|
||
'设备回路,选择对象的回路地址
|
||
Dim loopBuf() As Byte = BitConverter.GetBytes(CShort(DeviceLoop))
|
||
Array.Copy(loopBuf, 0, buf, 2, loopBuf.Length)
|
||
|
||
|
||
'执行方式,不同设备类型有不同方式
|
||
Dim bolicActio() As Byte = GetSymbolicAction(DevGroupName, straction)
|
||
If IsNothing(bolicActio) Then Return Nothing
|
||
buf(4) = bolicActio(0) '执行方式 继电器开关
|
||
|
||
'执行内容,不同设备类型有不同内容
|
||
buf(5) = bolicActio(1) '执行内容
|
||
|
||
'延时时间,动作执行延时
|
||
buf(6) = 0 '延时时间
|
||
|
||
'延时单位,做东执行延时单位
|
||
buf(7) = 1 '延时单位
|
||
|
||
'2022-10-31 Momo 打印动作数据
|
||
' Dim tmpStr As String = BitConverter.ToString(buf).Replace("-", " ")
|
||
' PrintInfo(" [行号:" & node.RowListIndex & "] - " & "> 动作数据:" & tmpStr)
|
||
|
||
Return buf
|
||
End Function
|
||
|
||
Public Function GetSymbolicAction(modetyupe As String, straction As String) As Byte()
|
||
Dim result(1) As Byte
|
||
Select Case modetyupe
|
||
Case "RELAY"
|
||
Select Case straction
|
||
Case Chr(CellDrop.TurnOn).ToString
|
||
result(0) = 1
|
||
Case Chr(CellDrop.TurnDrown).ToString
|
||
result(0) = 2
|
||
Case Chr(CellDrop.表示先开后关).ToString
|
||
result(0) = 1
|
||
Case Chr(CellDrop.代表先关后开).ToString
|
||
result(0) = 1
|
||
Case Else
|
||
Return Nothing
|
||
End Select
|
||
Case "Dimming"
|
||
|
||
Case "DO"
|
||
|
||
Case "MUSIC"
|
||
Dim parstr() As String = straction.Split(",")
|
||
|
||
Dim dirIndex As Integer = 0 'node.Params(0).ValueData '文件夹索引
|
||
Dim modeStatus As Integer = 0 'node.Params(1).ValueData '播放时场景状态
|
||
Dim fileIndex As Integer = 0 'node.Params(2).ValueData '文件索引
|
||
Select Case parstr.Count
|
||
Case 1
|
||
dirIndex = parstr(1)
|
||
Case 2
|
||
dirIndex = parstr(1) '文件夹索引
|
||
modeStatus = parstr(0) '播放时场景状态
|
||
Case 3
|
||
dirIndex = parstr(1) '文件夹索引
|
||
modeStatus = parstr(0) '播放时场景状态
|
||
fileIndex = parstr(2) '文件索引
|
||
Case Else
|
||
|
||
End Select
|
||
'2022-05-06 Caocong: 先将变量初始化为0.有可能没有三个参数 ---end
|
||
result(0) = result(0) Or (dirIndex << 0)
|
||
result(0) = result(0) Or (modeStatus << 4)
|
||
result(1) = fileIndex
|
||
Case Else
|
||
Return Nothing
|
||
End Select
|
||
|
||
Return result
|
||
End Function
|
||
|
||
|
||
|
||
''' <summary>
|
||
''' 获取条件组节点下的条件编译数据
|
||
''' </summary>
|
||
''' <param name="pNode">条件组节点</param>
|
||
''' <returns></returns>
|
||
Private Function GetConditionDataUnderConditionGroup() As Byte()
|
||
Dim result As New List(Of Byte)
|
||
For i = 1 To 8
|
||
result.Add(0)
|
||
Next
|
||
'If pNode.RowType <> RowNode.RowTypeEnum.DeviceEventAllConditions Then Throw New Exception("转换条件时无效的类型")
|
||
'Dim a As New ConditionConverter
|
||
'For Each node As RowNode In pNode.Nodes
|
||
' Select Case node.Name
|
||
' Case " 1 动作输出使能"
|
||
' a.动作输出使能 = CInt(GetNodeSelectStringValue(node))
|
||
' Case " 2 判断房态"
|
||
' a.房态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case " 3 控制取电服务"
|
||
' a.控制取电服务 = CInt(GetNodeSelectStringValue(node))
|
||
' Case " 4 判断取电状态"
|
||
' a.取电状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case " 5 判断勿扰状态"
|
||
' a.勿扰状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case " 6 判断清理状态"
|
||
' a.清理状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case " 7 判断呼叫状态"
|
||
' a.呼叫状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case " 8 判断洗衣状态"
|
||
' a.洗衣状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case " 9 判断退房状态"
|
||
' a.退房状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "10 判断稍后状态"
|
||
' a.稍后状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "11 判断SOS状态"
|
||
' a.SOS状态 = CInt(GetNodeSelectStringValue(node))
|
||
' ' Case "12 判断预约待租状态"
|
||
' Case "12 判断送餐状态"
|
||
' a.预约待租状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "13 判断开锁状态"
|
||
' a.开锁状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "14 判断行李状态"
|
||
' a.行李状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "15 判断保险箱状态"
|
||
' a.保险箱状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "16 判断门磁状态"
|
||
' a.门磁状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "17 判断提示音状态"
|
||
' a.提示音状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "18 判断背光状态"
|
||
' a.背光状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "19 判断季节状态"
|
||
' a.季节状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "20 判断时间状态"
|
||
' a.时间状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "21 判断起夜状态"
|
||
' a.起夜状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case "22 判断锁定状态"
|
||
' a.锁定状态 = CInt(GetNodeSelectStringValue(node))
|
||
' Case Else
|
||
' Throw New Exception($"未知条件属性名:{node.Name}")
|
||
' End Select
|
||
'Next
|
||
|
||
'Return a.GetConditionData()
|
||
|
||
Return result.ToArray
|
||
End Function
|
||
|
||
|
||
Private Function GetExecModeDataUnderCondtion(straction As String) As Byte
|
||
'If pNode.RowType <> RowNode.RowTypeEnum.DeviceEventActionModeGroup Then Throw New Exception("转换执行方式时无效的类型")
|
||
'If pNode.Count <> 1 Then Throw New Exception("执行方式数量异常")
|
||
Dim result As Integer = 1
|
||
Select Case straction
|
||
Case Chr(CellDrop.TurnOn).ToString
|
||
result = 1
|
||
Case Chr(CellDrop.TurnDrown).ToString
|
||
result = 1
|
||
Case Chr(CellDrop.表示先开后关).ToString
|
||
result = 2
|
||
Case Chr(CellDrop.代表先关后开).ToString
|
||
result = 2
|
||
End Select
|
||
Return result
|
||
End Function
|
||
|
||
|
||
|
||
End Class
|