using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; namespace Common { public static class ProtocalData { /// /// 获取子群数据 /// /// /// public static List> GetSubgroupSendData(XmlNode subGroupNode) { List> sendDatas = new List>(); int totalFrame = subGroupNode.ChildNodes.Count + 3;//补上配置xml文件版本号、配置数据版本号和全局属性数据 List textData; //=============1、新增配置xml文件版本号======================= sendDatas.Add(GetSendData(GetVersionSendData(subGroupNode.Attributes["SettingVersion"].Value), 0xA9, totalFrame, 1)); //=============2、配置数据版本号=========================== sendDatas.Add(GetSendData(GetVersionSendData(subGroupNode.Attributes["Version"].Value), 0xA5, totalFrame, 2)); //=============3、全局属性数据================================= sendDatas.Add(GetSendData(GetGlobalSendData(subGroupNode), 0xA3, totalFrame, 3)); //=============4、设备和动作数据============================= for (int i = 0; i < subGroupNode.ChildNodes.Count; i++) { XmlNode detailNode = subGroupNode.ChildNodes[i]; textData = new List(); textData.Add(detailNode.Attributes["Type"].Value);//类型 int paramCount = Convert.ToInt16(detailNode.Attributes["ParamCount"].Value); switch (Convert.ToInt16(detailNode.Attributes["Type"].Value)) { case 0://设备 textData.Add(detailNode.Attributes["DeviceAddress"].Value.Split('.')[0]);//设备地址第一位 textData.Add(detailNode.Attributes["DeviceAddress"].Value.Split('.')[1]);//设备地址第二位 textData.Add(detailNode.Attributes["DeviceAddress"].Value.Split('.')[2]);//设备地址第三位 for (int j = 1; j <= paramCount; j++) { //设备类型、输入回路数,输出回路数为两位字节 switch (j) { case 7: case 8: textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add(detailNode.Attributes["Param" + j.ToString()].Value); break; default: textData.Add(detailNode.Attributes["Param" + j.ToString()].Value); break; } } break; case 1://动作 textData.Add(detailNode.Attributes["DeviceAddress"].Value.Split('.')[0]);//设备地址第一位 textData.Add(detailNode.Attributes["DeviceAddress"].Value.Split('.')[1]);//设备地址第二位 textData.Add(detailNode.Attributes["DeviceAddress"].Value.Split('.')[2]);//设备地址第三位 for (int j = 1; j <= paramCount; j++) { //设备类型、输入地址为两位字节 switch (j) { case 4: textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add(detailNode.Attributes["Param" + j.ToString()].Value); break; default: textData.Add(detailNode.Attributes["Param" + j.ToString()].Value); break; } } //扩展属性 foreach (XmlNode expandNode in detailNode.ChildNodes) { paramCount = Convert.ToInt16(expandNode.Attributes["ParamCount"].Value); for (int j = 1; j <= paramCount; j++) { switch (j) { case 1: case 2: case 4://延时执行内容 case 5://延时执行单位 textData.Add(expandNode.Attributes["Param" + j.ToString()].Value); break; default: //扩展属性都为两位字节 textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add(expandNode.Attributes["Param" + j.ToString()].Value); break; } } //扩展属性的输出类型 int outTypeParamCount = Convert.ToInt16(expandNode.Attributes["OutTypeParamCount"].Value); switch (outTypeParamCount) { case 1: textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add(expandNode.Attributes["Param" + (paramCount + 1).ToString()].Value); break; case 2: textData.Add(expandNode.Attributes["Param" + (paramCount + 1).ToString()].Value); textData.Add(expandNode.Attributes["Param" + (paramCount + 2).ToString()].Value); break; case 3://背景音乐 textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add((Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 1).ToString()].Value) << 0) + (Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 2).ToString()].Value) << 12) + (Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 3).ToString()].Value) << 8)); break; case 4://地暖 textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add((Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 1).ToString()].Value) << 12) + (Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 2).ToString()].Value) << 8) + (Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 3).ToString()].Value) << 6) + Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 4).ToString()].Value)); break; case 5://空调 textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add((Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 1).ToString()].Value) << 14) + (Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 2).ToString()].Value) << 12) + (Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 3).ToString()].Value) << 10) + (Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 4).ToString()].Value) << 8) + Convert.ToInt16(expandNode.Attributes["Param" + (paramCount + 5).ToString()].Value)); break; } } break; case 2://MQTT映射:去掉组地址、设备地址,增加别名(长度20) string deviceType2 = detailNode.Attributes["DeviceType"].Value; textData.Add(deviceType2); textData.Add(detailNode.Attributes["Param1"].Value); if ("0" == deviceType2) { textData.Add(0x00); textData.Add(detailNode.Attributes["Param2"].Value); } else { textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add(detailNode.Attributes["Param2"].Value); } //paramCount = Convert.ToInt16(detailNode.Attributes["ParamCount"].Value); //for (int j = 1; j <= paramCount; j++) //{ // textData.Add(detailNode.Attributes["Param" + j.ToString()].Value); //} byte[] nameBGK = Encoding.GetEncoding("GBK").GetBytes(detailNode.Attributes["Name"].Value); foreach (byte b in nameBGK) { textData.Add(b); } for (int j = nameBGK.Length; j < 20; j++)//不足20位补0 { textData.Add(0x00); } break; case 3://BLW映射 textData.Add(detailNode.Attributes["GroupAddress"].Value); textData.Add(detailNode.Attributes["DeviceAddress"].Value); string deviceType3 = detailNode.Attributes["DeviceType"].Value; textData.Add(deviceType3); textData.Add(detailNode.Attributes["Param1"].Value); if ("0" == deviceType3) { textData.Add(0x00); textData.Add(detailNode.Attributes["Param2"].Value); } else { textData.Add("DeviceAddr");//标记一下,为了转为两位字节 textData.Add(detailNode.Attributes["Param2"].Value); } //textData.Add(detailNode.Attributes["DeviceType"].Value); //paramCount = Convert.ToInt16(detailNode.Attributes["ParamCount"].Value); //for (int j = 1; j <= paramCount; j++) //{ // textData.Add(detailNode.Attributes["Param" + j.ToString()].Value); //} break; } //每一组设备地址发送数据加入集合 sendDatas.Add(GetSendData(textData, 0xA2, totalFrame, (i + 4)));//组地址等属性 } return sendDatas; } /// /// 按所定义的格式获取与RCU主机通讯的数据 /// /// 数据内容 /// 模式:时间同步A0,组地址调试A1,子群发布A2,全局属性A3,V80复位开关A4,配置数据版本号A5,485调光A6,网络设置A7 /// 数据总帧数 /// 当前帧数 /// private static List GetSendData(List textData, byte mode, Int32 totalFrame, Int32 currentFrame) { //发送数据 //byte[] demoData = new byte[] { // 0xF0, 0x0F, //数据头 // 0xA1, //调试模式 // 0x00, 0x2C, //数据总长度 // 0x00, 0x01, //数据总帧数 // 0x00, 0x01, //当前帧数 // 0x54, 0x33, 0x53, 0x41, //识别码T3SA // 0x01, 0x01, 0x02, //组地址属性 // 0x01, 0x00, 0x23, 0x01, 0x00, 0x00, 0x00, 0x02, //弱电输入 // 0x01, 0x01, 0x09, 0x01, 0xFF, 0x03, 0x00, 0x00, 0xFF, //弱电输出 // 0x01, 0x02, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, //强电输出 // 0x57, 0xDA //CRC16校验 //}; List sendData = new List(); sendData.Add(0xF0);//数据头 sendData.Add(0x0F);//数据头 sendData.Add(mode);//调试模式 //数据总长度(除了前面2位数据头,其他都算) byte[] dataLen = Tools.Int32ToByte(textData.Count + 13); foreach (byte b in dataLen) { sendData.Add(b); } //数据总帧数 dataLen = Tools.Int32ToByte(totalFrame); foreach (byte b in dataLen) { sendData.Add(b); } //当前帧数 dataLen = Tools.Int32ToByte(currentFrame); foreach (byte b in dataLen) { sendData.Add(b); } sendData.Add(0x54);//识别码T3SA sendData.Add(0x33);//识别码T3SA sendData.Add(0x53);//识别码T3SA sendData.Add(0x41);//识别码T3SA bool isToByte = false; foreach (object obj in textData) { //遇到“DeviceAddr”标记,则改成2个byte if (Convert.ToString(obj) == "DeviceAddr") { isToByte = true; } else { if (isToByte) { dataLen = Tools.Int32ToByte2(Convert.ToInt32(obj));//小端 foreach (byte b in dataLen) { sendData.Add(b); } isToByte = false; } else { sendData.Add(byte.Parse(obj.ToString())); } } } ushort crc = Tools.CRC16(sendData.ToArray(), sendData.Count); sendData.Add(Convert.ToByte(crc & 0xFF));//CRC16校验 sendData.Add(Convert.ToByte((crc >> 8) & 0xFF));//CRC16校验 return sendData; } /// /// 获取配置数据版本号发送数据,version为空时,提供默认值FF,FF,FF /// /// /// private static List GetVersionSendData(string version) { List textData = new List(); if (string.IsNullOrEmpty(version)) { textData.Add(0xFF); textData.Add(0xFF); textData.Add(0xFF); } else { textData.Add(version.Split('.')[0]); textData.Add(version.Split('.')[1]); textData.Add(version.Split('.')[2]); } return textData; } /// /// 获取子群全局属性发送数据 /// /// 子群ID /// 项目ID /// private static List GetGlobalSendData(XmlNode subGroupNode) { List textData = new List(); int paramCount = Convert.ToInt16(subGroupNode.Attributes["ParamCount"].Value); for (int j = 1; j <= paramCount; j++) { textData.Add(subGroupNode.Attributes["Param" + j.ToString()].Value); } return textData; } } }