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