Files
Web_CRICS_Server_VS2010_Prod/Common/ProtocalData.cs

312 lines
16 KiB
C#
Raw Normal View History

2025-12-11 09:17:16 +08:00
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全局属性A3V80复位开关A4配置数据版本号A5485调光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;
}
}
}