20240301_JSEQ_upperpc/JiangsuEarthquakeJM/JiangsuEarthquake/Models/SeismographModel.cs
春风过客 d7f51483a7 新增功能:
1 将地震仪数据读取功能单独成一个页面;
2024-05-13 18:51:05 +08:00

387 lines
19 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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