387 lines
19 KiB
C#
387 lines
19 KiB
C#
using HandyControl.Controls;
|
||
using JiangsuEarthquake.Common;
|
||
using JiangsuEarthquake.DataAccess;
|
||
using JiangsuEarthquake.ViewModels;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace JiangsuEarthquake.Models
|
||
{
|
||
public class SeismographModel
|
||
{
|
||
private byte[] syncSend { get; set; } = new byte[4] { 0xBF, 0x13, 0x97, 0x74 }; //同步字,为0xbf139774
|
||
|
||
private byte[] cmdSend { get; set; } = new byte[2]; //帧标志
|
||
|
||
private byte[] cmdRecv { get; set; } = new byte[2]; //帧标志
|
||
|
||
private byte[] lengthSend { get; set; } = new byte[2]; //从DATA开始的帧长度,单位:字节
|
||
|
||
private byte[] lengthRecv { get; set; } = new byte[2]; //从DATA开始的帧长度,单位:字节
|
||
|
||
private List<byte> dataSend { get; set; } = new List<byte>(); //数据部分
|
||
|
||
private List<byte> dataRecv { get; set; } = new List<byte>(); //数据部分
|
||
|
||
private byte[] checkCode { get; set; } = new byte[2]; //从CMD到DATA结束的CRC16校验和
|
||
|
||
private List<byte> checkByte { get; set; } = new List<byte>(); //校验码Byte
|
||
|
||
public void ParsingData(List<byte> byteList, int id)
|
||
{
|
||
if (byteList.Count == 0)
|
||
return;
|
||
|
||
//原始数据存储
|
||
string sql = $"insert into earthquakeoriginaldata(StationID,RecordTime,OriginalData) values('{id}','{DateTime.Now}','{BitConverter.ToString(byteList.ToArray())}');";
|
||
DBHelper.ExecuteNonQuery(sql, 1);
|
||
|
||
//同步字校验
|
||
if (byteList[0] != 0xBF || byteList[1] != 0x13 || byteList[2] != 0x97 || byteList[3] != 0x74)
|
||
return;
|
||
|
||
checkByte.Clear();
|
||
//CRC16校验和校验
|
||
for (int i = 4; i < byteList.Count - 2; i++)
|
||
checkByte.Add(byteList[i]);
|
||
if (!Tools.CompareByte(new byte[] { byteList[^2], byteList[^1] }, Tools.CRCCalc(checkCode.ToArray())))
|
||
return;
|
||
|
||
//长度校验
|
||
int length = BitConverter.ToInt16(new byte[] { byteList[7], byteList[6] }, 0);
|
||
if (length != byteList.Count - 8)
|
||
return;
|
||
|
||
cmdRecv = new byte[] { byteList[4], byteList[5] };
|
||
|
||
dataRecv.Clear();
|
||
for (int i = 8; i < byteList.Count - 2; i++)
|
||
dataRecv.Add(byteList[i]);
|
||
|
||
if (Tools.CompareByte(cmdRecv, new byte[] { 0x77, 0x00 })) //用于客户端与状态流服务器建立链接过程中消息交换
|
||
{
|
||
if (dataRecv.Count != 2)
|
||
return;
|
||
|
||
int response = BitConverter.ToInt16(new byte[2] { dataRecv[1], dataRecv[0] }, 0);
|
||
|
||
if (response == 100)
|
||
{
|
||
//有空闲连接时应答
|
||
//发送用户认证帧
|
||
cmdSend = new byte[] { 0x77, 0x00 };
|
||
lengthSend = new byte[] { 0x00, 0x04 };
|
||
|
||
string User = "Admin";
|
||
byte[] userByte = System.Text.Encoding.ASCII.GetBytes(User);
|
||
byte[] userByteArray = new byte[16];
|
||
if (userByte.Length != 16)
|
||
{
|
||
for (int i = 0; i < 16; i++)
|
||
{
|
||
userByteArray[i] = 0;
|
||
}
|
||
|
||
Array.Copy(userByte, 0, userByteArray, 16, userByte.Length);
|
||
}
|
||
else
|
||
{
|
||
userByteArray = userByte;
|
||
}
|
||
|
||
string Password = "Admin";
|
||
byte[] passwordByte = System.Text.Encoding.ASCII.GetBytes(Password);
|
||
byte[] passwordByteArray = new byte[40];
|
||
if (passwordByte.Length != 40)
|
||
{
|
||
for (int i = 0; i < 40; i++)
|
||
{
|
||
passwordByteArray[i] = 0;
|
||
}
|
||
|
||
Array.Copy(passwordByte, 0, passwordByteArray, 40, passwordByte.Length);
|
||
}
|
||
else
|
||
{
|
||
passwordByteArray = passwordByte;
|
||
}
|
||
|
||
dataSend.Clear();
|
||
dataSend.AddRange(userByteArray);
|
||
dataSend.AddRange(passwordByteArray);
|
||
|
||
checkByte.Clear();
|
||
checkByte.AddRange(cmdSend);
|
||
checkByte.AddRange(lengthSend);
|
||
checkByte.AddRange(userByteArray);
|
||
checkByte.AddRange(passwordByteArray);
|
||
checkCode = Tools.CRCCalc(checkByte.ToArray());
|
||
|
||
dataSend.AddRange(checkCode);
|
||
if (id == 1)
|
||
{
|
||
MainWindow.mainViewModel.clientModelDZY1.SendMessage(dataSend.ToArray());
|
||
}
|
||
else
|
||
{
|
||
MainWindow.mainViewModel.clientModelDZY2.SendMessage(dataSend.ToArray());
|
||
}
|
||
}
|
||
else if (response == 405)
|
||
{
|
||
//没有空闲连接
|
||
//重新尝试连接
|
||
|
||
}
|
||
else if (response == 200)
|
||
{
|
||
//认证成功
|
||
//连接成功
|
||
|
||
}
|
||
else if (response == 400)
|
||
{
|
||
//认证失败
|
||
//重新尝试连接
|
||
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (Tools.CompareByte(cmdRecv, new byte[] { 0xC0, 0x00 })) //台站参数
|
||
{
|
||
if (dataRecv.Count != 128)
|
||
return;
|
||
|
||
//台号
|
||
int stationNum = BitConverter.ToInt32(new byte[] { dataRecv[3], dataRecv[2], dataRecv[1], dataRecv[0] }, 0);
|
||
|
||
//台站名称
|
||
List<byte> stationNameData = new List<byte>();
|
||
for (int i = 4; i < 36; i++)
|
||
stationNameData.Add(dataRecv[i]);
|
||
string stationName = Encoding.UTF8.GetString(stationNameData.ToArray());
|
||
|
||
//台名缩写
|
||
List<byte> stationNameAbbData = new List<byte>();
|
||
for (int i = 36; i < 44; i++)
|
||
stationNameAbbData.Add(dataRecv[i]);
|
||
string stationNameAbb = Encoding.UTF8.GetString(stationNameAbbData.ToArray());
|
||
|
||
//地震计总数
|
||
short seisNum = BitConverter.ToInt16(new byte[] { dataRecv[45], dataRecv[44] }, 0);
|
||
|
||
//总通道数
|
||
short passNum = BitConverter.ToInt16(new byte[] { dataRecv[47], dataRecv[46] }, 0);
|
||
|
||
//纬度
|
||
int latitude = BitConverter.ToInt16(new byte[] { dataRecv[51], dataRecv[50], dataRecv[49], dataRecv[48] }, 0);
|
||
|
||
//经度
|
||
int longitude = BitConverter.ToInt16(new byte[] { dataRecv[55], dataRecv[54], dataRecv[53], dataRecv[52] }, 0);
|
||
|
||
//高程
|
||
int elevation = BitConverter.ToInt16(new byte[] { dataRecv[59], dataRecv[58], dataRecv[57], dataRecv[56] }, 0);
|
||
|
||
//起用日期
|
||
List<byte> enablingDateList = new List<byte>();
|
||
for (int i = 60; i < 92; i++)
|
||
enablingDateList.Add(dataRecv[i]);
|
||
string enablingDate = Encoding.UTF8.GetString(enablingDateList.ToArray());
|
||
|
||
//台网标志
|
||
string tetworkLogo = Encoding.UTF8.GetString(new byte[] { dataRecv[95], dataRecv[94], dataRecv[93], dataRecv[92] });
|
||
|
||
//软件编本
|
||
List<byte> softVersionList = new List<byte>();
|
||
for (int i = 96; i < 128; i++)
|
||
softVersionList.Add(dataRecv[i]);
|
||
string softVersion = Encoding.UTF8.GetString(softVersionList.ToArray());
|
||
|
||
//数据存储
|
||
sql = $"insert into earthquakeoriginaldata(StationID,RecordTime,StationNo,StationName," +
|
||
$"StationShortName,EarthQuakeCount,ChannelsNo,WD,JD,GaoCheng,StartTime,Station_Id," +
|
||
$"Software_Version) values('{id}','{DateTime.Now}','{stationNum}','{stationName}','{stationNameAbb}','{seisNum}','{passNum}','{latitude}','{longitude}','{elevation}','{enablingDate}','{tetworkLogo}','{softVersion}');";
|
||
DBHelper.ExecuteNonQuery(sql, 1);
|
||
|
||
//通知到前端
|
||
if (id == 1)
|
||
{
|
||
MainViewModel.earthQuakeParaSetModel1.StationID = stationNum;
|
||
MainViewModel.earthQuakeParaSetModel1.StationName = stationName;
|
||
MainViewModel.earthQuakeParaSetModel1.StationShortName = stationNameAbb;
|
||
MainViewModel.earthQuakeParaSetModel1.EarthQuakeCount = seisNum;
|
||
MainViewModel.earthQuakeParaSetModel1.ChannelsNo = passNum;
|
||
MainViewModel.earthQuakeParaSetModel1.WD = latitude;
|
||
MainViewModel.earthQuakeParaSetModel1.JD = longitude;
|
||
MainViewModel.earthQuakeParaSetModel1.GaoCheng = elevation;
|
||
MainViewModel.earthQuakeParaSetModel1.StartTime = enablingDate;
|
||
MainViewModel.earthQuakeParaSetModel1.Station_Id = tetworkLogo;
|
||
MainViewModel.earthQuakeParaSetModel1.Software_Version = softVersion;
|
||
}
|
||
else
|
||
{
|
||
MainViewModel.earthQuakeParaSetModel2.StationID = stationNum;
|
||
MainViewModel.earthQuakeParaSetModel2.StationName = stationName;
|
||
MainViewModel.earthQuakeParaSetModel2.StationShortName = stationNameAbb;
|
||
MainViewModel.earthQuakeParaSetModel2.EarthQuakeCount = seisNum;
|
||
MainViewModel.earthQuakeParaSetModel2.ChannelsNo = passNum;
|
||
MainViewModel.earthQuakeParaSetModel2.WD = latitude;
|
||
MainViewModel.earthQuakeParaSetModel2.JD = longitude;
|
||
MainViewModel.earthQuakeParaSetModel2.GaoCheng = elevation;
|
||
MainViewModel.earthQuakeParaSetModel2.StartTime = enablingDate;
|
||
MainViewModel.earthQuakeParaSetModel2.Station_Id = tetworkLogo;
|
||
MainViewModel.earthQuakeParaSetModel2.Software_Version = softVersion;
|
||
}
|
||
}
|
||
else if (Tools.CompareByte(cmdRecv, new byte[] { 0xC0, 0x50 })) //启动地震计调零
|
||
{
|
||
if (dataRecv.Count != 2)
|
||
return;
|
||
|
||
int seisNum = BitConverter.ToInt16(new byte[] { dataRecv[1], dataRecv[0] }, 0);
|
||
}
|
||
else if (Tools.CompareByte(cmdRecv, new byte[] { 0xC0, 0x51 })) //停止地震计调零
|
||
{
|
||
if (dataRecv.Count != 2)
|
||
return;
|
||
|
||
int seisNum = BitConverter.ToInt16(new byte[] { dataRecv[1], dataRecv[0] }, 0);
|
||
}
|
||
else if (Tools.CompareByte(cmdRecv, new byte[] { 0xC0, 0x66 })) //运行状态信息
|
||
{
|
||
if (dataRecv.Count != 56)
|
||
return;
|
||
|
||
//外部供电电压
|
||
float supplyVoltage = BitConverter.ToInt16(new byte[] { dataRecv[1], dataRecv[0] }, 0) * 0.1f;
|
||
|
||
//后备电池电压
|
||
float batteryVoltage = BitConverter.ToInt16(new byte[] { dataRecv[3], dataRecv[2] }, 0) * 0.1f;
|
||
|
||
//压力
|
||
int pressure = BitConverter.ToInt16(new byte[] { dataRecv[5], dataRecv[4] }, 0);
|
||
|
||
//温度
|
||
float temperature = BitConverter.ToInt16(new byte[] { dataRecv[7], dataRecv[6] }, 0) * 0.1f;
|
||
|
||
//地震计倾斜角度
|
||
float tiltAngleSeis = BitConverter.ToInt16(new byte[] { dataRecv[9], dataRecv[8] }, 0) * 0.1f;
|
||
|
||
//OBS 倾斜角度
|
||
float tiltAngleOBS = BitConverter.ToInt16(new byte[] { dataRecv[11], dataRecv[10] }, 0) * 0.1f;
|
||
|
||
//钟差
|
||
int clockDeviation = BitConverter.ToInt16(new byte[] { dataRecv[13], dataRecv[12] }, 0);
|
||
|
||
//频差
|
||
float freDifference = BitConverter.ToInt16(new byte[] { dataRecv[15], dataRecv[14] }, 0) * 0.01f;
|
||
|
||
//CF 卡总空间
|
||
int totalSpaceCF = BitConverter.ToInt16(new byte[] { dataRecv[19], dataRecv[18], dataRecv[17], dataRecv[16] }, 0);
|
||
|
||
//CF 卡可用空间
|
||
int canUseSpaceCF = BitConverter.ToInt16(new byte[] { dataRecv[23], dataRecv[22], dataRecv[21], dataRecv[20] }, 0);
|
||
|
||
//SD1 卡总空间
|
||
int totalSpaceSD1 = BitConverter.ToInt16(new byte[] { dataRecv[27], dataRecv[26], dataRecv[25], dataRecv[24] }, 0);
|
||
|
||
//SD1 卡可用空间
|
||
int canUseSpaceSD1 = BitConverter.ToInt16(new byte[] { dataRecv[31], dataRecv[30], dataRecv[29], dataRecv[28] }, 0);
|
||
|
||
//SD2 卡总空间
|
||
int totalSpaceSD2 = BitConverter.ToInt16(new byte[] { dataRecv[35], dataRecv[34], dataRecv[33], dataRecv[32] }, 0);
|
||
|
||
//SD2 卡可用空间
|
||
int canUseSpaceSD2 = BitConverter.ToInt16(new byte[] { dataRecv[39], dataRecv[38], dataRecv[37], dataRecv[36] }, 0);
|
||
|
||
//地震计 U 零点
|
||
float zeroPointU = BitConverter.ToInt16(new byte[] { dataRecv[43], dataRecv[42], dataRecv[41], dataRecv[40] }, 0) * 0.1f;
|
||
|
||
//地震计 V 零点
|
||
float zeroPointV = BitConverter.ToInt16(new byte[] { dataRecv[47], dataRecv[46], dataRecv[45], dataRecv[44] }, 0) * 0.1f;
|
||
|
||
//地震计 W 零点
|
||
float zeroPointW = BitConverter.ToInt16(new byte[] { dataRecv[51], dataRecv[50], dataRecv[49], dataRecv[48] }, 0) * 0.1f;
|
||
|
||
//寻北角度
|
||
float northSeekingAngle = BitConverter.ToInt16(new byte[] { dataRecv[55], dataRecv[54], dataRecv[53], dataRecv[52] }, 0) * 0.1f;
|
||
|
||
//数据存储
|
||
sql = $"insert into earthquakestate(StationID,RecordTime,Out_Vol,Backup_Vol,Pre,Tem," +
|
||
$"Sei_Tilt_Angle,OBS_Tilt_Angle,Species_Dif,Frequency_Dif,CF_Total_Cap," +
|
||
$"CF_Usable_Cap,SD_Total_Cap1,SD_Usable_Cap1,SD_Total_Cap2,SD_Usable_Cap2," +
|
||
$"Sei_U_Point,Sei_V_Point,Sei_W_Point,North_Angle) values('{id}','{DateTime.Now}','{supplyVoltage}','{batteryVoltage}','{pressure}'," +
|
||
$"'{temperature}','{tiltAngleSeis}','{tiltAngleOBS}','{clockDeviation}'," +
|
||
$"'{freDifference}','{totalSpaceCF}','{canUseSpaceCF}','{totalSpaceSD1}'," +
|
||
$"'{canUseSpaceSD1}','{totalSpaceSD2}','{canUseSpaceSD2}','{zeroPointU}'," +
|
||
$"'{zeroPointV}','{zeroPointW}','{northSeekingAngle}');";
|
||
DBHelper.ExecuteNonQuery(sql, 1);
|
||
|
||
//通知到前端
|
||
if (id == 1)
|
||
{
|
||
MainViewModel.earthquakeSensorModel1.Out_Vol = supplyVoltage;
|
||
MainViewModel.earthquakeSensorModel1.Backup_Vol = batteryVoltage;
|
||
MainViewModel.earthquakeSensorModel1.Pre = pressure;
|
||
MainViewModel.earthquakeSensorModel1.Tem = temperature;
|
||
MainViewModel.earthquakeSensorModel1.Sei_Tilt_Angle = tiltAngleSeis;
|
||
MainViewModel.earthquakeSensorModel1.OBS_Tilt_Angle = tiltAngleOBS;
|
||
MainViewModel.earthquakeSensorModel1.Species_Dif = clockDeviation;
|
||
MainViewModel.earthquakeSensorModel1.Frequency_Dif = freDifference;
|
||
MainViewModel.earthquakeSensorModel1.CF_Total_Cap = totalSpaceCF;
|
||
MainViewModel.earthquakeSensorModel1.CF_Usable_Cap = canUseSpaceCF;
|
||
MainViewModel.earthquakeSensorModel1.SD_Total_Cap1 = totalSpaceSD1;
|
||
MainViewModel.earthquakeSensorModel1.SD_Usable_Cap1 = canUseSpaceSD1;
|
||
MainViewModel.earthquakeSensorModel1.SD_Total_Cap2 = totalSpaceSD2;
|
||
MainViewModel.earthquakeSensorModel1.SD_Usable_Cap2 = canUseSpaceSD2;
|
||
MainViewModel.earthquakeSensorModel1.Sei_U_Point = zeroPointU;
|
||
MainViewModel.earthquakeSensorModel1.Sei_V_Point = zeroPointV;
|
||
MainViewModel.earthquakeSensorModel1.Sei_W_Point = zeroPointW;
|
||
MainViewModel.earthquakeSensorModel1.North_Angle = northSeekingAngle;
|
||
}
|
||
else
|
||
{
|
||
MainViewModel.earthquakeSensorModel2.Out_Vol = supplyVoltage;
|
||
MainViewModel.earthquakeSensorModel2.Backup_Vol = batteryVoltage;
|
||
MainViewModel.earthquakeSensorModel2.Pre = pressure;
|
||
MainViewModel.earthquakeSensorModel2.Tem = temperature;
|
||
MainViewModel.earthquakeSensorModel2.Sei_Tilt_Angle = tiltAngleSeis;
|
||
MainViewModel.earthquakeSensorModel2.OBS_Tilt_Angle = tiltAngleOBS;
|
||
MainViewModel.earthquakeSensorModel2.Species_Dif = clockDeviation;
|
||
MainViewModel.earthquakeSensorModel2.Frequency_Dif = freDifference;
|
||
MainViewModel.earthquakeSensorModel2.CF_Total_Cap = totalSpaceCF;
|
||
MainViewModel.earthquakeSensorModel2.CF_Usable_Cap = canUseSpaceCF;
|
||
MainViewModel.earthquakeSensorModel2.SD_Total_Cap1 = totalSpaceSD1;
|
||
MainViewModel.earthquakeSensorModel2.SD_Usable_Cap1 = canUseSpaceSD1;
|
||
MainViewModel.earthquakeSensorModel2.SD_Total_Cap2 = totalSpaceSD2;
|
||
MainViewModel.earthquakeSensorModel2.SD_Usable_Cap2 = canUseSpaceSD2;
|
||
MainViewModel.earthquakeSensorModel2.Sei_U_Point = zeroPointU;
|
||
MainViewModel.earthquakeSensorModel2.Sei_V_Point = zeroPointV;
|
||
MainViewModel.earthquakeSensorModel2.Sei_W_Point = zeroPointW;
|
||
MainViewModel.earthquakeSensorModel2.North_Angle = northSeekingAngle;
|
||
}
|
||
}
|
||
else if (Tools.CompareByte(cmdRecv, new byte[] { 0xC0, 0x90 })) //启动地震计调平
|
||
{
|
||
if (dataRecv.Count != 2)
|
||
return;
|
||
|
||
int seisNum = BitConverter.ToInt16(new byte[] { dataRecv[1], dataRecv[0] }, 0);
|
||
}
|
||
else if (Tools.CompareByte(cmdRecv, new byte[] { 0xC0, 0x91 })) //停止地震计调平
|
||
{
|
||
if (dataRecv.Count != 2)
|
||
return;
|
||
|
||
int seisNum = BitConverter.ToInt16(new byte[] { dataRecv[1], dataRecv[0] }, 0);
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|