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 ''' ''' 别名转换所使用的编码格式,默认方式GBK ''' 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 ''' ''' Integer 类型转 4 字节 byte数组,高字节在前 ''' ''' ''' 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 ''' ''' Integer 类型转 3 字节 byte数组,高字节在前 ''' ''' ''' 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 '' '' 填充设备存在 '' '' 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 ''' ''' 根据连接在485设备下的模型节点信息,配置设备存在数据 ''' ''' 模型节点 ''' '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 ''' ''' 配置RCU模型设备存在数据 ''' ''' 模型节点 ''' 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 ''' ''' 根据RCU模型的设备存在属性组,配置设备存在数据 ''' ''' 模型节点 ''' 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 ''' ''' 在模型节点下查询指定名称的设备组节点 ''' ''' 模型节点 ''' 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 ''' ''' 获取输入类型设备对象的回路设置 ''' ''' ''' 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 ''' ''' 填充数据帧 ''' ''' 包含帧类型和帧参数 ''' 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 ''' ''' CRC16校验 ''' ''' ''' ''' 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 ''' ''' 获取设备对象下的所有动作编译数据(所有的设备对象动作数据) ''' ''' 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 ''' ''' 从动作行节点获取动作数据 ''' ''' ''' 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 ''' ''' 获取条件组节点下的条件编译数据 ''' ''' 条件组节点 ''' 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