ShakerControlViewModel.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. using HandyControl.Interactivity;
  2. using HandyControl.Interactivity.Commands;
  3. using OxyPlot;
  4. using Shaker.Model;
  5. using Shaker.ViewModel;
  6. using ShakerManger.Data;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Collections.ObjectModel;
  10. using System.ComponentModel.DataAnnotations;
  11. using System.Diagnostics.CodeAnalysis;
  12. using System.IO;
  13. using System.Linq;
  14. using System.Security.AccessControl;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. using System.Windows;
  18. using System.Windows.Controls;
  19. using System.Windows.Input;
  20. using System.Windows.Media;
  21. using System.Windows.Media.Animation;
  22. using System.Windows.Media.Media3D;
  23. using System.Windows.Threading;
  24. using XamlAnimatedGif;
  25. namespace ShakerManger.ViewModel
  26. {
  27. internal class ShakerControlViewModel:Shaker.ViewModel.DisplayViewModel<Shaker.Model.ShakerControlModel>
  28. {
  29. private object locker = new object();
  30. public string ClientID { get => Model.ClientID; set => UpdateProperty(ref Model.ClientID, value); }
  31. public int MaxItemCount => 1000;
  32. private ObservableCollection<DataMangerItemViewModel> Items { get; } = new ObservableCollection<DataMangerItemViewModel>();
  33. private List<OxyPlot.Series.LineSeries> _LineSeries = new List<OxyPlot.Series.LineSeries>();
  34. public string[] PropertiyNames { get; }= new string[]
  35. {
  36. nameof(DataMangerItemViewModel.OperatingStatus),
  37. nameof(DataMangerItemViewModel.OutputCurrent),
  38. nameof(DataMangerItemViewModel.OutputVoltage),
  39. nameof(DataMangerItemViewModel.ExcitationCurrent),
  40. nameof(DataMangerItemViewModel.ExcitationVoltage),
  41. nameof(DataMangerItemViewModel.ThreePhaseVoltage),
  42. nameof(DataMangerItemViewModel.AbutmentTemperature0),
  43. nameof(DataMangerItemViewModel.AbutmentTemperature1),
  44. nameof(DataMangerItemViewModel.DCVoltage1),
  45. nameof(DataMangerItemViewModel.DCVoltage2),
  46. nameof(DataMangerItemViewModel.DCVoltage3),
  47. nameof(DataMangerItemViewModel.DCVoltage4),
  48. nameof(DataMangerItemViewModel.ExternalCirculatoryPressure),
  49. nameof(DataMangerItemViewModel.MovingCoilPressure),
  50. nameof(DataMangerItemViewModel.ExcitationPressure),
  51. nameof(DataMangerItemViewModel.OilPumpPressure),
  52. nameof(DataMangerItemViewModel.DynamicFlow),
  53. nameof(DataMangerItemViewModel.ExcitationFlow),
  54. nameof(DataMangerItemViewModel.MovingCoilWaterTemperature),
  55. nameof(DataMangerItemViewModel.ExcitationWaterTemperature),
  56. nameof(DataMangerItemViewModel.OilPumpTemperature),
  57. nameof(DataMangerItemViewModel.CoolingWaterStatus),
  58. nameof(DataMangerItemViewModel.Gain),
  59. };
  60. public bool ModelVisibily { get => modelVisibily; set =>UpdateProperty(ref modelVisibily,value); }
  61. public ICommand MenuShowCommand => new DelegateCommand<ExCommandParameter>(MenuShow);
  62. private void MenuShow(ExCommandParameter parameter)
  63. {
  64. if(parameter.EventArgs is MouseButtonEventArgs args)
  65. {
  66. if (args.ChangedButton == MouseButton.Right && (args.OriginalSource == null ? true :!(args.OriginalSource.GetType().FullName.Contains("Helix"))))
  67. {
  68. MenuIsOpen = true;
  69. }
  70. }
  71. }
  72. public ICommand DisConnectCommand=> new DelegateCommand(DisConnect);
  73. private void DisConnect()
  74. {
  75. PromptViewModel.Default.Init();
  76. PromptViewModel.Default.IconType = IconType.Ask;
  77. PromptViewModel.Default.Message = "是否断开功放连接?";
  78. PromptViewModel.Default.YesAction = async ()=>
  79. {
  80. var result = await BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SysControl, Shaker.Model.Result>(new SysControl()
  81. {
  82. Cmd = SysCmd.DisConnect,
  83. }, Properties);
  84. if (result == null ||!result.Success)
  85. {
  86. PromptViewModel.Default.Init();
  87. PromptViewModel.Default.IconType = IconType.Error;
  88. PromptViewModel.Default.Message = result == null? "通信超时" : result.Message;
  89. PromptViewModel.Default.NoVisibility = Visibility.Collapsed;
  90. PromptViewModel.Default.IsOpen = true;
  91. }
  92. };
  93. PromptViewModel.Default.IsOpen = true;
  94. }
  95. public ICommand ConnectCommand => new DelegateCommand(Connect);
  96. private async void Connect()
  97. {
  98. var result = await BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SysControl, Shaker.Model.Result>(new SysControl()
  99. {
  100. Cmd = SysCmd.Connect,
  101. },Properties);
  102. if(result == null || !result.Success)
  103. {
  104. PromptViewModel.Default.Init();
  105. PromptViewModel.Default.IconType = IconType.Error;
  106. PromptViewModel.Default.Message = result == null?"通信超时": result.Message;
  107. PromptViewModel.Default.NoVisibility = Visibility.Collapsed;
  108. PromptViewModel.Default.IsOpen= true;
  109. }
  110. }
  111. public bool IsOnline { get => isOnline; set =>UpdateProperty(ref isOnline, value); }
  112. public DataMangerItemViewModel CurrentData { get => currentData; set =>UpdateProperty(ref currentData, value); }
  113. public Boolean SetPlotConfigIsOpen
  114. {
  115. get => setPlotConfigIsOpen;
  116. set
  117. {
  118. UpdateProperty(ref setPlotConfigIsOpen, value);
  119. if(value)
  120. {
  121. foreach(var item in PlotConfig)
  122. {
  123. item.Init();
  124. }
  125. }
  126. }
  127. }
  128. public string ActiveMQClintID
  129. {
  130. get => activeMQClintID;
  131. set
  132. {
  133. if (activeMQClintID == value) return;
  134. if(string.IsNullOrEmpty(value) || string.IsNullOrEmpty(activeMQClintID))
  135. {
  136. activeMQClintID = value;
  137. }
  138. }
  139. }
  140. public bool MenuIsOpen { get => menuIsOpen; set =>UpdateProperty(ref menuIsOpen , value); }
  141. private Data.ShakerViewType lastviewType = ShakerViewType.ShakerControl;
  142. public Data.ShakerViewType ShakerView
  143. {
  144. get => shakerView;
  145. set
  146. {
  147. if (shakerView == value) return;
  148. MenuIsOpen = false;
  149. UpdateProperty(ref shakerView, value);
  150. }
  151. }
  152. public bool IsDeviceControl { get => isDeviceControl; set =>UpdateProperty(ref isDeviceControl , value); }
  153. public bool IsConnected
  154. {
  155. get => isConnected;
  156. set
  157. {
  158. if (isConnected == value) return;
  159. UpdateProperty(ref isConnected, value);
  160. if (value)
  161. {
  162. ShakerView = lastviewType;
  163. }
  164. else
  165. {
  166. lastviewType = ShakerView;
  167. ShakerView = ShakerViewType.None;
  168. }
  169. }
  170. }
  171. public bool StartupCompleted
  172. {
  173. get => startupCompleted;
  174. set
  175. {
  176. if (startupCompleted == value) return;
  177. UpdateProperty(ref startupCompleted, value);
  178. OnPropertyChanged(nameof(GainSwitchEnabled));
  179. if (value)
  180. {
  181. animator?.Play();
  182. }
  183. else
  184. {
  185. animator.Pause();
  186. }
  187. }
  188. }
  189. public bool CacheFramesInMemory { get => cacheFramesInMemory; set => UpdateProperty(ref cacheFramesInMemory, value); }
  190. public bool AutoStart { get => autoStart; set => UpdateProperty(ref autoStart, value); }
  191. [AllowNull]
  192. private Animator animator;
  193. [AllowNull]
  194. private Image image;
  195. public Image Image
  196. {
  197. get => image;
  198. set
  199. {
  200. image = value;
  201. if (animator == null && value != null) animator = AnimationBehavior.GetAnimator(value);
  202. }
  203. }
  204. public RepeatBehavior RepeatBehavior { get => repeatBehavior; set =>UpdateProperty(ref repeatBehavior, value); }
  205. public string GifPath { get => gifPath; set => UpdateProperty(ref gifPath, value); }
  206. private bool isVisible = false;
  207. private static string ModelDirectory=System.AppDomain.CurrentDomain.BaseDirectory + $"Model\\";
  208. public bool IsVisible { get => isVisible; set => UpdateProperty(ref isVisible, value); }
  209. public string[] AnalogNames { get; } = new string[Shaker.Model.DataMangerItemModel.ANALOG_DATA_LENGTH];
  210. public string[] Units { get; } = new string[Shaker.Model.DataMangerItemModel.ANALOG_DATA_LENGTH];
  211. private Dictionary<string, string> Properties { get; init; } = new Dictionary<string, string>();
  212. public ObservableCollection<PlotConfigViewModel> PlotConfig { get; } = new ObservableCollection<PlotConfigViewModel>();
  213. public int Index { get; }
  214. public ShakerControlViewModel(Shaker.Model.ShakerControlModel model,int index)
  215. {
  216. Index = index;
  217. Model = model;
  218. GifPath = System.AppDomain.CurrentDomain.BaseDirectory + $"\\GIF\\Shaker{index}.gif";
  219. ModelVisibily = File.Exists(GifPath);
  220. Values.Add(new PLCAnlogViewModel(model.ExcitationVoltage));
  221. Values.Add(new PLCAnlogViewModel(model.ExcitationCurrent)
  222. {
  223. IsVisily = false,
  224. });
  225. Values.Add(new PLCAnlogViewModel(model.ThreePhaseVoltage)
  226. {
  227. IsVisily = false,
  228. });
  229. Values.Add(new PLCAnlogViewModel(model.AbutmentTemperature0));
  230. Values.Add(new PLCAnlogViewModel(model.AbutmentTemperature1));
  231. Values.Add(new PLCAnlogViewModel(model.DCVoltage1));
  232. Values.Add(new PLCAnlogViewModel(model.DCVoltage2));
  233. Values.Add(new PLCAnlogViewModel(model.DCVoltage3));
  234. Values.Add(new PLCAnlogViewModel(model.DCVoltage4));
  235. CoolingWaterValues.Add(new PLCAnlogViewModel(model.ExternalCirculatoryPressure));
  236. CoolingWaterValues.Add(new PLCAnlogViewModel(model.MovingCoilPressure));
  237. CoolingWaterValues.Add(new PLCAnlogViewModel(model.ExcitationPressure));
  238. CoolingWaterValues.Add(new PLCAnlogViewModel(model.OilPumpPressure));
  239. CoolingWaterValues.Add(new PLCAnlogViewModel(model.DynamicFlow));
  240. CoolingWaterValues.Add(new PLCAnlogViewModel(model.ExcitationFlow));
  241. CoolingWaterValues.Add(new PLCAnlogViewModel(model.MovingCoilWaterTemperature));
  242. CoolingWaterValues.Add(new PLCAnlogViewModel(model.ExcitationWaterTemperature));
  243. CoolingWaterValues.Add(new PLCAnlogViewModel(model.OilPumpTemperature));
  244. CurrentData = new DataMangerItemViewModel(new DataMangerItemModel());
  245. CurrentData.PropertyChanged += (sender, args) =>
  246. {
  247. if(args.PropertyName == nameof(DataMangerItemViewModel.OperatingStatus))
  248. {
  249. OnPropertyChanged(nameof(GainEnabled));
  250. OnPropertyChanged(nameof(GainSwitchEnabled));
  251. OnPropertyChanged(nameof(StartEnabled));
  252. OnPropertyChanged(nameof(StopEnabled));
  253. OnPropertyChanged(nameof(ResetEnabled));
  254. }
  255. };
  256. Properties[Shaker.Model.GlobalVariable.ShakerIDKey] = model.Id;
  257. AnalogNames[0] = Model.OperatingStatus.Name;
  258. AnalogNames[1] = Model.OutputCurrent.Name;
  259. AnalogNames[2] = Model.OutputVoltage.Name;
  260. AnalogNames[3] = Model.ExcitationCurrent.Name;
  261. AnalogNames[4] = Model.ExcitationVoltage.Name;
  262. AnalogNames[5] = Model.ThreePhaseVoltage.Name;
  263. Units[0] = Model.OperatingStatus.Unit;
  264. Units[1] = Model.OutputCurrent.Unit;
  265. Units[2] = Model.OutputVoltage.Unit;
  266. Units[3] = Model.ExcitationCurrent.Unit;
  267. Units[4] = Model.ExcitationVoltage.Unit;
  268. Units[5] = Model.ThreePhaseVoltage.Unit;
  269. if (!string.IsNullOrEmpty(model.AbutmentTemperature0.Name))
  270. {
  271. AnalogNames[6] = Model.AbutmentTemperature0.Name;
  272. Units[6] = Model.AbutmentTemperature0.Unit;
  273. }
  274. if (!string.IsNullOrEmpty(model.AbutmentTemperature1.Name))
  275. {
  276. AnalogNames[7] = Model.AbutmentTemperature1.Name;
  277. Units[7] = Model.AbutmentTemperature1.Unit;
  278. }
  279. if (!string.IsNullOrEmpty(model.DCVoltage1.Name))
  280. {
  281. AnalogNames[8] = Model.DCVoltage1.Name;
  282. Units[8] = Model.DCVoltage1.Unit;
  283. }
  284. if (!string.IsNullOrEmpty(model.DCVoltage2.Name))
  285. {
  286. AnalogNames[9] = Model.DCVoltage2.Name;
  287. Units[9] = Model.DCVoltage2.Unit;
  288. }
  289. if (!string.IsNullOrEmpty(model.DCVoltage3.Name))
  290. {
  291. AnalogNames[10] = Model.DCVoltage3.Name;
  292. Units[10] = Model.DCVoltage3.Unit;
  293. }
  294. if (!string.IsNullOrEmpty(model.DCVoltage4.Name))
  295. {
  296. AnalogNames[11] = Model.DCVoltage4.Name;
  297. Units[11] = Model.DCVoltage4.Unit;
  298. }
  299. AnalogNames[12] = Model.ExternalCirculatoryPressure.Name;
  300. Units[12] = Model.ExternalCirculatoryPressure.Unit;
  301. AnalogNames[13] = Model.MovingCoilPressure.Name;
  302. Units[13] = Model.MovingCoilPressure.Unit;
  303. AnalogNames[14] = Model.ExcitationPressure.Name;
  304. Units[14] = Model.ExcitationPressure.Unit;
  305. AnalogNames[15] = Model.OilPumpPressure.Name;
  306. Units[15] = Model.OilPumpPressure.Unit;
  307. AnalogNames[16] = Model.DynamicFlow.Name;
  308. Units[16] = Model.DynamicFlow.Unit;
  309. AnalogNames[17] = Model.ExcitationFlow.Name;
  310. Units[17] = Model.ExcitationFlow.Unit;
  311. AnalogNames[18] = Model.MovingCoilWaterTemperature.Name;
  312. Units[18] = Model.MovingCoilWaterTemperature.Unit;
  313. AnalogNames[19] = Model.ExcitationWaterTemperature.Name;
  314. Units[19] = Model.ExcitationWaterTemperature.Unit;
  315. AnalogNames[20] = Model.OilPumpTemperature.Name;
  316. Units[20] = Model.OilPumpTemperature.Unit;
  317. AnalogNames[21] = Model.CoolingWaterOperatingStatus.Name;
  318. Units[21] = Model.CoolingWaterOperatingStatus.Unit;
  319. var maincolor = Tools.ColorHelper.ColorToOxyColor(Tools.ColorHelper.MainColor);
  320. var lablecolor = Tools.ColorHelper.ColorToOxyColor(Tools.ColorHelper.LableColor);
  321. var auxiliarycolor = Tools.ColorHelper.ColorToOxyColor(Tools.ColorHelper.AuxiliaryColor);
  322. PlotModel.TextColor = lablecolor;
  323. PlotModel.TitleColor = lablecolor;
  324. PlotModel.PlotAreaBorderColor = lablecolor;
  325. PlotModel.Axes.Add(new OxyPlot.Axes.DateTimeAxis()
  326. {
  327. Title = "时间",
  328. Position = OxyPlot.Axes.AxisPosition.Bottom,
  329. Key = "X",
  330. MaximumPadding = 0,
  331. MajorGridlineColor = auxiliarycolor,
  332. MajorGridlineStyle = LineStyle.Dot,
  333. MajorGridlineThickness = 1,
  334. MinimumPadding = 0,
  335. ExtraGridlineColor = lablecolor,
  336. TextColor = lablecolor,
  337. TitleColor = lablecolor,
  338. AxislineColor = lablecolor,
  339. TicklineColor = lablecolor,
  340. });
  341. PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
  342. {
  343. Title = "值",
  344. Position = OxyPlot.Axes.AxisPosition.Left,
  345. Key = "Y",
  346. MajorGridlineStyle = LineStyle.Dot,
  347. MajorGridlineColor = auxiliarycolor,
  348. MajorGridlineThickness = 1,
  349. ExtraGridlineColor = lablecolor,
  350. TextColor = lablecolor,
  351. TitleColor =lablecolor,
  352. AxislineColor =lablecolor,
  353. TicklineColor = lablecolor,
  354. });
  355. for (int i = 0; i < AnalogNames.Length-1; i++)
  356. {
  357. if (string.IsNullOrEmpty(AnalogNames[i]) || i == 0 || i==21) continue;
  358. OxyPlot.Series.LineSeries lineSeries = new OxyPlot.Series.LineSeries();
  359. lineSeries.Title = AnalogNames[i];
  360. lineSeries.StrokeThickness = 1;
  361. lineSeries.XAxisKey = "X";
  362. lineSeries.YAxisKey = "Y";
  363. lineSeries.TrackerFormatString = "{1}:{2}\n{0}:{4}" + Units[i];
  364. lineSeries.CanTrackerInterpolatePoints = false;
  365. lineSeries.DataFieldX = nameof(DataMangerItemModel.Time);
  366. lineSeries.DataFieldY = PropertiyNames[i];
  367. lineSeries.IsVisible = PropertiyNames[i] == nameof(DataMangerItemModel.OutputCurrent) || PropertiyNames[i] == nameof(DataMangerItemModel.OutputVoltage);
  368. _LineSeries.Add(lineSeries);
  369. PlotModel.Series.Add(lineSeries);
  370. PlotConfig.Add(new PlotConfigViewModel(lineSeries));
  371. PlotConfig[^1].PropertyChanged += (_, _) =>
  372. {
  373. PlotModel.InvalidatePlot(false);
  374. PlotModel.InvalidatePlot(true);
  375. };
  376. }
  377. {
  378. OxyPlot.Series.LineSeries lineSeries = new OxyPlot.Series.LineSeries();
  379. lineSeries.Title = "增益";
  380. lineSeries.XAxisKey = "X";
  381. lineSeries.YAxisKey = "Y";
  382. lineSeries.IsVisible = false;
  383. lineSeries.StrokeThickness = 1;
  384. lineSeries.TrackerFormatString = "{1}:{2}\n{0}:{4}%";
  385. lineSeries.CanTrackerInterpolatePoints = false;
  386. lineSeries.DataFieldX = nameof(DataMangerItemModel.Time);
  387. lineSeries.DataFieldY = PropertiyNames[^1];
  388. _LineSeries.Add(lineSeries);
  389. PlotModel.Series.Add(lineSeries);
  390. PlotConfig.Add(new PlotConfigViewModel(lineSeries));
  391. PlotConfig[^1].PropertyChanged += (_, _) =>
  392. {
  393. PlotModel.InvalidatePlot(false);
  394. PlotModel.InvalidatePlot(true);
  395. };
  396. }
  397. PlotModel.Legends.Add(new OxyPlot.Legends.Legend()
  398. {
  399. IsLegendVisible = true,
  400. ShowInvisibleSeries = false,
  401. });
  402. BusManger.Defaut.Bus.PubSub.Subscribe<Shaker.Model.ShakerConnectState>((data,property) =>
  403. {
  404. Tools.DispatherInovke.Inovke(() =>
  405. {
  406. IsConnected = data.IsConnected;
  407. });
  408. }, $"{Shaker.Model.GlobalVariable.ShakerIDKey}='{Model.Id}'");
  409. BusManger.Defaut.Bus.PubSub.Subscribe<Shaker.Model.ShakerStatusModel>((data, _) =>
  410. {
  411. Tools.DispatherInovke.Inovke(() =>
  412. {
  413. GainSwitch = data.GainSwich;
  414. StartupCompleted = data.StartupCompleted;
  415. });
  416. }, $"{Shaker.Model.GlobalVariable.ShakerIDKey}='{Model.Id}'");
  417. BusManger.Defaut.Bus.PubSub.Subscribe<Shaker.Model.ClientExitModel>((data, pro) =>
  418. {
  419. Tools.DispatherInovke.Inovke(() =>
  420. {
  421. IsOnline = data.Online;
  422. if (!IsOnline) ActiveMQClintID = string.Empty;
  423. });
  424. }, $"{Shaker.Model.GlobalVariable.ShakerIDKey}='{Model.Id}'");
  425. BusManger.Defaut.Bus.PubSub.Subscribe<DataMangerItemModel>((model, property) =>
  426. {
  427. if(MainWindowViewModel.Default.IsSaveData) Sql.Default.Insert(model, Model.Id);
  428. Tools.DispatherInovke.Inovke(() =>
  429. {
  430. if (CurrentData == null)
  431. {
  432. CurrentData = new DataMangerItemViewModel(model);
  433. }
  434. else
  435. {
  436. CurrentData.UpDateModel(model);
  437. }
  438. lock (locker)
  439. {
  440. gain = model.Gain;
  441. OnPropertyChanged(nameof(Gain));
  442. }
  443. Items.Add(new DataMangerItemViewModel(model));
  444. if (Items.Count > MaxItemCount) Items.RemoveAt(0);
  445. PlotModel.InvalidatePlot(false);
  446. _LineSeries.ForEach(x => x.ItemsSource = Items);
  447. PlotModel.InvalidatePlot(true);
  448. });
  449. }, $"{Shaker.Model.GlobalVariable.ShakerIDKey}='{Model.Id}'");
  450. BusManger.Defaut.Bus.PubSub.Subscribe<Shaker.Model.AllowRemoteControl>((model, property) =>
  451. {
  452. Tools.DispatherInovke.Inovke(() =>
  453. {
  454. IsRemoteControl = model == AllowRemoteControl.Remote;
  455. });
  456. }, $"{Shaker.Model.GlobalVariable.ShakerIDKey}='{Model.Id}'");
  457. PlotController.BindMouseDown(OxyMouseButton.Right, new DelegatePlotCommand<OxyMouseDownEventArgs>((v, c, h) =>
  458. {
  459. h.Handled = true;
  460. MenuIsOpen = true;
  461. }));
  462. }
  463. public OxyPlot.IPlotController PlotController { get; } = new OxyPlot.PlotController();
  464. public View.ShakerView Content { get; } = new View.ShakerView();
  465. public bool GainSwitch
  466. {
  467. get => gainSwitch;
  468. set
  469. {
  470. if (value == gainSwitch) return;
  471. UpdateProperty(ref gainSwitch, value);
  472. OnPropertyChanged(nameof(GainEnabled));
  473. }
  474. }
  475. public bool AllowCoolingWater => Model.AllowCoolingWater;
  476. public ObservableCollection<PLCAnlogViewModel> CoolingWaterValues { get; } = new ObservableCollection<PLCAnlogViewModel>();
  477. public ObservableCollection<PLCAnlogViewModel> Values { get; } = new ObservableCollection<PLCAnlogViewModel>();
  478. public override Type View { get; } = typeof(View.ShakerView);
  479. public ICommand OpenCommand => new DelegateCommand(Open);
  480. public ICommand CloseCommand => new DelegateCommand(Close);
  481. public ICommand StartCommand => new DelegateCommand(Start);
  482. public ICommand StopCommand => new DelegateCommand(Stop);
  483. public ICommand ResetCommand => new DelegateCommand(Reset);
  484. public Task StartNoResult(bool skipPermissions = false)
  485. {
  486. return BusManger.Defaut.Bus.PubSub.PublishAsync<SysControl>(new SysControl()
  487. {
  488. Cmd = SysCmd.Start,
  489. SkipPermissions = skipPermissions,
  490. }, Properties);
  491. }
  492. public async void StopNoResult(bool skipPermissions = false)
  493. {
  494. await BusManger.Defaut.Bus.PubSub.PublishAsync<SysControl>(new SysControl()
  495. {
  496. Cmd = SysCmd.Stop,
  497. SkipPermissions = skipPermissions,
  498. }, Properties);
  499. }
  500. public async void ResetNoResult(bool skipPermissions = false)
  501. {
  502. await BusManger.Defaut.Bus.PubSub.PublishAsync<SysControl>(new SysControl()
  503. {
  504. Cmd = SysCmd.Reset,
  505. SkipPermissions = skipPermissions,
  506. }, Properties);
  507. }
  508. public async void GainSwitchControlNoResult(bool switchon,bool skipPermissions = false)
  509. {
  510. await BusManger.Defaut.Bus.PubSub.PublishAsync<Shaker.Model.SysControl>(new Shaker.Model.SysControl()
  511. {
  512. Cmd = switchon ? SysCmd.OpenGain : Shaker.Model.SysCmd.CloseGain,
  513. SkipPermissions = skipPermissions,
  514. }, Properties);
  515. }
  516. private bool isOpen = false;
  517. public OxyPlot.PlotModel PlotModel { get; } = new OxyPlot.PlotModel();
  518. public bool IsOpen { get => isOpen; set => UpdateProperty(ref isOpen, value); }
  519. private async void Close()
  520. {
  521. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}关闭功放"));
  522. var result = await BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SysControl,Shaker.Model.Result>(new Shaker.Model.SysControl()
  523. {
  524. Cmd = Shaker.Model.SysCmd.CloseGain,
  525. }, Properties);
  526. if(result == null || !result.Success)
  527. {
  528. PromptViewModel.Default.Init();
  529. PromptViewModel.Default.IconType = IconType.Error;
  530. PromptViewModel.Default.Message = result == null ? "通信超时" : result.Message;
  531. PromptViewModel.Default.NoVisibility = Visibility.Collapsed;
  532. PromptViewModel.Default.IsOpen = true;
  533. }
  534. }
  535. public void SetGainNoResult(short gain,bool skipPermissions = false)
  536. {
  537. lock (locker)
  538. {
  539. BusManger.Defaut.Bus.PubSub.PublishAsync(new SetGain()
  540. {
  541. Gain = gain,
  542. SkipPermissions = skipPermissions,
  543. }, Properties).Wait();
  544. this.gain = gain;
  545. OnPropertyChanged(nameof(Gain));
  546. }
  547. }
  548. public ICommand GainSwitchCommand => new DelegateCommand<ExCommandParameter>(GainSwitchControl);
  549. public void GainSwitchControl(ExCommandParameter parameter)
  550. {
  551. if (parameter.Parameter is bool switchon)
  552. {
  553. if (switchon) Open();
  554. else Close();
  555. return;
  556. }
  557. if(parameter.Parameter is string val && bool.TryParse(val,out var result))
  558. {
  559. if (result) Open();
  560. else Close();
  561. return;
  562. }
  563. }
  564. private void SetGain(short gain)
  565. {
  566. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}设置功放增益为{Gain}%"));
  567. var result = BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SetGain, Shaker.Model.Result>(new Shaker.Model.SetGain()
  568. {
  569. Gain = gain,
  570. }, Properties).Result;
  571. if (result == null || !result.Success)
  572. {
  573. PromptViewModel.Default.Init();
  574. PromptViewModel.Default.IconType = IconType.Error;
  575. PromptViewModel.Default.Message = result == null ? "通信超时" : result.Message;
  576. PromptViewModel.Default.NoVisibility = Visibility.Collapsed;
  577. PromptViewModel.Default.IsOpen = true;
  578. }
  579. } public bool GainSwitchEnabled => CurrentData?.OperatingStatus == OperatingStatus.Run && StartupCompleted;
  580. public bool GainEnabled => CurrentData != null && (CurrentData.OperatingStatus == OperatingStatus.Run && GainSwitch);
  581. public bool StartEnabled => CurrentData?.OperatingStatus == OperatingStatus.Wait;
  582. public bool StopEnabled => CurrentData?.OperatingStatus == OperatingStatus.Run;
  583. public bool ResetEnabled => CurrentData?.OperatingStatus != OperatingStatus.Run;
  584. private async void Start()
  585. {
  586. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}功放开始"));
  587. var result = await BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SysControl,Shaker.Model.Result>(new Shaker.Model.SysControl()
  588. {
  589. Cmd = Shaker.Model.SysCmd.Start,
  590. }, Properties);
  591. if (result == null || !result.Success)
  592. {
  593. PromptViewModel.Default.Init();
  594. PromptViewModel.Default.IconType = IconType.Error;
  595. PromptViewModel.Default.Message = result == null ? "通信超时" : result.Message;
  596. PromptViewModel.Default.NoVisibility = Visibility.Collapsed;
  597. PromptViewModel.Default.IsOpen = true;
  598. }
  599. }
  600. private async void Stop()
  601. {
  602. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}停止功放"));
  603. var result = await BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SysControl,Shaker.Model.Result>(new Shaker.Model.SysControl()
  604. {
  605. Cmd = Shaker.Model.SysCmd.Stop,
  606. }, Properties);
  607. }
  608. private async void Reset()
  609. {
  610. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}功放复位"));
  611. var result= await BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SysControl,Shaker.Model.Result>(new Shaker.Model.SysControl()
  612. {
  613. Cmd = Shaker.Model.SysCmd.Reset,
  614. }, Properties);
  615. if (result == null || !result.Success)
  616. {
  617. PromptViewModel.Default.Init();
  618. PromptViewModel.Default.IconType = IconType.Error;
  619. PromptViewModel.Default.Message = result == null ? "通信超时" : result.Message;
  620. PromptViewModel.Default.NoVisibility = Visibility.Collapsed;
  621. PromptViewModel.Default.IsOpen = true;
  622. }
  623. }
  624. private async void Open()
  625. {
  626. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}打开功放"));
  627. var result = await BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SysControl,Shaker.Model.Result>(new Shaker.Model.SysControl()
  628. {
  629. Cmd = Shaker.Model.SysCmd.OpenGain,
  630. }, Properties);
  631. if (result == null || !result.Success)
  632. {
  633. PromptViewModel.Default.Init();
  634. PromptViewModel.Default.IconType = IconType.Error;
  635. PromptViewModel.Default.Message = result == null ? "通信超时" : result.Message;
  636. PromptViewModel.Default.NoVisibility = Visibility.Collapsed;
  637. PromptViewModel.Default.IsOpen = true;
  638. }
  639. }
  640. private short gain;
  641. private bool setPlotConfigIsOpen = false;
  642. [AllowNull]
  643. private DataMangerItemViewModel currentData;
  644. private bool isConnected = false;
  645. private bool isRemoteControl = false;
  646. private bool isOnline = false;
  647. private bool gainSwitch = false;
  648. private bool isDeviceControl = false;
  649. private ShakerViewType shakerView = Data.ShakerViewType.None;
  650. private bool menuIsOpen = false;
  651. private bool startupCompleted = false;
  652. private string activeMQClintID = string.Empty;
  653. private string gifPath = string.Empty;
  654. private RepeatBehavior repeatBehavior = RepeatBehavior.Forever;
  655. private bool autoStart = true;
  656. private bool cacheFramesInMemory = true;
  657. public string Title => string.IsNullOrEmpty(Description) ? Name : Description;
  658. private bool modelVisibily = false;
  659. public string Name
  660. {
  661. get => Model.Name;
  662. set
  663. {
  664. UpdateProperty(ref Model.Name, value);
  665. OnPropertyChanged(nameof(Title));
  666. }
  667. }
  668. public string Description
  669. {
  670. get => Model.Description;
  671. set
  672. {
  673. if (value == Model.Description) return;
  674. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}别名修改为{value}"));
  675. UpdateProperty(ref Model.Description, value);
  676. Sql.Default.UpDate<Shaker.Model.ShakerControlModel, string, string>(p => p.Id, Model.Id, p => p.Description, Model.Description);
  677. OnPropertyChanged(nameof(Title));
  678. }
  679. }
  680. public byte SlaveID { get=>Model.SlaveID; set=>UpdateProperty(ref Model.SlaveID, value); }
  681. public string IPAddress
  682. {
  683. get => Model.IPAddress;
  684. set
  685. {
  686. if (Model.Id == value) return;
  687. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}功放IP地址修改为{value}"));
  688. UpdateProperty(ref Model.IPAddress, value);
  689. Sql.Default.UpDate<Shaker.Model.ShakerControlModel, string, string>(p => p.Id, Model.Id, p => p.IPAddress, Model.IPAddress);
  690. }
  691. }
  692. public int Port
  693. {
  694. get => Model.Port;
  695. set
  696. {
  697. if (value != Model.Port)
  698. {
  699. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"振动台{Name}功放端口号修改为{value}"));
  700. UpdateProperty(ref Model.Port, value);
  701. Sql.Default.UpDate<Shaker.Model.ShakerControlModel, string, int>(p => p.Id, Model.Id, p => p.Port, Model.Port);
  702. }
  703. }
  704. }
  705. public ICommand RequestPermissionsCommand => new DelegateCommand(RequestPermissions);
  706. private async void RequestPermissions()
  707. {
  708. if (IsRemoteControl) return;
  709. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"申请振动台{Name}功放控制权限"));
  710. var result = await BusManger.Defaut.Bus.RPC.RequestAsync<Shaker.Model.SysControl, Shaker.Model.Result>(new Shaker.Model.SysControl()
  711. {
  712. Cmd = Shaker.Model.SysCmd.ApplicationControl,
  713. }, Properties,CancellationToken.None,MainWindowViewModel.Default.SystemConfig.SystemPage.RequestPermissionsTimeout);
  714. if (result == null || !result.Success)
  715. {
  716. PromptViewModel.Default.Init();
  717. PromptViewModel.Default.IconType = IconType.Error;
  718. PromptViewModel.Default.Message = result == null ? "通信超时" : result.Message;
  719. PromptViewModel.Default.NoVisibility = Visibility.Collapsed;
  720. PromptViewModel.Default.IsOpen = true;
  721. }
  722. }
  723. public short Gain
  724. {
  725. get => gain;
  726. set
  727. {
  728. if (gain == value) return;
  729. lock (locker)
  730. {
  731. UpdateProperty(ref gain, value);
  732. }
  733. SetGain(value);
  734. }
  735. }
  736. public bool IsRemoteControl { get => isRemoteControl; set =>UpdateProperty(ref isRemoteControl, value); }
  737. public ICommand SaveCommand => new DelegateCommand(() => Save());
  738. public ICommand CancelCommand => new DelegateCommand(() => Cancel());
  739. private void Save()
  740. {
  741. GetEvent<Shaker.Model.LogModel>().Publish(this, new Shaker.Model.LogModel($"修改了振动台{Name}配置参数"));
  742. Sql.Default.Replace(p => p.Id, Model.Id, Model);
  743. }
  744. private void Cancel()
  745. {
  746. Model = Sql.Default.FindFirst<Shaker.Model.ShakerControlModel>(p => p.Id == Model.Id)!;
  747. RefreshUI();
  748. }
  749. public bool IsMax { get; set; }
  750. public bool IsSelected { get; set; }
  751. }
  752. }