using Panuon.WPF.UI;
using SWRIS.Core;
using SWRIS.Dtos;
using SWRIS.Enums;
using SWRIS.Events;
using SWRIS.Extensions;
using SWRIS.Models;
using SWRIS.Models.ViewModel;
using SWRIS.Pages;
using SWRIS.Repository;
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Speech.Synthesis;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
namespace SWRIS
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : WindowX, IComponentConnector
{
private readonly SpeechSynthesizer speech;
public MainViewModel MainView { get; set; }
private readonly IRecordRepository _recordRepository;
private readonly IAlarmRepository _alarmRepository;
public MainWindow()
{
InitializeComponent();
_recordRepository = new RecordRepository();
_alarmRepository = new AlarmRepository();
speech = new SpeechSynthesizer()
{
Rate = 1,
Volume = 100
};
MainView = new MainViewModel()
{
AppName = App.Config.AppName,
Version = App.Config.Version,
Copyright = App.Config.Copyright,
SwitchInstances = App.Config.SwitchInstances
};
Application.Current.MainWindow = this;
App.TcpServer.ClientConnected += TcpServer_ClientConnected;
App.TcpServer.ClientDisconnected += TcpServer_ClientDisconnected;
App.TcpServer.AlarmDataReceived += TcpServer_AlarmDataReceived;
App.TcpServer.DetectionDataReceived += TcpServer_DetectionDataReceived;
App.TcpServer.RealTimeDataReceived += TcpServer_RealTimeDataReceived;
App.TcpServer.FaultDataReceived += TcpServer_FaultDataReceived;
App.TcpServer.DetectionRawDataReceived += TcpServer_DetectionRawDataReceived;
App.TcpServer.DetectionRawDataResultReceived += TcpServer_DetectionRawDataResultReceived;
App.TcpServer.DetectionStatusResultReceived += TcpServer_DetectionStatusResultReceived;
App.TcpServer.DebugMessageReceived += TcpServer_DebugMessageReceived;
App.TcpServer.HeartbeatReceived += TcpServer_HeartbeatReceived;
App.TcpServer.UpgradedRequestResultReceived += TcpServer_UpgradedRequestResultReceived;
App.Calibration.ConnectionStateChanged += Calibration_ConnectionStateChanged;
App.Calibration.LimitStateChanged += Calibration_LimitStateChanged;
App.TcpServer.Start();
DataContext = MainView;
}
///
/// 接收心跳数据
///
private void TcpServer_HeartbeatReceived(object sender, HeartbeatReceviedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null)
{
equipmentData.IsHeartbeatReceived = true;
}
}
///
/// 接收调试信息
///
private void TcpServer_DebugMessageReceived(object sender, DebugMessageReceivedEventArgs e)
{
if (e.IpAddress.IsNullOrEmpty() && e.SerialNo.IsNullOrEmpty())
{
DebugMessageShow(e.Message);
}
else
{
DebugMessageShow(e.Message, e.IpAddress, e.SerialNo);
}
}
public void DebugMessageShow(string message, string ipAddress, string serialNo)
{
if (App.Config.ShowDebugMessage)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == ipAddress || (serialNo != null && c.SerialNo == serialNo));
if (equipmentData != null)
{
equipmentData.DebugMessage.DateTime = DateTime.Now;
equipmentData.DebugMessage.Message = message;
}
}
}
public void DebugMessageShow(string message)
{
if (App.Config.ShowDebugMessage)
{
MainView.DebugMessage.DateTime = DateTime.Now;
MainView.DebugMessage.Message = message;
}
}
///
/// 标定限位状态更改
///
private void Calibration_LimitStateChanged(object sender, LimitData limitData)
{
foreach (var equipment in App.DataCenter.Equipments)
{
foreach (var limit in equipment.Limits)
{
if (limit.Name == limitData.Name && limit.IsEnable)
{
if (limitData.State == LimitState.AtLimit)
{
limit.State = LimitState.AtLimit;
// 当前运行状态添加预标定状态
equipment.RunningStatus |= RunningStatus.PreCalibration;
if (App.TcpServer.SendRealTimeAbsolutePositionData((float)limitData.Position, equipment.SerialNo, equipment.ClientSocket))
{
DebugMessageShow($"{limitData.Name}标定成功", equipment.IpAddress, equipment.SerialNo);
}
}
else if (limitData.State == LimitState.NotInLimit)
{
limit.State = LimitState.NotInLimit;
}
}
}
}
}
///
/// 标定模块连接状态更改
///
private void Calibration_ConnectionStateChanged(object sender, bool isConnect)
{
foreach (var equipment in App.DataCenter.Equipments)
{
foreach (var limit in equipment.Limits)
{
if (isConnect)
{
if (limit.State == LimitState.Offline)
{
limit.State = LimitState.NotInLimit;
}
}
else
{
if (limit.State != LimitState.Offline)
{
limit.State = LimitState.Offline;
}
}
}
}
}
///
/// 接收检测状态开关结果
///
private void TcpServer_DetectionStatusResultReceived(object sender, DetectionStatusResultReceivedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null)
{
if (equipmentData.RunningStatus.HasFlag(RunningStatus.PreStop))
{
equipmentData.RunningStatus = RunningStatus.Stopped;
Application.Current.Dispatcher.Invoke(() =>
{
NoticeBox.Show("自动检测停止", "通知", MessageBoxIcon.Warning, true, 3000);
});
}
else if (equipmentData.RunningStatus.HasFlag(RunningStatus.PreRunning))
{
equipmentData.RunningStatus = RunningStatus.RunningNormal;
Application.Current.Dispatcher.Invoke(() =>
{
NoticeBox.Show("自动检测恢复", "通知", MessageBoxIcon.Success, true, 3000);
});
}
else if (equipmentData.RunningStatus.HasFlag(RunningStatus.PreCalibration))
{
equipmentData.RunningStatus = RunningStatus.RunningNormal;
}
}
}
///
/// 接收故障数据
///
private void TcpServer_FaultDataReceived(object sender, FaultDataReceivedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
equipmentData?.Faults.Add(e.FaultData);
}
///
/// 接收实时数据
///
private void TcpServer_RealTimeDataReceived(object sender, RealTimeDataReceivedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null)
{
equipmentData.Speed = Math.Round(e.RealTimeData.Speed * 60, 2);
equipmentData.Position = e.RealTimeData.Position;
equipmentData.RunningStatus = e.RealTimeData.Status;
equipmentData.AbsolutePosition = e.RealTimeData.AbsolutePosition;
equipmentData.LiftHeight = (equipmentData.RopeLength - equipmentData.AbsolutePosition) / equipmentData.LiftHightRatio;
equipmentData.Direction = equipmentData.Speed > 0 ? DirectionState.Forward :
(equipmentData.Speed == 0f ? DirectionState.Stoped : DirectionState.Reverse);
Console.WriteLine(equipmentData.AbsolutePosition);
equipmentData.AddSpeedData(equipmentData.Speed);
}
}
///
/// 客户端连接成功
///
private void TcpServer_ClientConnected(object sender, ClientConnectedEventArgs e)
{
var equipment = App.Config.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipment == null)
{
LogHelper.Error($"未找到设备,IP地址:{e.IpAddress}");
return;
}
var server = (TcpServerFrame)sender;
server.SendTurnLiveStreamData(true, equipment.SerialNo, e.ClientSocket);
Thread.Sleep(20);
server.SendSetClockData(DateTime.Now.DateTimeToTimestamp(), equipment.SerialNo, e.ClientSocket);
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null)
{
equipmentData.IsConnect = true;
equipmentData.ClientSocket = e.ClientSocket;
if (equipmentData.RunningStatus != RunningStatus.RunningNormal)
{
equipmentData.RunningStatus |= RunningStatus.RunningNormal;
}
}
}
///
/// 客户端连接断开
///
private void TcpServer_ClientDisconnected(object sender, ClientDisconnectedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null)
{
equipmentData.IsConnect = false;
equipmentData.ClientSocket = null;
equipmentData.Speed = 0;
equipmentData.AbsolutePosition = 0;
equipmentData.Position = 0;
equipmentData.Direction = DirectionState.Stoped;
}
}
///
/// 接收检测结果
///
private void TcpServer_DetectionDataReceived(object sender, DetectionDataReceivedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null)
{
e.DetectionData.DetectionNo = equipmentData.DetectionNo;
equipmentData.DetectionData = e.DetectionData;
}
}
///
/// 接检测原始数据结果
///
private void TcpServer_DetectionRawDataResultReceived(object sender, DetectionRawDataResultReceivedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null)
{
// 处理检测原始结果数据
if (e.DetectionRawResultData.Code == 0)
{
if (equipmentData.DetectionData != null)
{
equipmentData.DetectionData.RawResultData = e.DetectionRawResultData;
}
}
else
{
LogHelper.Error($"获取检测原始数据失败,错误码:{e.DetectionRawResultData.Code}");
}
}
}
///
/// 接受检测结果原始数据
///
private async void TcpServer_DetectionRawDataReceived(object sender, DetectionRawDataReceivedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null)
{
if (equipmentData.DisableAlarm)
{
DebugMessageShow($"获取检测结果原始数据结束", equipmentData.IpAddress, equipmentData.SerialNo);
return;
}
await Task.Run(() =>
{
if (equipmentData.DetectionData != null && equipmentData.DetectionData.RawResultData != null)
{
DebugMessageShow($"数据接收:{e.DetectionRawData.PacketNumber}/{e.DetectionRawData.TotalPackets}", equipmentData.IpAddress, equipmentData.SerialNo);
if (e.DetectionRawData.PacketNumber == 1)
{
equipmentData.DetectionData.RawDataReceiving = true;
equipmentData.DetectionData.RawData = new MemoryStream();
equipmentData.DetectionData.RawData.Write(e.DetectionRawData.Data, 0, e.DetectionRawData.Data.Length);
}
else if (e.DetectionRawData.PacketNumber <= e.DetectionRawData.TotalPackets)
{
// 添加原始数据到检测数据中
equipmentData.DetectionData.RawData.Write(e.DetectionRawData.Data, 0, e.DetectionRawData.Data.Length);
// 如果是最后一包数据,处理检测数据
if (e.DetectionRawData.PacketNumber == e.DetectionRawData.TotalPackets)
{
// 生成数据文件路径
(string absolutePath, string relativePath) = DatFileHandler.GetDatFilePath(equipmentData.SerialNo);
// 处理检测数据逻辑
var record = new RecordDto
{
RopeName = equipmentData.RopeName,
RopeNumber = equipmentData.RopeNumber,
StartPoint = equipmentData.DetectionData.StartPoint,
EndPoint = equipmentData.DetectionData.EndPoint,
DetectedSpeed = equipmentData.DetectionData.DetectedSpeed,
DetectionLength = equipmentData.DetectionData.DetectionLength,
StartTime = equipmentData.DetectionData.StartTime.TimestampToDateTime(),
EndTime = equipmentData.DetectionData.EndTime.TimestampToDateTime(),
SensorCount = equipmentData.DetectionData.RawResultData.SensorCount,
SamplingStep = equipmentData.DetectionData.RawResultData.SamplingStep,
DataFilePath = relativePath,
InUseSensors = string.Join(",", equipmentData.InUseSensor)
};
foreach (var damage in equipmentData.DetectionData.Damages)
{
var alarmCount = _alarmRepository.AddAlarm(new AlarmDataModel
{
DamageLevel = damage.DamageLevel,
DamagePosition = damage.DamagePoint,
DamageValue = damage.DamageValue,
RopeNumber = equipmentData.RopeNumber
}, AlarmSourceType.Detection, App.Config.DamageExtent);
if (alarmCount >= App.Config.AlarmValidCount)
{
record.Damages.Add(new DamageDto
{
DamageLevel = damage.DamageLevel,
DamagePoint = damage.DamagePoint,
DamageValue = damage.DamageValue,
});
record.DamageCount++;
//纠正健康度 以客户端上传的损伤数据 重新计算
if ((int)record.RiskLevel < (int)damage.DamageLevel)
{
record.RiskLevel = (RiskLevel)damage.DamageLevel;
}
}
}
equipmentData.RiskLevel = record.RiskLevel;
if (record.DamageCount > 0)
{
int? recordId = _recordRepository.CreateRecord(record);
if (recordId.HasValue)
{
record.Id = recordId.Value;
AddRecordToPageRecords(record);
if (!DatFileHandler.CreateDatFile(absolutePath, equipmentData.DetectionData.RawData))
{
LogHelper.Error($"创建检测数据文件失败,路径:{absolutePath}");
}
DebugMessageShow($"检测数据记录成功", equipmentData.IpAddress, equipmentData.SerialNo);
if ((int)record.RiskLevel >= (int)App.Config.SoundRiskLevel)
{
Application.Current.Dispatcher.Invoke(() =>
{
speech.SpeakAsync($"{equipmentData.RopeName},检测到{record.DamageCount}处损伤");
});
}
}
else
{
LogHelper.Error("检测数据记录失败");
}
}
else
{
DebugMessageShow($"检测完成,未发现损伤,本次检测不做记录。", equipmentData.IpAddress, equipmentData.SerialNo);
}
equipmentData.DetectionData.RawDataReceiving = false;
}
}
}
});
}
}
///
/// 接收报警数据
///
private void TcpServer_AlarmDataReceived(object sender, AlarmDataReceivedEventArgs e)
{
var equipmentData = App.DataCenter.Equipments.FirstOrDefault(c => c.IpAddress == e.IpAddress);
if (equipmentData != null && equipmentData.IsSpeedStable && !equipmentData.DisableAlarm)
{
Dispatcher.InvokeAsync(() =>
{
e.AlarmData.RopeNumber = equipmentData.RopeNumber;
var alarmCount = _alarmRepository.AddAlarm(e.AlarmData, AlarmSourceType.RealTime, App.Config.DamageExtent);
if (alarmCount >= App.Config.AlarmValidCount)
{
equipmentData.AddAlarm(e.AlarmData);
}
});
}
}
private void TcpServer_UpgradedRequestResultReceived(object sender, UpgradedResultReceivedEventArgs e)
{
Dispatcher.InvokeAsync(async () =>
{
if (e.Code == 0)
{
await Task.Delay(2000);
string url = $"http://192.168.1.200"; // 替换为您的网页地址
Extensions.Tools.OpenUrl(url);
}
});
}
public void AddRecordToPageRecords(RecordDto record)
{
Application.Current.Dispatcher.Invoke(() =>
{
if (main_frame.Content is Page currentPage && currentPage != null)
{
var simpleRecord = record.ToSimpleRecordDto();
switch (currentPage.Title)
{
case "OneRopePage":
if (currentPage.DataContext is OneRopeViewModel oneRopeView)
{
oneRopeView.AddRecord(simpleRecord);
}
break;
case "TwoRopesPage":
if (currentPage.DataContext is TwoRopesViewModel twoRopesView)
{
twoRopesView.AddRecord(simpleRecord);
}
break;
case "ThreeRopesPage":
if (currentPage.DataContext is ThreeRopesViewModel threeRopesView)
{
threeRopesView.AddRecord(simpleRecord);
}
break;
case "FourRopesPage":
if (currentPage.DataContext is FourRopesViewModel fourRopesView)
{
fourRopesView.AddRecord(simpleRecord);
}
break;
}
}
});
}
private void WindowX_Loaded(object sender, RoutedEventArgs e)
{
NavigateToPage("Home");
}
public void NavigatePage(Uri uri)
{
main_frame.NavigationService.Navigate(uri);
}
private void NavigateToPage(object pageName)
{
switch (pageName)
{
case "Home":
MainView.CurrentPage = "Home";
int equipmentCount = App.Config.Equipments.Count;
switch (equipmentCount)
{
case 1:
main_frame.NavigationService.Navigate(new Uri($"Pages/RealTime/OneRopePage.xaml", uriKind: UriKind.Relative));
break;
case 2:
main_frame.NavigationService.Navigate(new Uri($"Pages/RealTime/TwoRopesPage.xaml", uriKind: UriKind.Relative));
break;
case 3:
main_frame.NavigationService.Navigate(new Uri($"Pages/RealTime/ThreeRopesPage.xaml", uriKind: UriKind.Relative));
break;
case 4:
main_frame.NavigationService.Navigate(new Uri($"Pages/RealTime/FourRopesPage.xaml", uriKind: UriKind.Relative));
break;
}
break;
case "Record":
MainView.CurrentPage = "Record";
main_frame.NavigationService.Navigate(new Uri($"Pages/RecordPage.xaml", uriKind: UriKind.Relative));
break;
}
}
private void Menu_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (sender is TextBlock menuItem)
{
CleanNavigation(main_frame);
NavigateToPage(menuItem?.Tag);
}
}
private void CleanNavigation(Frame frame)
{
while (frame.CanGoBack)
frame.RemoveBackEntry();
}
private void StackPanel_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.ClickCount == 2)
{
Left = 0;
Top = 0;
}
}
private void Setting_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
SettingDialog settingDialog = new SettingDialog();
if (settingDialog.ShowDialog(true) == true)
{
if (settingDialog.IsAutoStart)
{
App.RestartApplication();
}
}
}
private void Window_Closing(object sender, CancelEventArgs e)
{
App.TcpServer?.Dispose();
speech?.Dispose();
}
private void Minimize_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
WindowState = WindowState.Minimized;
}
private void Close_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var result = MessageBoxX.Show(this, "退出后将无法进行实时检测,是否确认退出程序?", "警告",
MessageBoxButton.YesNo,
MessageBoxIcon.Warning, DefaultButton.YesOK);
if (result == MessageBoxResult.Yes)
{
Close();
}
}
private void SwitchToInstance_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (sender is Border instanceBorder && instanceBorder.Tag != null)
{
App.SwitchToExistingInstance(instanceBorder.Tag.ToString());
}
}
}
}