MainWin.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. using DevExpress.XtraEditors;
  2. using DevExpress.XtraLayout.Utils;
  3. using Ips.Library.Basic;
  4. using Ips.AdcTool.Win.ViewModels;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.ComponentModel;
  8. using System.Data;
  9. using System.Drawing;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Text.Json;
  14. using System.Threading.Tasks;
  15. using System.Windows.Forms;
  16. using Ips.Library.DxpLib;
  17. using Ips.Library.Entity;
  18. using DevExpress.XtraDiagram.Bars;
  19. using DevExpress.CodeParser;
  20. using DevExpress.CodeParser.VB;
  21. using Ips.AdcAlgorithm;
  22. using DevExpress.XtraCharts;
  23. using DevExpress.Pdf.Native.DocumentSigning;
  24. using DevExpress.XtraEditors.Controls;
  25. using Ips.Library.LocLib;
  26. namespace Ips.AdcTool.Win
  27. {
  28. public partial class MainWin : DevExpress.XtraBars.ToolbarForm.ToolbarForm
  29. {
  30. public MainWin()
  31. {
  32. InitializeComponent();
  33. DirectoryUtil.CreateIfNotExists(Path.GetDirectoryName(ConfigPath));
  34. InitForm();
  35. }
  36. IAdController _adController;
  37. static readonly string ConfigPath = Path.Combine(Directory.GetCurrentDirectory(), "AppData", "adconfig.json");
  38. DriveMonitor _driveMonitor;
  39. CancellationTokenSource _cts;
  40. void InitForm()
  41. {
  42. gvAdSig.ShowRowNumber();
  43. txtAdCardType.Properties.Items.AddEnum<AdCardType>();
  44. txtAdCardType.SelectedIndex = 0;
  45. txtTriggerMode.Properties.Items.AddEnum<AdTriggerMode>();
  46. txtTriggerMode.SelectedIndex = 0;
  47. txtClockType.Properties.Items.AddEnum<AdClockType>();
  48. txtClockType.SelectedIndex = 0;
  49. txtAdMode.Properties.Items.AddEnum<AdMode>();
  50. txtAdMode.SelectedValueChanged += (sender, arg) =>
  51. {
  52. var admode = (AdMode)txtAdMode.EditValue;
  53. switch (admode)
  54. {
  55. case AdMode.ADC:
  56. tcgMain.SelectedTabPage = lcgWorkLog;
  57. lcgDdcArg.Visibility = LayoutVisibility.Never;
  58. lciStartupType.Enabled = true;
  59. lciLoopInterval.Enabled = true;
  60. lciLoopTimes.Enabled = true;
  61. txtChCount.Enabled = true;
  62. break;
  63. case AdMode.DDC:
  64. tcgMain.SelectedTabPage = lcgDdcArg;
  65. lcgDdcArg.Visibility = LayoutVisibility.Always;
  66. lciStartupType.Enabled = true;
  67. lciLoopInterval.Enabled = true;
  68. lciLoopTimes.Enabled = true;
  69. txtChCount.Enabled = false;
  70. break;
  71. case AdMode.DDCKeep:
  72. tcgMain.SelectedTabPage = lcgDdcArg;
  73. lcgDdcArg.Visibility = LayoutVisibility.Always;
  74. lciStartupType.Enabled = false;
  75. lciLoopInterval.Enabled = false;
  76. lciLoopTimes.Enabled = false;
  77. txtChCount.Enabled = false;
  78. break;
  79. }
  80. };
  81. txtStartupType.Properties.Items.AddEnum<AdStartupMode>();
  82. txtStartupType.SelectedValueChanged += (sender, arg) =>
  83. {
  84. var startupType = (AdStartupMode)txtStartupType.EditValue;
  85. bool showLoop = startupType == AdStartupMode.AdLoop;
  86. lciLoopInterval.Visibility = showLoop ? LayoutVisibility.Always : LayoutVisibility.Never;
  87. lciLoopTimes.Visibility = showLoop ? LayoutVisibility.Always : LayoutVisibility.Never;
  88. };
  89. txtStartTime.UseTimeEdit();
  90. _adController = AppSettings.ApiVersion == 0 ? new AdcController() : new AdgController();
  91. }
  92. void InitViewModel()
  93. {
  94. if (!File.Exists(ConfigPath))
  95. {
  96. viewModel = new MainViewModel();
  97. }
  98. else
  99. {
  100. string json = File.ReadAllText(ConfigPath);
  101. viewModel = JsonSerializer.Deserialize<MainViewModel>(json);
  102. }
  103. txtAdCardType.EditValue = viewModel.CarderType;
  104. txtTriggerMode.EditValue = viewModel.TriggerMode;
  105. txtClockType.EditValue = viewModel.ClockerType;
  106. txtDdcFreq.EditValue = viewModel.DdcFreq;
  107. txtClockFreq.EditValue = viewModel.ClockFreq;
  108. txtAdMode.EditValue = viewModel.AdMode;
  109. txtMutil.EditValue = viewModel.Mutil;
  110. txtChCount.EditValue = viewModel.ChCount;
  111. txtAdLen.EditValue = viewModel.AdLen;
  112. txtStartupType.EditValue = viewModel.StartupType;
  113. txtStorePath.EditValue = viewModel.StorePath;
  114. txtLoopInterval.EditValue = viewModel.LoopInterval;
  115. txtLoopTimes.EditValue = viewModel.LoopTimes;
  116. txtStartTime.EditValue = null;
  117. }
  118. void SetViewModel()
  119. {
  120. viewModel.CarderType = (AdCardType)txtAdCardType.EditValue;
  121. viewModel.TriggerMode = (AdTriggerMode)txtTriggerMode.EditValue;
  122. viewModel.ClockerType = (AdClockType)txtClockType.EditValue;
  123. viewModel.DdcFreq = txtDdcFreq.Text.To(0d);
  124. viewModel.ClockFreq = txtClockFreq.Text.To(0d);
  125. viewModel.AdMode = (AdMode)txtAdMode.EditValue;
  126. viewModel.Mutil = txtMutil.Text.To(0);
  127. viewModel.ChCount = viewModel.AdMode == AdMode.ADC ? txtChCount.Text.To(1) : viewModel.AdChes.Max(m => m.ChNum);
  128. viewModel.AdLen = txtAdLen.Text.To(1);
  129. viewModel.StartTime = txtStartTime.EditValue == null ? null : txtStartTime.DateTime;
  130. viewModel.StartupType = (AdStartupMode)txtStartupType.EditValue;
  131. viewModel.StorePath = txtStorePath.Text;
  132. viewModel.LoopInterval = txtLoopInterval.Text.To(0);
  133. viewModel.LoopTimes = txtLoopTimes.Text.To(0);
  134. if (viewModel.StorePath.IsNotNullOrWhitespace())
  135. {
  136. try
  137. {
  138. DirectoryUtil.CreateIfNotExists(viewModel.StorePath);
  139. }
  140. catch (Exception ex)
  141. {
  142. IpsLogger.Info($"创建存储目录[{viewModel.StorePath}]出错,{ex.Message}");
  143. }
  144. }
  145. }
  146. void SaveViewModel()
  147. {
  148. string json = JsonSerializer.Serialize<MainViewModel>(viewModel, new JsonSerializerOptions()
  149. {
  150. WriteIndented = true
  151. });
  152. File.WriteAllText(ConfigPath, json);
  153. }
  154. MainViewModel viewModel;
  155. private void WriteAdLog(string msg)
  156. {
  157. if (msg.IsNotNullOrWhitespace())
  158. IpsLogger.Info($"adc:{msg}");
  159. }
  160. private void MainWin_Load(object sender, EventArgs e)
  161. {
  162. try
  163. {
  164. InitViewModel();
  165. grdAdCh.DataSource = viewModel.AdChes;
  166. grdAdSig.DataSource = viewModel.AdSigs;
  167. repSatNums.DataSource = viewModel.AdChes.OrderBy(m => m.SatNum);
  168. repSatNums.DisplayMember = nameof(AdCh.SatNum);
  169. repSatNums.ValueMember = nameof(AdCh.SatNum);
  170. IpsLogger.Info("启动信道化采集工具成功");
  171. }
  172. catch (Exception ex)
  173. {
  174. IpsLogger.Error("启动信道化采集工具失败", ex);
  175. }
  176. }
  177. private void btnStart_Click(object sender, EventArgs e)
  178. {
  179. try
  180. {
  181. SetViewModel();
  182. if (!Directory.Exists(viewModel.StorePath))
  183. {
  184. MsgHelper.ShowError($"启动采集失败,存储目录【{viewModel.StorePath}】不存在!");
  185. return;
  186. }
  187. SaveViewModel();
  188. _driveMonitor = new DriveMonitor(viewModel.StorePath);
  189. _driveMonitor.Start();
  190. btnStart.Enabled = false;
  191. btnStop.Enabled = true;
  192. tcgMain.SelectedTabPage = lcgWorkLog;
  193. _cts = new CancellationTokenSource();
  194. cjWorker.RunWorkerAsync();
  195. }
  196. catch (Exception ex)
  197. {
  198. MsgHelper.ShowError("启动采集异常:" + ex.Message, ex);
  199. }
  200. }
  201. private async void btnStop_Click(object sender, EventArgs e)
  202. {
  203. try
  204. {
  205. _driveMonitor?.Stop();
  206. await _adController?.Stop();
  207. cjWorker.CancelAsync();
  208. _cts.Cancel();
  209. }
  210. catch (Exception ex)
  211. {
  212. ex.HandleCancelEx(ex1 =>
  213. {
  214. MsgHelper.ShowError("停止采集出错:" + ex1.Message, ex1);
  215. });
  216. }
  217. }
  218. private void lcgAdCh_CustomButtonClick(object sender, DevExpress.XtraBars.Docking2010.BaseButtonEventArgs e)
  219. {
  220. string caption = e.Button.Properties.Caption;
  221. switch (caption)
  222. {
  223. case "添加":
  224. gvAdCh.AddNewRow();
  225. break;
  226. case "删除":
  227. gvAdCh.DeleteSelectedRows();
  228. break;
  229. }
  230. }
  231. private void lcgAdSig_CustomButtonClick(object sender, DevExpress.XtraBars.Docking2010.BaseButtonEventArgs e)
  232. {
  233. string caption = e.Button.Properties.Caption;
  234. switch (caption)
  235. {
  236. case "添加":
  237. gvAdSig.AddNewRow();
  238. break;
  239. case "删除":
  240. gvAdSig.DeleteSelectedRows();
  241. break;
  242. }
  243. }
  244. private void MainWin_FormClosing(object sender, FormClosingEventArgs e)
  245. {
  246. if (cjWorker.IsBusy)
  247. {
  248. e.Cancel = !MsgHelper.ShowConfirm("采集正在进行中,确定要退出吗?");
  249. if (!e.Cancel) return;
  250. }
  251. try
  252. {
  253. _adController.Stop();
  254. SetViewModel();
  255. SaveViewModel();
  256. }
  257. catch (Exception ex)
  258. {
  259. MsgHelper.ShowError("退出采集出错:" + ex.Message, ex);
  260. }
  261. }
  262. private void gvAdSig_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
  263. {
  264. //if (e.Column == gcUpFreq)
  265. //{
  266. // var upFreq = (double)e.Value;
  267. // if (upFreq >= 200 && upFreq <= 400)
  268. // {
  269. // var downFreq = FreqBasicUtils.GetDownFreq(upFreq);
  270. // gvAdSig.SetRowCellValue(e.RowHandle, gcDownFreq, downFreq);
  271. // }
  272. //}
  273. }
  274. private AdcOptions BuildAdcOptions()
  275. {
  276. AdcOptions options = new AdcOptions();
  277. options.CardType = viewModel.CarderType;
  278. options.ChCount = viewModel.ChCount;
  279. options.ClockFreq = viewModel.ClockFreq.E6l();
  280. options.DdcFreq = viewModel.DdcFreq.E6();
  281. options.ClockType = viewModel.ClockerType;
  282. options.StorePath = viewModel.StorePath;
  283. options.Mutil = viewModel.Mutil;
  284. options.TimeLen = viewModel.AdLen;
  285. options.TriggerMode = viewModel.TriggerMode;
  286. options.Real = viewModel.Mutil < 2;
  287. if (viewModel.StartTime.HasValue)
  288. {
  289. }
  290. else
  291. {
  292. }
  293. if (viewModel.AdMode != AdMode.ADC)
  294. {
  295. viewModel.AdChes.ForEach(ch =>
  296. {
  297. var chOpt = options.SetChannel(ch.SiteCode, ch.AdcCode, ch.ChNum, ch.CenterFreq.E6l());
  298. var sigList = viewModel.AdSigs.Where(m => m.SatNums.IsNullOrWhitespace() || m.SatNums.Contains(ch.SatNum));
  299. sigList.ForEach(sig =>
  300. {
  301. long upFreq = sig.UpFreq.E6l();
  302. int bandWidth = sig.BandWidth.E3();
  303. long downFreq = upFreq;
  304. if (AppSettings.IsWarSat(ch.SatNum))
  305. {
  306. downFreq = WarSatFreq.GetDownFreq(upFreq);
  307. }
  308. //chOpt.AddSignal(downFreq, bandWidth, upFreq.ToString());
  309. chOpt.AddSignal(downFreq, bandWidth, ch.SatNum, upFreq);
  310. });
  311. });
  312. }
  313. return options;
  314. }
  315. private void cjWorker_DoWork(object sender, DoWorkEventArgs e)
  316. {
  317. var adcOptions = BuildAdcOptions();
  318. switch (viewModel.AdMode)
  319. {
  320. case AdMode.ADC:
  321. ExecAdc(adcOptions);
  322. break;
  323. case AdMode.DDC:
  324. ExecDdcOne(adcOptions);
  325. break;
  326. case AdMode.DDCKeep:
  327. ExecDdcKeep(adcOptions);
  328. break;
  329. }
  330. }
  331. private void cjWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  332. {
  333. btnStart.Enabled = true;
  334. btnStop.Enabled = false;
  335. _driveMonitor?.Stop();
  336. if (e.Error != null)
  337. {
  338. bool isStop = false;
  339. e.Error.HandleCancelEx(m =>
  340. {
  341. IpsLogger.Info("采集异常,错误消息:" + m.Message);
  342. }, m =>
  343. {
  344. isStop = true;
  345. });
  346. if (isStop)
  347. {
  348. IpsLogger.Info("已手动停止采集!");
  349. }
  350. }
  351. }
  352. private void ExecAdc(AdcOptions options)
  353. {
  354. IpsLogger.Info($"开始执行ADC直采");
  355. if (viewModel.StartupType == AdStartupMode.AdOnce)
  356. {
  357. var adres = _adController.StartAdc(options, WriteAdLog, _cts.Token).Result;
  358. IpsLogger.Info($"采集完成,信号时间:{adres.StartTime:yyyy-MM-dd HH:mm:ss},采集参数:" + adres.Arguments);
  359. }
  360. else
  361. {
  362. int loopTimes = 1;
  363. while (viewModel.LoopTimes == 0 || loopTimes <= viewModel.LoopTimes)
  364. {
  365. if (_cts.IsCancellationRequested)
  366. {
  367. IpsLogger.Info("已手动停止采集");
  368. break;
  369. }
  370. var adres = _adController.StartAdc(options, WriteAdLog, _cts.Token).Result;
  371. var stopTime = (options.StartTime.AddSeconds(options.TimeLen + 2));
  372. if (stopTime > DateTime.Now)
  373. {
  374. Task.Delay(stopTime - DateTime.Now, _cts.Token).Wait();
  375. }
  376. IpsLogger.Info($"第{loopTimes}次采集完成,信号时间:{adres.StartTime:yyyy-MM-dd HH:mm:ss},采集参数:" + adres.Arguments);
  377. var nextStartTime = adres.StartTime.AddSeconds(viewModel.LoopInterval);
  378. options.StartTime = nextStartTime;
  379. loopTimes++;
  380. }
  381. IpsLogger.Info($"循环采集完成,共采集{loopTimes - 1}次!");
  382. }
  383. }
  384. private void ExecDdcOne(AdcOptions options)
  385. {
  386. IpsLogger.Info($"开始执行DDC采集");
  387. if (viewModel.StartupType == AdStartupMode.AdOnce)
  388. {
  389. var adres = _adController.StartDdcOne(options, WriteAdLog, _cts.Token).Result;
  390. IpsLogger.Info($"DDC采集结束,开始时间:{adres.StartTime},采集参数:{adres.Arguments}");
  391. }
  392. else
  393. {
  394. int loopTimes = 0;
  395. while (viewModel.LoopTimes == 0 || loopTimes > viewModel.LoopTimes)
  396. {
  397. if (_cts.IsCancellationRequested)
  398. {
  399. IpsLogger.Info("已手动停止采集");
  400. break;
  401. }
  402. var adres = _adController.StartDdcOne(options, WriteAdLog, _cts.Token).Result;
  403. IpsLogger.Info($"信道化采集完成,信号时间:{adres.StartTime:yyyy-MM-dd HH:mm:ss},采集参数:{adres.Arguments}");
  404. var nextStartTime = adres.StartTime.AddSeconds(viewModel.LoopInterval);
  405. options.StartTime = nextStartTime;
  406. loopTimes++;
  407. }
  408. }
  409. }
  410. private void ExecDdcKeep(AdcOptions options)
  411. {
  412. if (options.StartTime < DateTime.Now.AddSeconds(AdcConst.MinWaitTime))
  413. options.StartTime = DateTime.Now.AddSeconds(AdcConst.MinWaitTime);
  414. var startTime = options.StartTime;
  415. options.StartTime = startTime.ClearSecond().AddSeconds(Math.Ceiling(startTime.Second * 1.0 / options.TimeLen) * options.TimeLen);
  416. IpsLogger.Info($"开始执行DDC持续采集");
  417. var adres = _adController.StartDdcKeep(options, null, WriteAdLog, _cts.Token).Result;
  418. IpsLogger.Info($"信号化持续采集启动成功,开始时间:{adres.StartTime:yyyy-MM-dd HH:mm:ss},参数:{adres.Arguments}");
  419. try
  420. {
  421. Task.Delay(int.MaxValue, _cts.Token).Wait();
  422. }
  423. catch (AggregateException aggEx)
  424. {
  425. aggEx.Handle(ex =>
  426. {
  427. if (ex is TaskCanceledException)
  428. {
  429. IpsLogger.Info("手动停止采集成功!");
  430. return true;
  431. }
  432. return false;
  433. });
  434. }
  435. }
  436. private void gvAdSig_CustomColumnDisplayText(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDisplayTextEventArgs e)
  437. {
  438. if (e.Column == gcDownFreq)
  439. {
  440. var selCh = gvAdCh.FocusedRowObject as AdCh;
  441. var sig = gvAdSig.GetRow(gvAdSig.GetRowHandle(e.ListSourceRowIndex)) as AdSig;
  442. if (selCh == null)
  443. {
  444. e.DisplayText = "--";
  445. }
  446. else if (AppSettings.IsWarSat(selCh.SatNum))
  447. {
  448. var downFreq = WarSatFreq.GetDownFreq(sig.UpFreq.E6l()).E6m();
  449. e.DisplayText = $"{downFreq}";
  450. }
  451. else
  452. {
  453. e.DisplayText = $"{sig.UpFreq}";
  454. }
  455. }
  456. else if (e.Column == gcSatNums)
  457. {
  458. var satNums = e.Value?.ToString();
  459. e.DisplayText = satNums.IsNullOrWhitespace() ? "全部" : e.DisplayText;
  460. }
  461. }
  462. private void gvAdCh_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
  463. {
  464. gvAdSig.RefreshData();
  465. }
  466. private void repSatNums_Popup(object sender, EventArgs e)
  467. {
  468. repSatNums.DataSource = viewModel.AdChes.OrderBy(m => m.SatNum);
  469. }
  470. private void txtStartTime_ButtonClick(object sender, ButtonPressedEventArgs e)
  471. {
  472. if (e.Button.Kind == ButtonPredefines.Clear)
  473. {
  474. txtStartTime.EditValue = null;
  475. }
  476. }
  477. }
  478. }