312 lines
16 KiB
C#
312 lines
16 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Xml;
|
||
|
||
namespace Common
|
||
{
|
||
public static class ProtocalData
|
||
{
|
||
/// <summary>
|
||
/// 获取子群数据
|
||
/// </summary>
|
||
/// <param name="subGroupNode"></param>
|
||
/// <returns></returns>
|
||
public static List<List<byte>> GetSubgroupSendData(XmlNode subGroupNode)
|
||
{
|
||
List<List<byte>> sendDatas = new List<List<byte>>();
|
||
int totalFrame = subGroupNode.ChildNodes.Count + 3;//补上配置xml文件版本号、配置数据版本号和全局属性数据
|
||
|
||
List<object> 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<object>();
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 按所定义的格式获取与RCU主机通讯的数据
|
||
/// </summary>
|
||
/// <param name="textData">数据内容</param>
|
||
/// <param name="mode">模式:时间同步A0,组地址调试A1,子群发布A2,全局属性A3,V80复位开关A4,配置数据版本号A5,485调光A6,网络设置A7</param>
|
||
/// <param name="totalFrame">数据总帧数</param>
|
||
/// <param name="currentFrame">当前帧数</param>
|
||
/// <returns></returns>
|
||
private static List<byte> GetSendData(List<object> 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<byte> sendData = new List<byte>();
|
||
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;
|
||
}
|
||
/// <summary>
|
||
/// 获取配置数据版本号发送数据,version为空时,提供默认值FF,FF,FF
|
||
/// </summary>
|
||
/// <param name="version"></param>
|
||
/// <returns></returns>
|
||
private static List<object> GetVersionSendData(string version)
|
||
{
|
||
List<object> textData = new List<object>();
|
||
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;
|
||
}
|
||
/// <summary>
|
||
/// 获取子群全局属性发送数据
|
||
/// </summary>
|
||
/// <param name="projectGroupAddrID">子群ID</param>
|
||
/// <param name="projectID">项目ID</param>
|
||
/// <returns></returns>
|
||
private static List<object> GetGlobalSendData(XmlNode subGroupNode)
|
||
{
|
||
List<object> textData = new List<object>();
|
||
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;
|
||
}
|
||
}
|
||
}
|