123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- using CliWrap;
- using CliWrap.Buffered;
- using Ips.Library.Basic;
- using Ips.Library.Entity;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Reflection.Metadata;
- using System.Text;
- using System.Text.Json;
- using System.Text.Json.Serialization;
- using System.Threading;
- using System.Threading.Tasks;
- namespace Ips.AdcAlgorithm
- {
- public static class AdgUtil
- {
- static AdgUtil()
- {
- DirectoryUtil.CreateIfNotExists(ParamsPath);
- }
- static readonly string CliPath = PathUtil.GetBasePath("ipscli", "adg");
- static readonly string CliFile = Path.Combine(CliPath, "adg.exe");
- static readonly string CliAppCfg = Path.Combine(CliPath, "app.cfg");
- static readonly string ParamsPath = PathUtil.GetBasePath("AdParams");
- static readonly string AdArgFile = Path.Combine(ParamsPath, "adarg.json");
- static readonly string DdcArgFile = Path.Combine(ParamsPath, "ddcarg.json");
- static readonly string QFStopExe = Path.Combine(CliPath, "stop.exe");
- static CommandTask<CommandResult> DDCTsk;
- static Timer DDCOneStopTimer = new Timer(AutoStopAdDdc, null, Timeout.Infinite, Timeout.Infinite);
- static Timer DDCRestartTimer = new Timer(RestartDdc, null, Timeout.Infinite, Timeout.Infinite);
- static AdcOptions lastAdArg;
- static Dictionary<string, AdcOptions> _adArgs = new Dictionary<string, AdcOptions>();
- static Dictionary<string, DdcOptions> _ddcArgs = new Dictionary<string, DdcOptions>();
- public static event EventHandler<AdcMessageEventArgs> AdLogNotify;
- public static async Task<ExeResult<AdcResult>> StartAdc(AdcOptions options, Action<string> handline = null, CancellationToken token = default)
- {
- //停止采集
- await StopAdc();
- //修改配置
- SetAppCfg(options);
- if (options.StartTime < DateTime.Now.AddSeconds(AdcConst.MinWaitTime))
- options.StartTime = DateTime.Now.AddSeconds(AdcConst.MinWaitTime);
- DirectoryUtil.CreateIfNotExists(options.StorePath);
- var cmd = CliWrap.Cli.Wrap(CliFile)
- .WithWorkingDirectory(CliPath)
- .WithValidation(CommandResultValidation.None)
- .WithArguments(args =>
- {
- args.Add(1);
- args.Add(DateTimeUtil.To1970s(options.StartTime));
- args.Add(options.ClockType.ToString("D"));
- args.Add(options.TriggerMode.ToString("D"));
- args.Add(options.DdcFreq.E6m().ToString());
- args.Add(options.ClockFreq.E6m().ToString());
- args.Add(options.Mutil == 1 ? 0 : options.Mutil);
- args.Add(options.ChCount);
- args.Add(options.StorePath, true);
- args.Add(options.TimeLen);
- });
- if (handline != null)
- {
- cmd = cmd.WithStandardErrorPipe(PipeTarget.ToDelegate(handline))
- .WithStandardOutputPipe(PipeTarget.ToDelegate(handline));
- }
- var result = await cmd.ExecuteAsync(token);
- var adcResult = AdcFileUtil.BuildAdcResult(options, AdMode.ADC);
- return ExeResult.Create(adcResult, cmd.Arguments, result.StartTime, result.ExitTime, result.ExitCode);
- }
- /// <summary>
- /// DDC采集
- /// </summary>
- public static async Task<ExeResult<AdcResult>> StartDdcOne(AdcOptions options, Action<string> handline = null, CancellationToken token = default)
- {
- await StopAdc();
- SetAppCfg(options);
- if (options.StartTime < DateTime.Now.AddSeconds(AdcConst.MinWaitTime))
- options.StartTime = DateTime.Now.AddSeconds(AdcConst.MinWaitTime);
- var cmd = BuildDdcCommand(options, handline);
- //由于DDC采集不会停止,到时间后结束进程
- var stopTimeSpan = options.StartTime.AddSeconds(options.TimeLen + AdcConst.DDCFindFileDelay) - DateTime.Now;
- DDCOneStopTimer.Change(stopTimeSpan, Timeout.InfiniteTimeSpan);
- var cmdRes = await cmd.ExecuteAsync(token);
- var adcResult = BuildDdcResult(options);
- return ExeResult.Create(adcResult, cmd.Arguments, cmdRes.StartTime, cmdRes.ExitTime, cmdRes.ExitCode);
- }
- /// <summary>
- /// DDC持续采集
- /// </summary>
- /// <param name="adArg">采集参数</param>
- /// <param name="ddcArg">DDC参数</param>
- /// <returns></returns>
- public static async Task<ExeResult<AdcResult>> StartDdcKeep(AdcOptions options, Action<AdcResult> resultCallback, Action<string> handline = null, CancellationToken token = default)
- {
- //停止原有采集
- await StopAdc();
- //设置配置文件
- SetAppCfg(options);
- if (options.StartTime < DateTime.Now.AddSeconds(AdcConst.MinWaitTime))
- options.StartTime = DateTime.Now.AddSeconds(AdcConst.MinWaitTime);
- var startTime = options.StartTime;
- options.StartTime = startTime.ClearSecond().AddSeconds(Math.Ceiling(startTime.Second * 1.0 / options.TimeLen) * options.TimeLen);
- var cmd = BuildDdcCommand(options, handline);
- var adcTsk = cmd.ExecuteAsync(token);
- var outTsk = Task.Run(async () =>
- {
- while (!adcTsk.Task.IsCompleted)
- {
- await Task.Delay(options.StartTime.AddSeconds(options.TimeLen + AdcConst.DDCFindFileDelay) - DateTime.Now, token);
- var adcResult = BuildDdcResult(options);
- resultCallback?.Invoke(adcResult);
- options.StartTime = options.StartTime.AddSeconds(options.TimeLen);
- }
- });
- await Task.WhenAll(adcTsk, outTsk);
- var cmdRes = await adcTsk;
- return ExeResult.Create(new AdcResult(options.StartTime, options.StorePath), cmd.Arguments, cmdRes.StartTime, cmdRes.ExitTime, cmdRes.ExitCode);
- }
- /// <summary>
- /// DDC持续采集,共享采集
- /// </summary>
- /// <param name="sharedId">共享编号</param>
- /// <param name="adArg">采集参数</param>
- /// <param name="ddcArg">DDC参数</param>
- /// <returns></returns>
- public static Task<ExeResult<AdcResult>> StartDdcShared(string sharedId, AdcOptions adArg, DdcOptions ddcArg, CancellationToken token)
- {
- lastAdArg = adArg;
- _adArgs[sharedId] = adArg;
- _ddcArgs[sharedId] = ddcArg;
- SaveAdParams();
- var result = StartDdcKeepInternal(token);
- return result;
- }
- private static Task<ExeResult<AdcResult>> StartDdcKeepInternal(CancellationToken token = default)
- {
- //StopAdc();
- var adDdcArg = GetAdDdcArg();
- AdcOptions adArg = adDdcArg.adArg;
- DdcOptions ddcArg = adDdcArg.ddcArg;
- SetAppCfg(adArg);
- var startTime = DateTime.Now.AddSeconds(30);
- adArg.StartTime = startTime.ClearSecond().AddSeconds(Math.Ceiling(startTime.Second * 1.0 / 15) * 15);
- DirectoryUtil.CreateIfNotExists(adArg.StorePath);
- var cmd = CliWrap.Cli.Wrap(CliFile)
- .WithWorkingDirectory(CliPath)
- .WithValidation(CommandResultValidation.None)
- .WithArguments(args =>
- {
- args.Add(2);
- args.Add(DateTimeUtil.To1970s(adArg.StartTime));
- args.Add(adArg.ClockType.ToString("D"));
- args.Add(adArg.TriggerMode.ToString("D"));
- args.Add(adArg.DdcFreq.E6m().ToString());
- args.Add(adArg.ClockFreq.E6m().ToString());
- args.Add(adArg.Mutil);
- args.Add(adArg.ChCount);
- args.Add(adArg.StorePath);
- args.Add(adArg.TimeLen);
- args.Add(1);
- args.Add(ddcArg.CenterFreqs.Select(m => m.ToString()));
- foreach (var freqItem in ddcArg.DdcSigList)
- {
- int mutil = SigCalcUtil.CalcMutil(adArg.ClockFreq / adArg.Mutil, freqItem.BandWidth);
- args.Add(freqItem.ChNo);
- args.Add(freqItem.UpFreq.E6m().ToString());
- args.Add(freqItem.DownFreq.E6m().ToString());
- args.Add(mutil);
- args.Add(freqItem.SigName);
- }
- });
- if (AdLogNotify != null)
- {
- cmd = cmd.WithStandardErrorPipe(PipeTarget.ToDelegate(OnAdLog))
- .WithStandardOutputPipe(PipeTarget.ToDelegate(OnAdLog));
- }
- DDCTsk = cmd.ExecuteAsync(token);
- var adResult = new AdcResult();
- var folderTime = adArg.StartTime.Format("yyyyMMdd_HH");
- var nameTime = adArg.StartTime.Format("yyyyMMddHHmmss");
- foreach (var freqItem in ddcArg.DdcSigList)
- {
- int mutil = SigCalcUtil.CalcMutil(adArg.ClockFreq / adArg.Mutil, freqItem.BandWidth);
- double upFreqMHz = freqItem.UpFreq.E6m();
- double downFreqMHz = freqItem.DownFreq.E6m();
- var fs = adArg.ClockFreq / adArg.Mutil / mutil;
- var foldername = "{0:yyyyMMdd_HH}";
- var filename = Path.Combine(adArg.StorePath, "{0:yyyyMMdd_HH}", $"{{0:yyyyMMddHHmmss}}_{freqItem.SigName}_{upFreqMHz}MHz_{downFreqMHz}MHz_C{fs}_CH{freqItem.ChNo}.dat");
- var fileItem = new AdcFile()
- {
- //StartTime = adArg.StartTime,
- //ChNum = freqItem.ChNo,
- //SatCode = freqItem.SigName,
- //UpFreq = freqItem.UpFreq,
- //DownFreq = freqItem.DownFreq,
- //BandWidth = freqItem.BandWidth,
- //Mutil = mutil * adArg.Mutil,
- //DDCMutil = mutil,
- //Fs = (int)(adArg.ClockFreq * 1e6 / adArg.Mutil / mutil),
- //FolderName = foldername,
- //FileName = filename
- };
- adResult.FileList.Add(fileItem);
- }
- StartRestartDdc();
- var result = ExeResult.Create(adResult, cmd.Arguments, DateTime.Now, DateTime.MaxValue, 0, "");
- return Task.FromResult(result);
- }
- /// <summary>
- /// 停止采集
- /// </summary>
- public static async Task StopAdc()
- {
- DDCOneStopTimer?.Change(Timeout.Infinite, Timeout.Infinite);
- DDCRestartTimer?.Change(Timeout.Infinite, Timeout.Infinite);
- if (lastAdArg != null && lastAdArg.CardType == AdCardType.QFCarder)
- {
- if (File.Exists(QFStopExe))
- {
- await Cli.Wrap(QFStopExe).ExecuteAsync();
- }
- }
- ProcessUtil.KillProcessByName(CliFile);
- }
- /// <summary>
- /// 设置采集参数
- /// </summary>
- /// <param name="options"></param>
- private static void SetAppCfg(AdcOptions options)
- {
- string cardTypeDesc = options.CardType.ToString("g");
- string cfgContent = $"DllPath={cardTypeDesc}\r\nDllName = {cardTypeDesc}.dll\r\nFilePath = {options.StorePath}";
- File.WriteAllText(CliAppCfg, cfgContent);
- }
- public static void StartLastTask()
- {
- DirectoryUtil.CreateIfNotExists(ParamsPath);
- if (File.Exists(AdArgFile))
- {
- _adArgs = JsonSerializer.Deserialize<Dictionary<string, AdcOptions>>(AdArgFile);
- }
- if (File.Exists(DdcArgFile))
- {
- _ddcArgs = JsonSerializer.Deserialize<Dictionary<string, DdcOptions>>(DdcArgFile);
- }
- if (_adArgs.IsNullOrEmpty() || _ddcArgs.IsNullOrEmpty()) return;
- StartDdcKeepInternal();
- }
- private static void AutoStopAdDdc(object obj)
- {
- StopAdc();
- }
- private static void StartRestartDdc()
- {
- var now = DateTime.Now;
- var addHour = now.Minute > 30 ? 2 : 1;
- var restartTime = now.AddHours(addHour).ClearMinute().AddMinutes(2);
- DDCRestartTimer.Change((int)(restartTime - now).TotalMilliseconds, Timeout.Infinite);
- }
- private static void RestartDdc(object obj)
- {
- StartDdcKeepInternal();
- }
- private static void InitAdcConfig(AdcOptions adArg)
- {
- lastAdArg = adArg;
- DeleteAdParams();
- SetAppCfg(adArg);
- }
- private static Command BuildDdcCommand(AdcOptions options, Action<string> handline)
- {
- DirectoryUtil.CreateIfNotExists(options.StorePath);
- var cmd = CliWrap.Cli.Wrap(CliFile)
- .WithWorkingDirectory(CliPath)
- .WithValidation(CommandResultValidation.None)
- .WithArguments(args =>
- {
- args.Add(2);
- args.Add(DateTimeUtil.To1970s(options.StartTime));
- args.Add(options.ClockType.ToString("D"));
- args.Add(options.TriggerMode.ToString("D"));
- args.Add(options.DdcFreq.E6m().ToString());
- args.Add(options.ClockFreq.E6m().ToString());
- args.Add(options.Mutil);
- args.Add(options.ChCount);
- args.Add(options.StorePath);
- args.Add(options.TimeLen);
- args.Add(1);
- args.Add(options.GetCenterFreqs().Select(m => m.ToString()));
- foreach (var ch in options.Channels)
- {
- foreach (var sigGroup in ch.Signals.GroupBy(m => new { m.DownFreq, m.BandWidth }))
- {
- var sig = sigGroup.Key;
- int mutil = SigCalcUtil.CalcMutil(options.ClockFreq / options.Mutil, sig.BandWidth);
- args.Add(ch.ChNum);
- args.Add("0");
- args.Add(sig.DownFreq.E6m().ToString());
- args.Add(mutil);
- args.Add("0");
- }
- }
- });
- if (handline != null)
- {
- cmd = cmd.WithStandardErrorPipe(PipeTarget.ToDelegate(handline))
- .WithStandardOutputPipe(PipeTarget.ToDelegate(handline));
- }
- return cmd;
- }
- private static AdcResult BuildDdcResult(AdcOptions options)
- {
- var adcResult = new AdcResult(options.StartTime, options.StorePath);
- var folderTime = options.StartTime.Format("yyyyMMdd_HH");
- var nameTime = options.StartTime.Format("yyyyMMddHHmmss");
- foreach (var ch in options.Channels)
- {
- foreach (var sigGroup in ch.Signals.GroupBy(m => new { m.DownFreq, m.BandWidth }))
- {
- var sigKey = sigGroup.Key;
- int mutil = SigCalcUtil.CalcMutil(options.ClockFreq / options.Mutil, sigKey.BandWidth);
- double downFreqMHz = sigKey.DownFreq.E6m();
- var fs = options.ClockFreq / options.Mutil / mutil;
- string sourceFile = Path.Combine(options.StorePath, folderTime, $"{nameTime}_0_0MHz_{downFreqMHz}MHz_C{fs}_CH{ch.ChNum}.dat");
- foreach (var sig in sigGroup)
- {
- AdcFile fileItem = new AdcFile(
- options.StartTime,
- sig.SatCode,
- ch.RecCode,
- sig.FreqPoint,
- sig.BandWidth,
- SigCalcUtil.CalcFs(options.ClockFreq, sig.BandWidth, options.Mutil),
- ch.ChNum,
- options.StorePath,
- sig.UpFreq,
- sig.DownFreq
- );
- string targetFile = fileItem.GetFullName();
- DirectoryUtil.CreateIfNotExists(Path.GetDirectoryName(targetFile));
- File.Move(sourceFile, targetFile, true);
- adcResult.FileList.Add(fileItem);
- }
- }
- }
- return adcResult;
- }
- private static void SaveAdParams()
- {
- if (_adArgs != null)
- {
- var adArgContent = JsonSerializer.Serialize(_adArgs, new JsonSerializerOptions()
- {
- WriteIndented = true
- });
- File.WriteAllText(AdArgFile, adArgContent);
- }
- if (_ddcArgs != null)
- {
- var ddcArgContent = JsonSerializer.Serialize(_ddcArgs, new JsonSerializerOptions()
- {
- WriteIndented = true
- });
- File.WriteAllText(DdcArgFile, ddcArgContent);
- }
- }
- private static void DeleteAdParams()
- {
- FileUtil.DeleteIfExists(AdArgFile);
- FileUtil.DeleteIfExists(DdcArgFile);
- }
- private static (AdcOptions adArg, DdcOptions ddcArg) GetAdDdcArg()
- {
- AdcOptions adArg = lastAdArg;
- DdcOptions ddcArg = null;
- if (_ddcArgs.Count == 1)
- {
- ddcArg = _ddcArgs.First().Value;
- }
- else
- {
- adArg.Mutil = _adArgs.Min(m => m.Value.Mutil);
- adArg.ChCount = _adArgs.Max(m => m.Value.ChCount);
- ddcArg = new DdcOptions();
- List<DdcSignal> freqItems = new List<DdcSignal>();
- foreach (var item in _ddcArgs)
- {
- if (ddcArg.CenterFreqs == null || ddcArg.CenterFreqs.Length < item.Value.CenterFreqs.Length)
- {
- ddcArg.CenterFreqs = item.Value.CenterFreqs;
- }
- foreach (var freqItem in item.Value.DdcSigList)
- {
- if (freqItems.Any(m =>
- m.ChNo == freqItem.ChNo
- && m.UpFreq == freqItem.UpFreq
- && m.DownFreq == freqItem.DownFreq
- && m.BandWidth == freqItem.BandWidth
- && m.SigName == freqItem.SigName))
- continue;
- freqItems.Add(freqItem);
- }
- ddcArg.DdcSigList = freqItems;
- }
- }
- return (adArg, ddcArg);
- }
- private static void OnAdLog(string message)
- {
- AdLogNotify.InvokeSafely(null, new AdcMessageEventArgs(message));
- }
- }
- }
|