using Aurora; using Aurora.Api; using Aurora.Api.Manager; using Aurora.View; using Hermes; using LiveCharts; using LiveCharts.Defaults; using LiveCharts.Wpf; using Microsoft.Win32; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data.Common; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using static AuroraLaser.Laser; namespace AuroraLaser.Views { public class PowerProfileViewModel : NotifyPropertyChangedBase { Logger Log = new Logger("Laser"); private ObservableCollection _ProfileList; public ObservableCollection ProfileList { get => _ProfileList; set => SetProperty(ref _ProfileList, value); } private int _ProfileListSelectedIndex; public int ProfileListSelectedIndex { get => _ProfileListSelectedIndex; set => SetProperty(ref _ProfileListSelectedIndex, value); } private string _ProfileListSelectedItem; public string ProfileListSelectedItem { get => _ProfileListSelectedItem; set => SetProperty(ref _ProfileListSelectedItem, value); } private ObservableCollection _ListboxProfileList; public ObservableCollection ListboxProfileList { get => _ListboxProfileList; set => SetProperty(ref _ListboxProfileList, value); } private int _ListboxProfileListSelectedIndex; public int ListboxProfileListSelectedIndex { get => _ListboxProfileListSelectedIndex; set => SetProperty(ref _ListboxProfileListSelectedIndex, value); } private string _ListboxProfileListSelectedItem; public string ListboxProfileListSelectedItem { get => _ListboxProfileListSelectedItem; set => SetProperty(ref _ListboxProfileListSelectedItem, value); } private double _RecordPeriod; public double RecordPeriod { get => _RecordPeriod; set => SetProperty(ref _RecordPeriod, value); } private double _Threshold; public double Threshold { get => _Threshold; set => SetProperty(ref _Threshold, value); } private double _StabilizedValue; public double StabilizedValue { get => _StabilizedValue; set => SetProperty(ref _StabilizedValue, value); } private SeriesCollection _ChartPowerProfile; public SeriesCollection ChartPowerProfile { get => _ChartPowerProfile; set => SetProperty(ref _ChartPowerProfile, value); } private SeriesCollection _ChartRecord; public SeriesCollection ChartRecord { get => _ChartRecord; set => SetProperty(ref _ChartRecord, value); } private ObservableCollection _RegionIDList; public ObservableCollection RegionIDList { get => _RegionIDList; set => SetProperty(ref _RegionIDList, value); } private int _RegionIDListSelectedIndex; public int RegionIDListSelectedIndex { get => _RegionIDListSelectedIndex; set => SetProperty(ref _RegionIDListSelectedIndex, value); } private string _RegionIDListSelectedItem; public string RegionIDListSelectedItem { get => _RegionIDListSelectedItem; set => SetProperty(ref _RegionIDListSelectedItem, value); } List> groupList = new List>(); List uploadedRecord = new List(); public ICommand CMD_SaveProfiles { get; } public ICommand CMD_LoadProfiles { get; } public ICommand CMD_AddProfiles { get; } public ICommand CMD_CopyProfiles { get; } public ICommand CMD_DeleteProfiles { get; } public ICommand CMD_LoadRecordProfiles { get; } public ICommand CMD_UploadRecord { get; } public ICommand CMD_AddParameter { get; } public ICommand CMD_CopyParameter { get; } public ICommand CMD_DeleteParameter { get; } private PowerProfileParam _PowerProfileParamSelectedObject; public PowerProfileParam PowerProfileParamSelectedObject { get => _PowerProfileParamSelectedObject; set => SetProperty(ref _PowerProfileParamSelectedObject, value); } private readonly IDeviceManager _deviceManger; private readonly Laser _Laser; public PowerProfileViewModel(IAuroraEnvironment aurora, string deviceId) { _deviceManger = aurora.DeviceManager; _Laser = _deviceManger[deviceId] as Laser; CMD_SaveProfiles = new DelegateCommand(SaveProfiles); CMD_LoadProfiles = new DelegateCommand(LoadProfiles); CMD_AddProfiles = new DelegateCommand(AddProfiles); CMD_CopyProfiles = new DelegateCommand(CopyProfiles); CMD_DeleteProfiles = new DelegateCommand(DeleteProfiles); CMD_LoadRecordProfiles = new DelegateCommand(LoadRecordProfiles); CMD_UploadRecord = new DelegateCommand(UploadRecord); CMD_AddParameter = new DelegateCommand(AddParameter); CMD_CopyParameter = new DelegateCommand(CopyParameter); CMD_DeleteParameter = new DelegateCommand(DeleteParameter); RecordPeriod = 0.02; Threshold = 0.05; StabilizedValue = 0.1; } public void UpdateChartPowerProfile() { TopRootObject root = _Laser.LoadPowerProfile(); ChartPowerProfile = new SeriesCollection(); double totaltime = 0; for (int i = 0; i < root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles.Count; i++) { totaltime += root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0].Time; } double timeStart = 0; double timeEnd = 0; for (int i = 0; i < root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles.Count; i++) { timeStart = timeEnd; timeEnd += root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0].Time / totaltime; double power1 = root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0].StartPowerPercent; double power2 = root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0].EndPowerPercent; var chartValues = new ChartValues { new ObservablePoint(timeStart, power1), new ObservablePoint(timeEnd, power2) }; ChartPowerProfile.Add(new LineSeries { Title = $"Line {ChartPowerProfile.Count + 1}", Values = chartValues } ); } //ChartProfile에 Record정보까지 같이 포함해야함 #region Chartprofile에 record정보 그리는 부분 Update 필요 //ChartRecord = new SeriesCollection(); //timeStart = 0; //timeEnd = 0; //for (int i = 0; i < uploadedRecord.Count - 1; i++) //{ // if (i * RecordPeriod < totaltime) // { // timeStart = timeEnd; // timeEnd = i * RecordPeriod; // double record1 = uploadedRecord[i] / StabilizedValue / 2; // double record2 = uploadedRecord[i + 1] / StabilizedValue / 2; // var chartValues = new ChartValues // { // new ObservablePoint(timeStart / totaltime, record1), // new ObservablePoint(timeEnd / totaltime, record2) // }; // ChartRecord.Add(new LineSeries // { // Title = $"Line {uploadedRecord.Count + 1}", // Values = chartValues // } // ); // } // else // { // break; // } //} #endregion } #region PropertyGrid Event를 위한 오버로드 함수 public void UpdateChartPowerProfile(object newSelectedObject) { TopRootObject root = _Laser.LoadPowerProfile(); root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[ListboxProfileListSelectedIndex].PowerProfileParams[0].Copy(PowerProfileParamSelectedObject); var outputjson = JsonConvert.SerializeObject(root, Formatting.Indented); File.WriteAllText("PowerProfileTest.json", outputjson); ChartPowerProfile = new SeriesCollection(); double totaltime = 0; for (int i = 0; i < root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles.Count; i++) { totaltime += root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0].Time; } double timeStart = 0; double timeEnd = 0; for (int i = 0; i < root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles.Count; i++) { timeStart = timeEnd; timeEnd += root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0].Time / totaltime; double power1 = root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0].StartPowerPercent; double power2 = root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[i].PowerProfileParams[0].EndPowerPercent; var chartValues = new ChartValues { new ObservablePoint(timeStart, power1), new ObservablePoint(timeEnd, power2) }; ChartPowerProfile.Add(new LineSeries { Title = $"Line {ChartPowerProfile.Count + 1}", Values = chartValues } ); } } #endregion public void UpdateComboBoxPowerProfile() { TopRootObject root = _Laser.LoadPowerProfile(); try { ProfileList = new ObservableCollection(); for (int i = 1; i <= root.PowerProfilesLists.Count; i++) { ProfileList.Add($"Profile {i}"); } ProfileListSelectedItem = ProfileList[root.PowerProfilesLists.Count - 1]; } catch(Exception ex) { Log.E(string.Format($"{ex.Message}" )); } } //Listbox와 propertyGrid는 이벤트로 받아옴 public void UpdateListboxPowerProfile(int comboboxSelectedIndex) { TopRootObject root = _Laser.LoadPowerProfile(); try { ListboxProfileList = new ObservableCollection(); for (int i = 1; i <= root.PowerProfilesLists[comboboxSelectedIndex].PowerProfiles.Count; i++) { ListboxProfileList.Add($"Parameter {i}"); } ListboxProfileListSelectedItem = ListboxProfileList[root.PowerProfilesLists[comboboxSelectedIndex].PowerProfiles.Count - 1]; UpdatePropertyGridPowerProfile(ListboxProfileListSelectedIndex); UpdateChartPowerProfile(); } catch (Exception ex) { Log.E(string.Format($"{ex.Message}")); } } public void UpdatePropertyGridPowerProfile(int listboxSelectedIndex) { TopRootObject root = _Laser.LoadPowerProfile(); try { PowerProfileParamSelectedObject = root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[listboxSelectedIndex].PowerProfileParams[0]; } catch (Exception ex) { Log.E(string.Format($"{ex.Message}")); } } private void SaveProfiles(object obj) { // Save Button을 다른이름으로 파일 저장해서 해당 파일을 Sequence에서 사용하고 Load할때또 해당 경로 파일 불러오는걸로구성할까.. // 현재 편집하는 정보는 메모리가아닌 파일을 수정하는 형태이니.. 수정 파일을 메모리처럼 관리를하고.. //현재 propertyGrid 값 변경 시 SaveProfiles 버튼눌러야 저장되는 형태로 구성 //TopRootObject root = _Laser.LoadPowerProfile(); //root.PowerProfilesLists[ProfileListSelectedIndex].PowerProfiles[ListboxProfileListSelectedIndex].PowerProfileParams[0].Copy(PowerProfileParamSelectedObject); //var outputjson = JsonConvert.SerializeObject(root, Formatting.Indented); //File.WriteAllText("PowerProfileTest.json", outputjson); //UpdateChartPowerProfile(); } private void LoadProfiles(object obj) { UpdateComboBoxPowerProfile(); ProfileListSelectedItem = ProfileList[0]; } private void AddProfiles(object obj) { _Laser.AddPowerProfile(); UpdateComboBoxPowerProfile(); } private void CopyProfiles(object obj) { _Laser.CopyPowerProfile(ProfileListSelectedIndex); UpdateComboBoxPowerProfile(); } private void DeleteProfiles(object obj) { _Laser.DeleteProfiles(ProfileListSelectedIndex); UpdateComboBoxPowerProfile(); } private void LoadRecordProfiles(object obj) { try { OpenFileDialog dlg = new OpenFileDialog(); dlg.DefaultExt = "csv"; dlg.Filter = "csv 파일 (*.csv)|*.csv"; dlg.Title = "csv 파일 열기"; if (dlg.ShowDialog() == true) { StreamReader reader = new StreamReader(dlg.FileName); reader = new StreamReader(dlg.FileName); List values = new List(); while (!reader.EndOfStream) { string rows = reader.ReadLine(); double value = Convert.ToDouble(rows); values.Add(value); } //gorupList가 RegionIDList... 코드 재활용.. List group = new List(); groupList = new List>(); bool isFirstValue = false; RegionIDList = new ObservableCollection(); //CSV 파일에서 col을 파싱하여 0.05이하 일때까지 1개 group으로 구성함.. 마지막 0.05이하 값 이후 값은 그룹으로 묶지않고 날려버림.. int id = 0; for (int i = 0; i < values.Count; i++) { double temp = values[i]; //Legacy code에 0.05를 아마 Threshold를 사용해서 받지않을까해서 하드코딩을 변경해둠 if (temp > Threshold) { if (!isFirstValue) { isFirstValue = true; group = new List(); } group.Add(temp); } if (temp < Threshold && isFirstValue) { isFirstValue = false; groupList.Add(group); RegionIDList.Add($"Group {id}"); id++; } } RegionIDListSelectedItem = RegionIDList[0]; } } catch (Exception ex) { Log.E($"{ex.Message}"); } } public void UpdateChartRecord(int id) { try { ChartRecord = new SeriesCollection(); List group = groupList[id]; double StartX = 0; double EndX = 0; //그래프 Y좌표가 Legacy코드는 다른게 구성되어있는데 필요시 변경하면됨.. for (int i = 0; i < group.Count - 1; i++) { StartX = EndX; EndX = (i + 1) / (double)group.Count; double record1 = (StabilizedValue * 2 - group[i]) / StabilizedValue / 2; double record2 = (StabilizedValue * 2 - group[i + 1]) / StabilizedValue / 2; var chartValues = new ChartValues { new ObservablePoint(StartX, record1), new ObservablePoint(EndX, record2) }; ChartRecord.Add(new LineSeries { Title = $"Line {ChartRecord.Count + 1}", Values = chartValues } ); } } catch (Exception ex) { Log.E($"{ex.Message}"); } } private void UploadRecord(object obj) { uploadedRecord = groupList[RegionIDListSelectedIndex]; //Upload Recod의 목적이 ChartPowerProfile에 동일한 스케일로 보여준다는건가..? //목적이 확실해졌을때 다시 구현해보자 //UpdateChartPowerProfile(); } private void AddParameter(object obj) { _Laser.AddPowerProfileParam(ProfileListSelectedIndex); //Parmeter는 Listbox만 Update UpdateListboxPowerProfile(ProfileListSelectedIndex); } private void CopyParameter(object obj) { _Laser.CopyProfileParam(ProfileListSelectedIndex, ListboxProfileListSelectedIndex); UpdateListboxPowerProfile(ProfileListSelectedIndex); } private void DeleteParameter(object obj) { _Laser.DeleteProfileParam(ProfileListSelectedIndex, ListboxProfileListSelectedIndex); UpdateListboxPowerProfile(ProfileListSelectedIndex); } } }