AdgUtil - 复制.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. using CliWrap;
  2. using CliWrap.Buffered;
  3. using Ips.Library.Basic;
  4. using Ips.Library.Entity;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Reflection.Metadata;
  11. using System.Text;
  12. using System.Text.Json;
  13. using System.Text.Json.Serialization;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. namespace Ips.AdcAlgorithm
  17. {
  18. public static class AdgUtil
  19. {
  20. static AdgUtil()
  21. {
  22. DirectoryUtil.CreateIfNotExists(ParamsPath);
  23. }
  24. static readonly string CliPath = PathUtil.GetBasePath("ipscli", "adg");
  25. static readonly string CliFile = Path.Combine(CliPath, "adg.exe");
  26. static readonly string CliAppCfg = Path.Combine(CliPath, "app.cfg");
  27. static readonly string ParamsPath = PathUtil.GetBasePath("AdParams");
  28. static readonly string AdArgFile = Path.Combine(ParamsPath, "adarg.json");
  29. static readonly string DdcArgFile = Path.Combine(ParamsPath, "ddcarg.json");
  30. static readonly string QFStopExe = Path.Combine(CliPath, "stop.exe");
  31. static CommandTask<CommandResult> DDCTsk;
  32. static Timer DDCOneStopTimer = new Timer(AutoStopAdDdc, null, Timeout.Infinite, Timeout.Infinite);
  33. static Timer DDCRestartTimer = new Timer(RestartDdc, null, Timeout.Infinite, Timeout.Infinite);
  34. static AdcOptions lastAdArg;
  35. static Dictionary<string, AdcOptions> _adArgs = new Dictionary<string, AdcOptions>();
  36. static Dictionary<string, DdcOptions> _ddcArgs = new Dictionary<string, DdcOptions>();
  37. public static event EventHandler<AdcMessageEventArgs> AdLogNotify;
  38. public static async Task<ExeResult<AdcResult>> StartAdc(AdcOptions options, Action<string> handline = null, CancellationToken token = default)
  39. {
  40. //停止采集
  41. await StopAdc();
  42. //修改配置
  43. SetAppCfg(options);
  44. if (options.StartTime < DateTime.Now.AddSeconds(AdcConst.MinWaitTime))
  45. options.StartTime = DateTime.Now.AddSeconds(AdcConst.MinWaitTime);
  46. DirectoryUtil.CreateIfNotExists(options.StorePath);
  47. var cmd = CliWrap.Cli.Wrap(CliFile)
  48. .WithWorkingDirectory(CliPath)
  49. .WithValidation(CommandResultValidation.None)
  50. .WithArguments(args =>
  51. {
  52. args.Add(1);
  53. args.Add(DateTimeUtil.To1970s(options.StartTime));
  54. args.Add(options.ClockType.ToString("D"));
  55. args.Add(options.TriggerMode.ToString("D"));
  56. args.Add(options.DdcFreq.E6m().ToString());
  57. args.Add(options.ClockFreq.E6m().ToString());
  58. args.Add(options.Mutil == 1 ? 0 : options.Mutil);
  59. args.Add(options.ChCount);
  60. args.Add(options.StorePath, true);
  61. args.Add(options.TimeLen);
  62. });
  63. if (handline != null)
  64. {
  65. cmd = cmd.WithStandardErrorPipe(PipeTarget.ToDelegate(handline))
  66. .WithStandardOutputPipe(PipeTarget.ToDelegate(handline));
  67. }
  68. var result = await cmd.ExecuteAsync(token);
  69. var adcResult = AdcFileUtil.BuildAdcResult(options, AdMode.ADC);
  70. return ExeResult.Create(adcResult, cmd.Arguments, result.StartTime, result.ExitTime, result.ExitCode);
  71. }
  72. /// <summary>
  73. /// DDC采集
  74. /// </summary>
  75. public static async Task<ExeResult<AdcResult>> StartDdcOne(AdcOptions options, Action<string> handline = null, CancellationToken token = default)
  76. {
  77. await StopAdc();
  78. SetAppCfg(options);
  79. if (options.StartTime < DateTime.Now.AddSeconds(AdcConst.MinWaitTime))
  80. options.StartTime = DateTime.Now.AddSeconds(AdcConst.MinWaitTime);
  81. var cmd = BuildDdcCommand(options, handline);
  82. //由于DDC采集不会停止,到时间后结束进程
  83. var stopTimeSpan = options.StartTime.AddSeconds(options.TimeLen + AdcConst.DDCFindFileDelay) - DateTime.Now;
  84. DDCOneStopTimer.Change(stopTimeSpan, Timeout.InfiniteTimeSpan);
  85. var cmdRes = await cmd.ExecuteAsync(token);
  86. var adcResult = BuildDdcResult(options);
  87. return ExeResult.Create(adcResult, cmd.Arguments, cmdRes.StartTime, cmdRes.ExitTime, cmdRes.ExitCode);
  88. }
  89. /// <summary>
  90. /// DDC持续采集
  91. /// </summary>
  92. /// <param name="adArg">采集参数</param>
  93. /// <param name="ddcArg">DDC参数</param>
  94. /// <returns></returns>
  95. public static async Task<ExeResult<AdcResult>> StartDdcKeep(AdcOptions options, Action<AdcResult> resultCallback, Action<string> handline = null, CancellationToken token = default)
  96. {
  97. //停止原有采集
  98. await StopAdc();
  99. //设置配置文件
  100. SetAppCfg(options);
  101. if (options.StartTime < DateTime.Now.AddSeconds(AdcConst.MinWaitTime))
  102. options.StartTime = DateTime.Now.AddSeconds(AdcConst.MinWaitTime);
  103. var startTime = options.StartTime;
  104. options.StartTime = startTime.ClearSecond().AddSeconds(Math.Ceiling(startTime.Second * 1.0 / options.TimeLen) * options.TimeLen);
  105. var cmd = BuildDdcCommand(options, handline);
  106. var adcTsk = cmd.ExecuteAsync(token);
  107. var outTsk = Task.Run(async () =>
  108. {
  109. while (!adcTsk.Task.IsCompleted)
  110. {
  111. await Task.Delay(options.StartTime.AddSeconds(options.TimeLen + AdcConst.DDCFindFileDelay) - DateTime.Now, token);
  112. var adcResult = BuildDdcResult(options);
  113. resultCallback?.Invoke(adcResult);
  114. options.StartTime = options.StartTime.AddSeconds(options.TimeLen);
  115. }
  116. });
  117. await Task.WhenAll(adcTsk, outTsk);
  118. var cmdRes = await adcTsk;
  119. return ExeResult.Create(new AdcResult(options.StartTime, options.StorePath), cmd.Arguments, cmdRes.StartTime, cmdRes.ExitTime, cmdRes.ExitCode);
  120. }
  121. /// <summary>
  122. /// DDC持续采集,共享采集
  123. /// </summary>
  124. /// <param name="sharedId">共享编号</param>
  125. /// <param name="adArg">采集参数</param>
  126. /// <param name="ddcArg">DDC参数</param>
  127. /// <returns></returns>
  128. public static Task<ExeResult<AdcResult>> StartDdcShared(string sharedId, AdcOptions adArg, DdcOptions ddcArg, CancellationToken token)
  129. {
  130. lastAdArg = adArg;
  131. _adArgs[sharedId] = adArg;
  132. _ddcArgs[sharedId] = ddcArg;
  133. SaveAdParams();
  134. var result = StartDdcKeepInternal(token);
  135. return result;
  136. }
  137. private static Task<ExeResult<AdcResult>> StartDdcKeepInternal(CancellationToken token = default)
  138. {
  139. //StopAdc();
  140. var adDdcArg = GetAdDdcArg();
  141. AdcOptions adArg = adDdcArg.adArg;
  142. DdcOptions ddcArg = adDdcArg.ddcArg;
  143. SetAppCfg(adArg);
  144. var startTime = DateTime.Now.AddSeconds(30);
  145. adArg.StartTime = startTime.ClearSecond().AddSeconds(Math.Ceiling(startTime.Second * 1.0 / 15) * 15);
  146. DirectoryUtil.CreateIfNotExists(adArg.StorePath);
  147. var cmd = CliWrap.Cli.Wrap(CliFile)
  148. .WithWorkingDirectory(CliPath)
  149. .WithValidation(CommandResultValidation.None)
  150. .WithArguments(args =>
  151. {
  152. args.Add(2);
  153. args.Add(DateTimeUtil.To1970s(adArg.StartTime));
  154. args.Add(adArg.ClockType.ToString("D"));
  155. args.Add(adArg.TriggerMode.ToString("D"));
  156. args.Add(adArg.DdcFreq.E6m().ToString());
  157. args.Add(adArg.ClockFreq.E6m().ToString());
  158. args.Add(adArg.Mutil);
  159. args.Add(adArg.ChCount);
  160. args.Add(adArg.StorePath);
  161. args.Add(adArg.TimeLen);
  162. args.Add(1);
  163. args.Add(ddcArg.CenterFreqs.Select(m => m.ToString()));
  164. foreach (var freqItem in ddcArg.DdcSigList)
  165. {
  166. int mutil = SigCalcUtil.CalcMutil(adArg.ClockFreq / adArg.Mutil, freqItem.BandWidth);
  167. args.Add(freqItem.ChNo);
  168. args.Add(freqItem.UpFreq.E6m().ToString());
  169. args.Add(freqItem.DownFreq.E6m().ToString());
  170. args.Add(mutil);
  171. args.Add(freqItem.SigName);
  172. }
  173. });
  174. if (AdLogNotify != null)
  175. {
  176. cmd = cmd.WithStandardErrorPipe(PipeTarget.ToDelegate(OnAdLog))
  177. .WithStandardOutputPipe(PipeTarget.ToDelegate(OnAdLog));
  178. }
  179. DDCTsk = cmd.ExecuteAsync(token);
  180. var adResult = new AdcResult();
  181. var folderTime = adArg.StartTime.Format("yyyyMMdd_HH");
  182. var nameTime = adArg.StartTime.Format("yyyyMMddHHmmss");
  183. foreach (var freqItem in ddcArg.DdcSigList)
  184. {
  185. int mutil = SigCalcUtil.CalcMutil(adArg.ClockFreq / adArg.Mutil, freqItem.BandWidth);
  186. double upFreqMHz = freqItem.UpFreq.E6m();
  187. double downFreqMHz = freqItem.DownFreq.E6m();
  188. var fs = adArg.ClockFreq / adArg.Mutil / mutil;
  189. var foldername = "{0:yyyyMMdd_HH}";
  190. var filename = Path.Combine(adArg.StorePath, "{0:yyyyMMdd_HH}", $"{{0:yyyyMMddHHmmss}}_{freqItem.SigName}_{upFreqMHz}MHz_{downFreqMHz}MHz_C{fs}_CH{freqItem.ChNo}.dat");
  191. var fileItem = new AdcFile()
  192. {
  193. //StartTime = adArg.StartTime,
  194. //ChNum = freqItem.ChNo,
  195. //SatCode = freqItem.SigName,
  196. //UpFreq = freqItem.UpFreq,
  197. //DownFreq = freqItem.DownFreq,
  198. //BandWidth = freqItem.BandWidth,
  199. //Mutil = mutil * adArg.Mutil,
  200. //DDCMutil = mutil,
  201. //Fs = (int)(adArg.ClockFreq * 1e6 / adArg.Mutil / mutil),
  202. //FolderName = foldername,
  203. //FileName = filename
  204. };
  205. adResult.FileList.Add(fileItem);
  206. }
  207. StartRestartDdc();
  208. var result = ExeResult.Create(adResult, cmd.Arguments, DateTime.Now, DateTime.MaxValue, 0, "");
  209. return Task.FromResult(result);
  210. }
  211. /// <summary>
  212. /// 停止采集
  213. /// </summary>
  214. public static async Task StopAdc()
  215. {
  216. DDCOneStopTimer?.Change(Timeout.Infinite, Timeout.Infinite);
  217. DDCRestartTimer?.Change(Timeout.Infinite, Timeout.Infinite);
  218. if (lastAdArg != null && lastAdArg.CardType == AdCardType.QFCarder)
  219. {
  220. if (File.Exists(QFStopExe))
  221. {
  222. await Cli.Wrap(QFStopExe).ExecuteAsync();
  223. }
  224. }
  225. ProcessUtil.KillProcessByName(CliFile);
  226. }
  227. /// <summary>
  228. /// 设置采集参数
  229. /// </summary>
  230. /// <param name="options"></param>
  231. private static void SetAppCfg(AdcOptions options)
  232. {
  233. string cardTypeDesc = options.CardType.ToString("g");
  234. string cfgContent = $"DllPath={cardTypeDesc}\r\nDllName = {cardTypeDesc}.dll\r\nFilePath = {options.StorePath}";
  235. File.WriteAllText(CliAppCfg, cfgContent);
  236. }
  237. public static void StartLastTask()
  238. {
  239. DirectoryUtil.CreateIfNotExists(ParamsPath);
  240. if (File.Exists(AdArgFile))
  241. {
  242. _adArgs = JsonSerializer.Deserialize<Dictionary<string, AdcOptions>>(AdArgFile);
  243. }
  244. if (File.Exists(DdcArgFile))
  245. {
  246. _ddcArgs = JsonSerializer.Deserialize<Dictionary<string, DdcOptions>>(DdcArgFile);
  247. }
  248. if (_adArgs.IsNullOrEmpty() || _ddcArgs.IsNullOrEmpty()) return;
  249. StartDdcKeepInternal();
  250. }
  251. private static void AutoStopAdDdc(object obj)
  252. {
  253. StopAdc();
  254. }
  255. private static void StartRestartDdc()
  256. {
  257. var now = DateTime.Now;
  258. var addHour = now.Minute > 30 ? 2 : 1;
  259. var restartTime = now.AddHours(addHour).ClearMinute().AddMinutes(2);
  260. DDCRestartTimer.Change((int)(restartTime - now).TotalMilliseconds, Timeout.Infinite);
  261. }
  262. private static void RestartDdc(object obj)
  263. {
  264. StartDdcKeepInternal();
  265. }
  266. private static void InitAdcConfig(AdcOptions adArg)
  267. {
  268. lastAdArg = adArg;
  269. DeleteAdParams();
  270. SetAppCfg(adArg);
  271. }
  272. private static Command BuildDdcCommand(AdcOptions options, Action<string> handline)
  273. {
  274. DirectoryUtil.CreateIfNotExists(options.StorePath);
  275. var cmd = CliWrap.Cli.Wrap(CliFile)
  276. .WithWorkingDirectory(CliPath)
  277. .WithValidation(CommandResultValidation.None)
  278. .WithArguments(args =>
  279. {
  280. args.Add(2);
  281. args.Add(DateTimeUtil.To1970s(options.StartTime));
  282. args.Add(options.ClockType.ToString("D"));
  283. args.Add(options.TriggerMode.ToString("D"));
  284. args.Add(options.DdcFreq.E6m().ToString());
  285. args.Add(options.ClockFreq.E6m().ToString());
  286. args.Add(options.Mutil);
  287. args.Add(options.ChCount);
  288. args.Add(options.StorePath);
  289. args.Add(options.TimeLen);
  290. args.Add(1);
  291. args.Add(options.GetCenterFreqs().Select(m => m.ToString()));
  292. foreach (var ch in options.Channels)
  293. {
  294. foreach (var sigGroup in ch.Signals.GroupBy(m => new { m.DownFreq, m.BandWidth }))
  295. {
  296. var sig = sigGroup.Key;
  297. int mutil = SigCalcUtil.CalcMutil(options.ClockFreq / options.Mutil, sig.BandWidth);
  298. args.Add(ch.ChNum);
  299. args.Add("0");
  300. args.Add(sig.DownFreq.E6m().ToString());
  301. args.Add(mutil);
  302. args.Add("0");
  303. }
  304. }
  305. });
  306. if (handline != null)
  307. {
  308. cmd = cmd.WithStandardErrorPipe(PipeTarget.ToDelegate(handline))
  309. .WithStandardOutputPipe(PipeTarget.ToDelegate(handline));
  310. }
  311. return cmd;
  312. }
  313. private static AdcResult BuildDdcResult(AdcOptions options)
  314. {
  315. var adcResult = new AdcResult(options.StartTime, options.StorePath);
  316. var folderTime = options.StartTime.Format("yyyyMMdd_HH");
  317. var nameTime = options.StartTime.Format("yyyyMMddHHmmss");
  318. foreach (var ch in options.Channels)
  319. {
  320. foreach (var sigGroup in ch.Signals.GroupBy(m => new { m.DownFreq, m.BandWidth }))
  321. {
  322. var sigKey = sigGroup.Key;
  323. int mutil = SigCalcUtil.CalcMutil(options.ClockFreq / options.Mutil, sigKey.BandWidth);
  324. double downFreqMHz = sigKey.DownFreq.E6m();
  325. var fs = options.ClockFreq / options.Mutil / mutil;
  326. string sourceFile = Path.Combine(options.StorePath, folderTime, $"{nameTime}_0_0MHz_{downFreqMHz}MHz_C{fs}_CH{ch.ChNum}.dat");
  327. foreach (var sig in sigGroup)
  328. {
  329. AdcFile fileItem = new AdcFile(
  330. options.StartTime,
  331. sig.SatCode,
  332. ch.RecCode,
  333. sig.FreqPoint,
  334. sig.BandWidth,
  335. SigCalcUtil.CalcFs(options.ClockFreq, sig.BandWidth, options.Mutil),
  336. ch.ChNum,
  337. options.StorePath,
  338. sig.UpFreq,
  339. sig.DownFreq
  340. );
  341. string targetFile = fileItem.GetFullName();
  342. DirectoryUtil.CreateIfNotExists(Path.GetDirectoryName(targetFile));
  343. File.Move(sourceFile, targetFile, true);
  344. adcResult.FileList.Add(fileItem);
  345. }
  346. }
  347. }
  348. return adcResult;
  349. }
  350. private static void SaveAdParams()
  351. {
  352. if (_adArgs != null)
  353. {
  354. var adArgContent = JsonSerializer.Serialize(_adArgs, new JsonSerializerOptions()
  355. {
  356. WriteIndented = true
  357. });
  358. File.WriteAllText(AdArgFile, adArgContent);
  359. }
  360. if (_ddcArgs != null)
  361. {
  362. var ddcArgContent = JsonSerializer.Serialize(_ddcArgs, new JsonSerializerOptions()
  363. {
  364. WriteIndented = true
  365. });
  366. File.WriteAllText(DdcArgFile, ddcArgContent);
  367. }
  368. }
  369. private static void DeleteAdParams()
  370. {
  371. FileUtil.DeleteIfExists(AdArgFile);
  372. FileUtil.DeleteIfExists(DdcArgFile);
  373. }
  374. private static (AdcOptions adArg, DdcOptions ddcArg) GetAdDdcArg()
  375. {
  376. AdcOptions adArg = lastAdArg;
  377. DdcOptions ddcArg = null;
  378. if (_ddcArgs.Count == 1)
  379. {
  380. ddcArg = _ddcArgs.First().Value;
  381. }
  382. else
  383. {
  384. adArg.Mutil = _adArgs.Min(m => m.Value.Mutil);
  385. adArg.ChCount = _adArgs.Max(m => m.Value.ChCount);
  386. ddcArg = new DdcOptions();
  387. List<DdcSignal> freqItems = new List<DdcSignal>();
  388. foreach (var item in _ddcArgs)
  389. {
  390. if (ddcArg.CenterFreqs == null || ddcArg.CenterFreqs.Length < item.Value.CenterFreqs.Length)
  391. {
  392. ddcArg.CenterFreqs = item.Value.CenterFreqs;
  393. }
  394. foreach (var freqItem in item.Value.DdcSigList)
  395. {
  396. if (freqItems.Any(m =>
  397. m.ChNo == freqItem.ChNo
  398. && m.UpFreq == freqItem.UpFreq
  399. && m.DownFreq == freqItem.DownFreq
  400. && m.BandWidth == freqItem.BandWidth
  401. && m.SigName == freqItem.SigName))
  402. continue;
  403. freqItems.Add(freqItem);
  404. }
  405. ddcArg.DdcSigList = freqItems;
  406. }
  407. }
  408. return (adArg, ddcArg);
  409. }
  410. private static void OnAdLog(string message)
  411. {
  412. AdLogNotify.InvokeSafely(null, new AdcMessageEventArgs(message));
  413. }
  414. }
  415. }