Newer
Older
Correlator / Correlator / ViewModels / MainWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;
using Correlator.DataService;
using Correlator.Events;
using Correlator.Model;
using Correlator.SensorHubTag;
using Correlator.Util;
using Correlator.Views;
using HandyControl.Controls;
using MathWorks.MATLAB.NET.Arrays;
using Newtonsoft.Json;
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using ComboBox = System.Windows.Controls.ComboBox;

namespace Correlator.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        #region DispatcherTimer

        private readonly DispatcherTimer _checkSerialPortTimer = new DispatcherTimer
        {
            Interval = new TimeSpan(0, 0, 7)
        };

        private readonly DispatcherTimer _timer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(1)
        };

        private readonly DispatcherTimer _batteryTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromMinutes(5)
        };


        //运行时间Timer
        private readonly DispatcherTimer _runningTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(1)
        };

        //自动截屏倒计时
        private readonly DispatcherTimer _snapShotTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(3)
        };

        //指令记录刷新计时器
        private readonly DispatcherTimer _commandTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(1)
        };

        #endregion

        #region 变量

        private readonly IEventAggregator _eventAggregator;
        private readonly IApplicationDataService _dataService;
        private readonly IDialogService _dialogService;
        private readonly ISerialPortService _serialPortService;
        private readonly IAudioService _audioService;
        private readonly ICommandService _commandService;
        private readonly BackgroundWorker _backgroundWorker;
        private readonly string _today;
        private readonly string _week;
        private MainWindow _mainWindow;
        private string _locateDataDir;
        private int _locateTimes;
        private string _snapShotPath = string.Empty;
        private ParamConfigModel _paramConfig;

        //计算时间
        private int _runningSeconds;

        //Matlab算法
        private static readonly Lazy<CorrelatorSingle.Correlator> LazyCorrelator =
            new Lazy<CorrelatorSingle.Correlator>(() => new CorrelatorSingle.Correlator());

        #endregion

        #region VM属性

        private string _currentTime;

        public string CurrentTime
        {
            get => _currentTime;
            private set
            {
                _currentTime = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 红色发射机信号强度0-5
        /// </summary>
        private int _redTransmitterSignal;

        public int RedTransmitterSignal
        {
            get => _redTransmitterSignal;
            private set
            {
                _redTransmitterSignal = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 蓝色发射机信号强度0-5
        /// </summary>
        private int _blueTransmitterSignal;

        public int BlueTransmitterSignal
        {
            get => _blueTransmitterSignal;
            private set
            {
                _blueTransmitterSignal = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 绑定干扰频段值
        /// </summary>
        private string _interferenceFrequency = "无";

        public string InterferenceFrequency
        {
            get => _interferenceFrequency;
            private set
            {
                _interferenceFrequency = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 绑定过信噪比
        /// </summary>
        private string _snr = "无";

        public string Snr
        {
            get => _snr;
            private set
            {
                _snr = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 绑定过滤器值
        /// </summary>
        private string _filterValue = " ~ Hz";

        public string FilterValue
        {
            get => _filterValue;
            private set
            {
                _filterValue = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 绑定声速值
        /// </summary>
        private string _soundSpeed = "0";

        public string SoundSpeed
        {
            get => _soundSpeed;
            private set
            {
                _soundSpeed = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 绑定采样率
        /// </summary>
        private int _soundSampleRate = 7500;

        public int SoundSampleRate
        {
            get => _soundSampleRate;
            private set
            {
                _soundSampleRate = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 红色发射机是否故障
        /// </summary>
        private bool _redTransmitterState;

        public bool RedTransmitterState
        {
            get => _redTransmitterState;
            set
            {
                _redTransmitterState = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 蓝色发射机是否故障
        /// </summary>
        private bool _blueTransmitterState;

        public bool BlueTransmitterState
        {
            get => _blueTransmitterState;
            private set
            {
                _blueTransmitterState = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 红色发射机距离 
        /// </summary>
        private double _redTransmitterDistance;

        public double RedTransmitterDistance
        {
            get => _redTransmitterDistance;
            private set
            {
                _redTransmitterDistance = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 蓝色发射机距离
        /// </summary>
        private double _blueTransmitterDistance;

        public double BlueTransmitterDistance
        {
            get => _blueTransmitterDistance;
            private set
            {
                _blueTransmitterDistance = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 红色发射机电量 0-100
        /// </summary>
        private int _redTransmitterBattery;

        public int RedTransmitterBattery
        {
            get => _redTransmitterBattery;
            set
            {
                _redTransmitterBattery = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 蓝色发射机电量 0-100
        /// </summary>
        private int _blueTransmitterBattery;

        public int BlueTransmitterBattery
        {
            get => _blueTransmitterBattery;
            set
            {
                _blueTransmitterBattery = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 电脑电量 0-100
        /// </summary>
        private int _computerBattery;

        public int ComputerBattery
        {
            get => _computerBattery;
            set
            {
                _computerBattery = value;
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 绑定经过了值
        /// </summary>
        private string _elapseTime = "0";

        public string ElapseTime
        {
            get => _elapseTime;
            private set
            {
                _elapseTime = value;
                RaisePropertyChanged();
            }
        }

        private string _connectColorBrush = "LightGray";

        public string ConnectColorBrush
        {
            get => _connectColorBrush;
            private set
            {
                _connectColorBrush = value;
                RaisePropertyChanged();
            }
        }

        private ObservableCollection<string> _pipeMaterialsArray;

        public ObservableCollection<string> PipeMaterialsArray
        {
            get => _pipeMaterialsArray;
            set
            {
                _pipeMaterialsArray = value;
                RaisePropertyChanged();
            }
        }

        private string _materialName = string.Empty;

        public string MaterialName
        {
            get => _materialName;
            set
            {
                _materialName = value;
                RaisePropertyChanged();
            }
        }

        private string _pipeDiameter = string.Empty;

        public string PipeDiameter
        {
            get => _pipeDiameter;
            set
            {
                _pipeDiameter = value;
                RaisePropertyChanged();
            }
        }

        private string _pipeLength = string.Empty;

        public string PipeLength
        {
            get => _pipeLength;
            set
            {
                _pipeLength = value;
                RaisePropertyChanged();
            }
        }

        private string _frequencyInterval = "100 ~ 3000Hz";

        public string FrequencyInterval
        {
            get => _frequencyInterval;
            private set
            {
                _frequencyInterval = value;
                RaisePropertyChanged();
            }
        }

        private string _lowFrequency = string.Empty;

        public string LowFrequency
        {
            get => _lowFrequency;
            set
            {
                _lowFrequency = value;
                RaisePropertyChanged();
            }
        }

        private string _highFrequency = string.Empty;

        public string HighFrequency
        {
            get => _highFrequency;
            set
            {
                _highFrequency = value;
                RaisePropertyChanged();
            }
        }

        //是否已开始采集或者计算数据
        private bool _startButtonIsEnabled;

        public bool StartButtonEnabled
        {
            get => _startButtonIsEnabled;
            private set
            {
                _startButtonIsEnabled = value;
                RaisePropertyChanged();
            }
        }

        private CorrelatorDataModel _correlatorData = new CorrelatorDataModel();

        public CorrelatorDataModel CorrelatorData
        {
            get => _correlatorData;
            set
            {
                _correlatorData = value;
                RaisePropertyChanged();
            }
        }

        private CommandModel _lastCommand;

        public CommandModel LastCommand
        {
            get => _lastCommand;
            set
            {
                _lastCommand = value;
                RaisePropertyChanged();
            }
        }

        #endregion

        #region PC电量状态

        [DllImport("kernel32.dll", EntryPoint = "GetSystemPowerStatus")]
        private static extern void GetSystemPowerStatus(ref SystemConfig.SystemPowerStatus lpSystemPowerStatus);

        #endregion

        #region DelegateCommand

        public DelegateCommand<MainWindow> WindowLoadedCommand { set; get; }
        public DelegateCommand CloseWindowCommand { private set; get; }
        public DelegateCommand<Popup> OpenFolderCommand { private set; get; }
        public DelegateCommand<Popup> OpenImageFileCommand { private set; get; }
        public DelegateCommand<Popup> OpenAudioFileCommand { private set; get; }
        public DelegateCommand OpenListenAudioCommand { private set; get; }
        public DelegateCommand ShowWaveCommand { private set; get; }
        public DelegateCommand OpenNumericKeypadCommand { private set; get; }
        public DelegateCommand<ComboBox> PipeItemSelectedCommand { set; get; }
        public DelegateCommand DetectNoiseCommand { private set; get; }
        public DelegateCommand<Popup> ExtensionsCommand { private set; get; }
        public DelegateCommand<Popup> SoundSampleRateCommand { private set; get; }
        public DelegateCommand<Popup> SoundSpeedCommand { private set; get; }
        public DelegateCommand<Popup> ImportDataCommand { private set; get; }
        public DelegateCommand<Popup> HelpCenterCommand { private set; get; }
        public DelegateCommand<Popup> ShowLogCommand { private set; get; }
        public DelegateCommand<Popup> ShowApplicationInfoCommand { private set; get; }
        public DelegateCommand SaveAudioCommand { private set; get; }
        public DelegateCommand ResetParamCommand { private set; get; }
        public DelegateCommand SnapShotCommand { private set; get; }
        public DelegateCommand StartCollectDataCommand { private set; get; }

        #endregion

        public MainWindowViewModel(IEventAggregator eventAggregator, IApplicationDataService dataService,
            IDialogService dialogService, ISerialPortService serialPortService, IAudioService audioService,
            ICommandService commandService)
        {
            _eventAggregator = eventAggregator;
            _dataService = dataService;
            _dialogService = dialogService;
            _serialPortService = serialPortService;
            _audioService = audioService;
            _commandService = commandService;

            // 算法计算后台任务
            _backgroundWorker = new BackgroundWorker();
            _backgroundWorker.WorkerReportsProgress = true;
            _backgroundWorker.WorkerSupportsCancellation = true;
            _backgroundWorker.DoWork += Worker_OnDoWork;
            _backgroundWorker.ProgressChanged += Worker_OnProgressChanged;
            _backgroundWorker.RunWorkerCompleted += Worker_OnRunWorkerCompleted;

            _pipeMaterialsArray = new ObservableCollection<string>();
            var pipeMaterials = dataService.GetPipeMaterial();
            foreach (var material in pipeMaterials)
            {
                PipeMaterialsArray.Add(material.ChineseMaterial);
            }

            //获取当前日期,星期
            _today = DateTime.Now.ToString("yyyy年MM月dd日");
            _week = DateTime.Now.ToString("dddd", new CultureInfo("zh-cn"));

            RegisterMessage();

            TimerTick();

            InitDelegateCommand();
        }

        /// <summary>
        /// 消息监听注册
        /// </summary>
        private void RegisterMessage()
        {
            _eventAggregator.GetEvent<RedSensorEvent>().Subscribe(delegate(DevStatus dev)
            {
                "MainWindowViewModel".WriteLog("Red Sensor收到消息:" + JsonConvert.SerializeObject(dev));

                //新协议不计算实际信号
                RedTransmitterBattery = Convert.ToInt32(dev.Cell);
                RedTransmitterSignal = 5;
                RedTransmitterState = true;
                RuntimeCache.RedSensorIsEnable = true;
            });

            _eventAggregator.GetEvent<BlueSensorEvent>().Subscribe(delegate(DevStatus dev)
            {
                "MainWindowViewModel".WriteLog("Blue Sensor收到消息:" + JsonConvert.SerializeObject(dev));

                //新协议不计算实际信号
                BlueTransmitterBattery = Convert.ToInt32(dev.Cell);
                BlueTransmitterSignal = 5;
                BlueTransmitterState = true;
                RuntimeCache.BlueSensorIsEnable = true;
                //因为红色先收到信号,所以只需要等到蓝色也收到信号即可
                StartButtonEnabled = true;
            });

            //加速度计
            _eventAggregator.GetEvent<StartCalculateEvent>().Subscribe(StartCalculateData);

            //水听器
            _eventAggregator.GetEvent<ShowCheckResponseEvent>().Subscribe(delegate
            {
                _dialogService.Show("CheckResponseDialog", null, delegate(IDialogResult result)
                {
                    if (result.Result == ButtonResult.Cancel)
                    {
                        ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "数据未校验,无法进行计算");
                        return;
                    }

                    if (result.Result == ButtonResult.Abort)
                    {
                        ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "数据校验被终止,无法进行计算");
                        return;
                    }

                    if (result.Result == ButtonResult.OK)
                    {
                        //水听器数据采集完毕,开始计算
                        StartCalculateData();
                    }
                });
            });

            //数字键盘
            _eventAggregator.GetEvent<NumericKeypadEvent>().Subscribe(delegate(NumberStruct number)
            {
                if (number.TextBoxName.Equals(_mainWindow.PipeDiameterTextBox.Name))
                {
                    PipeDiameter = number.NumberValue;
                }
                else if (number.TextBoxName.Equals(_mainWindow.PipeLengthTextBox.Name))
                {
                    PipeLength = number.NumberValue;
                }
                else if (number.TextBoxName.Equals(_mainWindow.LowFrequencyTextBox.Name))
                {
                    LowFrequency = number.NumberValue;
                }
                else if (number.TextBoxName.Equals(_mainWindow.HighFrequencyTextBox.Name))
                {
                    HighFrequency = number.NumberValue;
                }
            });
        }

        private void StartCalculateData()
        {
            DialogHub.Get.ShowLoadingDialog(_mainWindow, "数据计算中,请稍后...");
            //开始计算就不收集收据了且不能点击开始按钮
            StartButtonEnabled = false;
            using (var manager = new DataBaseManager())
            {
                var today = DateTime.Now.ToString("yyyyMMdd");
                var configModel = manager.Table<CorrelatorConfigModel>()
                    .Where(x => x.Date == today)
                    .OrderBy(x => x.Date)
                    .LastOrDefault() ?? new CorrelatorConfigModel
                    { Date = today, Pipe = 1, LocateTimes = 1, ListenTimes = 1 };

                //如果配置里面的日期相同,则取配置里面的Pipe作为index,如果配置里面的日期不相同,则默认index=1
                var pipeIndex = configModel.Date.Equals(today) ? configModel.Pipe : 1;
                _locateDataDir = DirectoryManager.GetLocateDataDir(pipeIndex);
                _locateTimes = configModel.LocateTimes;
                //插入新纪录
                configModel.Pipe++;
                configModel.LocateTimes++;
                manager.Insert(configModel);
            }

            //计算
            var dataModel = RuntimeCache.CorrelatorData;
            if (dataModel.LeftDeviceDataArray == null || dataModel.RightDeviceDataArray == null)
            {
                "MainWindowViewModel".WriteLog("数据未收集完整,请稍后...");
                return;
            }

            if (_backgroundWorker.IsBusy)
            {
                "MainWindowViewModel".WriteLog("正在计算中,请稍后...");
                return;
            }

            //设置噪声值
            CorrelatorData = dataModel;
            _backgroundWorker.RunWorkerAsync();
        }

        /// <summary>
        /// 各种定时器
        /// </summary>
        private void TimerTick()
        {
            //实时刷新显示最新一条指令
            _commandTimer.Tick += delegate { LastCommand = _commandService.GetLastCommand(); };
            _commandTimer.Start();

            _checkSerialPortTimer.Tick += delegate
            {
                var ports = SerialPort.GetPortNames();
                foreach (var portName in ports)
                {
                    if (portName != RuntimeCache.PortName || _serialPortService.Sp.IsOpen) continue;
                    _serialPortService.Sp.PortName = portName; //串口名称
                    _serialPortService.Sp.BaudRate = 230400; //波特率57600和230400
                    _serialPortService.Sp.DataBits = 8; //数据位
                    _serialPortService.Sp.StopBits = (StopBits)1; //停止位
                    _serialPortService.Sp.Open(); //打开串口
                    "MainWindowViewModel".WriteLog("打开串口");

                    ConnectColorBrush = "LimeGreen";
                    break;
                }

                if (_serialPortService.Sp.IsOpen)
                {
                    //实时显示信号电量
                    _serialPortService.ShowSignal();
                }
            };
            _checkSerialPortTimer.Start();

            //实时显示时间
            _timer.Tick += delegate
            {
                CurrentTime = $"{_today}" + $"\x20\x20\x20{_week}\x20\x20" + DateTime.Now.ToString("HH:mm:ss");
            };
            _timer.Start();

            //获取电池电量
            var sysPower = new SystemConfig.SystemPowerStatus();
            GetSystemPowerStatus(ref sysPower);
            ComputerBattery = sysPower.BatteryPercent == 255 ? 100 : sysPower.BatteryPercent;

            _batteryTimer.Tick += delegate
            {
                GetSystemPowerStatus(ref sysPower);
                ComputerBattery = sysPower.BatteryPercent == 255 ? 100 : sysPower.BatteryPercent;
            };
            _batteryTimer.Start();

            //计算时间Timer
            _runningTimer.Tick += delegate
            {
                _runningSeconds++;
                ElapseTime = _runningSeconds.ToString();
            };

            //自动截屏Timer
            _snapShotTimer.Tick += delegate
            {
                _snapShotTimer.Stop();
                if (!string.IsNullOrEmpty(_snapShotPath))
                {
                    _snapShotPath.SnapShot();
                    "MainWindowViewModel".WriteLog("截屏路径:" + _snapShotPath);
                }
            };
        }

        /// <summary>
        /// 事件指令
        /// </summary>
        private void InitDelegateCommand()
        {
            //界面加载完成
            WindowLoadedCommand = new DelegateCommand<MainWindow>(it =>
            {
                _mainWindow = it;
                "MainWindowViewModel".WriteLog("加载");
                it.AccelerationRadioButton.Checked += delegate
                {
                    RuntimeCache.IsHydrophone = false;
                    FrequencyInterval = "100 ~ 3000Hz";
                };

                it.HydrophonesRadioButton.Checked += delegate
                {
                    RuntimeCache.IsHydrophone = true;
                    FrequencyInterval = "10 ~ 300Hz";
                };
            });

            //退出应用
            CloseWindowCommand = new DelegateCommand(delegate
            {
                _dialogService.ShowDialog("AlertControlDialog", new DialogParameters
                    {
                        { "AlertType", AlertType.Question }, { "Title", "温馨提示" }, { "Message", "是否确定退出应用?" }
                    },
                    delegate(IDialogResult dialogResult)
                    {
                        if (dialogResult.Result == ButtonResult.Cancel)
                        {
                            return;
                        }

                        //删除小于50K的音频
                        foreach (var file in RuntimeCache.SmallAudioFiles)
                        {
                            File.Delete(file);
                        }

                        RuntimeCache.SmallAudioFiles.Clear();
                        _mainWindow.Close();
                    }
                );
            });

            //打开图片、音频菜单
            OpenFolderCommand = new DelegateCommand<Popup>(delegate(Popup popup) { popup.IsOpen = true; });

            //查看图片列表
            OpenImageFileCommand = new DelegateCommand<Popup>(delegate(Popup popup)
            {
                _dialogService.Show("PictureFileView", null, delegate { });
                popup.IsOpen = false;
            });

            //查看音频列表
            OpenAudioFileCommand = new DelegateCommand<Popup>(delegate(Popup popup)
            {
                _dialogService.Show("AudioFileView", null, delegate { });
                popup.IsOpen = false;
            });

            //打开听音
            OpenListenAudioCommand = new DelegateCommand(delegate
            {
                if (!_serialPortService.Sp.IsOpen)
                {
                    ShowAlertMessageDialog(AlertType.Error, "操作错误", "串口状态异常,无法打开听音功能");
                    return;
                }

                _dialogService.Show("SimplyAuditionDialog", null, delegate { });
            });

            //噪声探测
            DetectNoiseCommand = new DelegateCommand(delegate
            {
                if (!_serialPortService.Sp.IsOpen)
                {
                    ShowAlertMessageDialog(AlertType.Error, "操作错误", "串口状态异常,无法打开探测功能");
                    return;
                }

                _dialogService.Show("DetectNoiseDialog", null, delegate { });
            });

            //扩展
            ExtensionsCommand = new DelegateCommand<Popup>(delegate(Popup popup) { popup.IsOpen = true; });

            //采样率
            SoundSampleRateCommand = new DelegateCommand<Popup>(delegate(Popup popup)
            {
                _dialogService.Show("SoundSampleRateDialog", null, delegate { });
                popup.IsOpen = false;
            });

            //声速
            SoundSpeedCommand = new DelegateCommand<Popup>(delegate(Popup popup)
            {
                if (string.IsNullOrEmpty(_materialName))
                {
                    ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请选择管道材料");
                    return;
                }

                _dialogService.Show("SoundSpeedDialog", new DialogParameters
                    {
                        { "MaterialName", _materialName }
                    },
                    delegate { }
                );
                popup.IsOpen = false;
            });

            //导入水听器数据
            ImportDataCommand = new DelegateCommand<Popup>(delegate(Popup popup)
            {
                if (RuntimeCache.IsHydrophone)
                {
                    _dialogService.Show("ImportResponseDialog", null, delegate(IDialogResult result)
                    {
                        if (result.Result == ButtonResult.Cancel)
                        {
                            ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "用户取消导入数据");
                            return;
                        }

                        if (result.Result == ButtonResult.OK)
                        {
                            var configModel = result.Parameters.GetValue<ParamConfigModel>("ParamConfigModel");

                            MaterialName = configModel.PipeMaterial;
                            PipeDiameter = configModel.PipeDiameter;
                            PipeLength = configModel.PipeLength;
                            LowFrequency = configModel.MinFrequency;
                            HighFrequency = configModel.MaxFrequency;

                            //计算声速
                            var soundVelocity = _dataService.GetSoundVelocity(
                                _materialName, Convert.ToInt32(_pipeDiameter)
                            );
                            SoundSpeed = soundVelocity.ToString();
                        }

                        //导入数据完成,可以计算数据
                        StartCalculateData();
                    });
                }
                else
                {
                    ShowAlertMessageDialog(AlertType.Error, "操作错误", "仅支持水听器模式导入数据");
                }

                popup.IsOpen = false;
            });

            //设置
            HelpCenterCommand = new DelegateCommand<Popup>(delegate(Popup popup) { popup.IsOpen = true; });

            //查看日志
            ShowLogCommand = new DelegateCommand<Popup>(delegate(Popup popup)
            {
                try
                {
                    var file = new DirectoryInfo(DirectoryManager.LogDirPath)
                        .GetFiles("*.log", SearchOption.AllDirectories)
                        .OrderBy(f => f.LastWriteTime)
                        .Reverse()
                        .First();
                    if (file == null)
                    {
                        ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "暂时没有日志生成,请稍后再试");
                        return;
                    }

                    _dialogService.Show("ApplicationLogView", new DialogParameters
                        {
                            { "LogFullName", file.FullName }
                        },
                        delegate { }
                    );
                    popup.IsOpen = false;
                }
                catch (DirectoryNotFoundException e)
                {
                    ShowAlertMessageDialog(AlertType.Error, "温馨提示", e.Message);
                }
            });

            //查看软件、协议版本
            ShowApplicationInfoCommand = new DelegateCommand<Popup>(delegate(Popup popup)
            {
                _dialogService.Show("ApplicationInfoDialog", null, delegate { });
                popup.IsOpen = false;
            });

            //打开Matlab波形
            ShowWaveCommand = new DelegateCommand(delegate
            {
                if (RuntimeCache.CorrelatorData == null)
                {
                    ShowAlertMessageDialog(AlertType.Error, "温馨提示", "请先采集数据");
                    return;
                }

                _dialogService.Show("NoiseWaveView", null, delegate { });
            });

            //打开数字键盘
            OpenNumericKeypadCommand = new DelegateCommand(delegate
            {
                _dialogService.ShowDialog("NumericKeypadDialog", null, delegate { });
            });

            //管道材料选择
            PipeItemSelectedCommand = new DelegateCommand<ComboBox>(delegate(ComboBox box)
            {
                MaterialName = box.SelectedItem.ToString();
            });

            //将采集的数据转为音频并保存
            SaveAudioCommand = new DelegateCommand(delegate
            {
                if (_locateDataDir != null)
                {
                    var redValueSortResult = from pair in RuntimeCache.RedSensorOriginalResp
                        orderby pair.Key
                        select pair;
                    var redValueCollection = redValueSortResult.Select(valuePair => valuePair.Value).ToList();
                    var redTags = redValueCollection.Select(data => data.HandleLocalData()).ToList();
                    var redPcmArray = new List<byte[]>();
                    foreach (var tag in redTags)
                    {
                        var dataValue = tag.DataValue;
                        //PCM数据
                        var pcm = new byte[_soundSampleRate * 3]; //每个采样点2字节

                        for (var i = 0; i < _soundSampleRate; i++)
                        {
                            pcm[i * 3 + 2] = dataValue[i * 2 + 0];
                            pcm[i * 3 + 1] = dataValue[i * 2 + 1];
                            pcm[i * 3 + 0] = 0x00;
                        }

                        redPcmArray.Add(pcm);
                    }

                    _audioService.Write(_locateDataDir, "音频_红", redPcmArray);

                    var blueValueSortResult = from pair in RuntimeCache.BlueSensorOriginalResp
                        orderby pair.Key
                        select pair;
                    var blueValueCollection = blueValueSortResult.Select(valuePair => valuePair.Value).ToList();
                    var blueTags = blueValueCollection.Select(data => data.HandleLocalData()).ToList();
                    var bluePcmArray = new List<byte[]>();
                    foreach (var tag in blueTags)
                    {
                        var dataValue = tag.DataValue;
                        //PCM数据
                        var pcm = new byte[_soundSampleRate * 3]; //每个采样点2字节

                        for (var i = 0; i < _soundSampleRate; i++)
                        {
                            pcm[i * 3 + 2] = dataValue[i * 2 + 0];
                            pcm[i * 3 + 1] = dataValue[i * 2 + 1];
                            pcm[i * 3 + 0] = 0x00;
                        }

                        bluePcmArray.Add(pcm);
                    }

                    _audioService.Write(_locateDataDir, "音频_蓝", bluePcmArray);
                    Growl.Success("音频已保存");
                }
                else
                {
                    ShowAlertMessageDialog(AlertType.Error, "温馨提示", "请先采集数据");
                }
            });

            //复位
            ResetParamCommand = new DelegateCommand(delegate { ResetParam(true); });

            //截屏
            SnapShotCommand = new DelegateCommand(delegate
            {
                var filePath = $"{DirectoryManager.GetPictureDir()}\\快照_{DateTime.Now:yyyyMMddHHmmss}.png";
                filePath.SnapShot();
            });

            //开始采集数据
            StartCollectDataCommand = new DelegateCommand(delegate
            {
                if (!_serialPortService.Sp.IsOpen)
                {
                    ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "串口状态异常,无法操作");
                    return;
                }

                if (CheckParamLegitimacy())
                {
                    //每次计算之前都需要判断是否已经完成之前的计算,然后清空上一次的计算数据
                    ResetParam(false);

                    //开始数据采集
                    if (RuntimeCache.IsHydrophone)
                    {
                        RuntimeCache.WorkMode = 2;
                        _commandService.SendHydrophoneWakeUpCmd(_serialPortService.Sp);
                    }
                    else
                    {
                        RuntimeCache.WorkMode = 1;
                        _commandService.SendCorrelatorWakeUpCmd(_serialPortService.Sp);
                    }

                    SoundSampleRate = _dataService.GetSampleRateByWorkMode(RuntimeCache.WorkMode);

                    RuntimeCache.IsDetectNoise = false;

                    //记录计算时间
                    _runningTimer.Start();
                }
            });
        }

        /// <summary>
        /// 重置参数
        /// </summary>
        /// <param name="isResetParam"></param>
        private void ResetParam(bool isResetParam)
        {
            if (isResetParam)
            {
                PipeDiameter = string.Empty;
                PipeLength = string.Empty;
                LowFrequency = string.Empty;

                HighFrequency = string.Empty;
                SoundSpeed = "0";

                //复位之后可以再次开始
                StartButtonEnabled = true;
                //清空上次的缓存
                RuntimeCache.CorrelatorData = null;
            }

            InterferenceFrequency = "无";
            Snr = "无";
            FilterValue = " ~ Hz";
            RedTransmitterDistance = 0;
            ElapseTime = "0";
            BlueTransmitterDistance = 0;
            CorrelatorData = new CorrelatorDataModel();
            ClearCache();

            _runningSeconds = 0;
            _runningTimer.Stop();

            _eventAggregator.GetEvent<ClearOscillogramEvent>().Publish();
        }

        /// <summary>
        /// 清空上次计算的缓存
        /// </summary>
        private void ClearCache()
        {
            RuntimeCache.RedSensorOriginalResp.Clear();
            RuntimeCache.BlueSensorOriginalResp.Clear();
            RuntimeCache.RedSensorResponseTags.Clear();
            RuntimeCache.BlueSensorResponseTags.Clear();
        }

        /// <summary>
        /// 参数检查
        /// </summary>
        /// <returns></returns>
        private bool CheckParamLegitimacy()
        {
            if (string.IsNullOrEmpty(_materialName))
            {
                ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请选择管道材料");
                return false;
            }

            if (string.IsNullOrEmpty(_pipeDiameter))
            {
                ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请输入管道直径");
                return false;
            }

            if (string.IsNullOrEmpty(_pipeLength))
            {
                ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请输入管道长度");
                return false;
            }

            if (string.IsNullOrEmpty(_lowFrequency) || string.IsNullOrEmpty(_highFrequency))
            {
                ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请输入完整的计算频段");
                return false;
            }

            var low = Convert.ToInt32(_lowFrequency);
            var high = Convert.ToInt32(_highFrequency);

            if (RuntimeCache.IsHydrophone)
            {
                if (low < 10 || low > 300 || high < 10 || high > 300 || low >= high)
                {
                    ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "频段范围10 ~ 300Hz,请重新输入");
                    return false;
                }

                //缓存计算参数
                _paramConfig = new ParamConfigModel
                {
                    PipeMaterial = _materialName,
                    PipeDiameter = _pipeDiameter,
                    PipeLength = _pipeLength,
                    MinFrequency = _lowFrequency,
                    MaxFrequency = _highFrequency
                };
            }
            else
            {
                if (low < 100 || low > 3000 || high < 100 || high > 3000 || low >= high)
                {
                    ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "频段范围100 ~ 3000Hz,请重新输入");
                    return false;
                }
            }

            //声速
            var soundVelocity = _dataService.GetSoundVelocity(_materialName, Convert.ToInt32(_pipeDiameter));
            SoundSpeed = soundVelocity.ToString();
            return true;
        }

        /// <summary>
        /// 后台计算
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Worker_OnDoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                "MainWindowViewModel".WriteLog("开始计算");
                var array = LazyCorrelator.Value.locating(
                    11,
                    (MWNumericArray)_correlatorData.LeftDeviceDataArray,
                    (MWNumericArray)_correlatorData.RightDeviceDataArray,
                    _soundSampleRate,
                    int.Parse(_pipeLength), int.Parse(_soundSpeed),
                    0, 0,
                    0, 0,
                    _materialName,
                    int.Parse(_pipeDiameter), int.Parse(_pipeDiameter),
                    1, -1,
                    -1, -1,
                    int.Parse(_lowFrequency), int.Parse(_highFrequency)
                );
                e.Result = array;
            }
            catch (Exception)
            {
                _runningTimer.Stop();
                DialogHub.Get.DismissLoadingDialog();

                Application.Current.Dispatcher.Invoke(delegate
                {
                    _dialogService.ShowDialog("AlertControlDialog", new DialogParameters
                        {
                            { "AlertType", AlertType.Question }, { "Title", "温馨提示" }, { "Message", "计算出现错误,请重新计算" }
                        },
                        delegate(IDialogResult dialogResult)
                        {
                            if (dialogResult.Result == ButtonResult.Cancel)
                            {
                                return;
                            }

                            StartButtonEnabled = true;
                            ClearCache();
                        }
                    );
                });
            }
        }

        private void Worker_OnProgressChanged(object sender, ProgressChangedEventArgs e)
        {
        }

        private void Worker_OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            "MainWindowViewModel".WriteLog("计算结束");
            DialogHub.Get.DismissLoadingDialog();

            var array = (MWArray[])e.Result;
            //数据绑定
            var snr = Convert.ToDouble(array[0].ToString()); //信噪比
            Snr = snr.ToString("0.0") + ":1";
            RedTransmitterDistance = Convert.ToDouble(array[1].ToString()); //距离A
            BlueTransmitterDistance = Convert.ToDouble(array[2].ToString()); //距离B

            var maxFreLowOut = Convert.ToInt32(array[6].ToString()); //低频
            var maxFreHighOut = Convert.ToInt32(array[7].ToString()); //高频

            FilterValue = maxFreLowOut + " ~ " + maxFreHighOut + "Hz";

            _eventAggregator.GetEvent<RenderOscillogramEvent>().Publish(array);

            var time = DateTime.Now.ToString("HHmmss");
            if (RuntimeCache.IsHydrophone)
            {
                //保存参数
                var paramConfigFile = $"{_locateDataDir}\\参数配置.{_locateTimes}.{time}.json";
                File.AppendAllText(paramConfigFile, JsonConvert.SerializeObject(_paramConfig));
            }

            //保存数据
            var fileName = $"{_locateDataDir}\\测试数据.{_locateTimes}.{time}.txt";
            fileName.SaveLocateData(_correlatorData);
            "MainWindowViewModel".WriteLog("定位数据路径:" + fileName);

            //保存了数据之后3s再截图
            _snapShotPath = $"{_locateDataDir}\\快照.{_locateTimes}.{time}.png";
            _snapShotTimer.Start();

            _runningTimer.Stop();
            StartButtonEnabled = true;
        }

        /// <summary>
        /// 显示普通提示对话框
        /// </summary>
        private void ShowAlertMessageDialog(AlertType type, string title, string message)
        {
            _dialogService.ShowDialog("AlertMessageDialog", new DialogParameters
                {
                    { "AlertType", type }, { "Title", title }, { "Message", message }
                },
                delegate { }
            );
        }
    }
}