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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|