zoulei 1 ano atrás
pai
commit
e2e8273951

+ 1 - 1
Service/X2D1NoRefTaskServer/Controllers/HistoryTaskProcessingController.cs

@@ -39,7 +39,7 @@ namespace X2D1NoRefTaskServer.Controllers
             try
             {
               
-                _service.StartAsync(dto);
+                _service.StartHistoryAsync(dto);
                 return Success();
             }
             catch (Exception ex)

+ 280 - 4
Service/X2D1NoRefTaskServer/Service/TaskService.cs

@@ -24,7 +24,279 @@ namespace X2D1NoRefTaskServer.Service
             else
                 this.baseUrl = posPlatformAddr + "/api/";
         }
-        public void StartAsync(X2D1NoRefTaskHandleDto dto)
+
+        /// <summary>
+        /// 启动历史任务
+        /// </summary>
+        /// <param name="dto"></param>
+        public void StartHistoryAsync(X2D1NoRefTaskHandleDto dto)
+        {
+            cts = new CancellationTokenSource();
+            if (!Directory.Exists(dto.CapDir))
+            {
+                StopTask(dto.ID, EnumTaskStopType.Error, $"文件路径[{dto.CapDir}]不存在,任务结束");
+                return;
+            }
+            if (dto.DateDirFormat.Contains("\\"))
+            {
+                StopTask(dto.ID, EnumTaskStopType.Error, $"子目录日期格式不能包含多级目录格式");
+                return;
+            }
+
+            LogHelper.Info($"【任务{dto.ID}】开始执行...");
+            int.TryParse(ConfigurationManager.AppSettings["PosDtoFactor"], out int posDtoFactor);
+            if (posDtoFactor == 0) posDtoFactor = 1;//定位时时差系数
+            LogHelper.Info($"【任务{dto.ID}】定位时差系数={posDtoFactor}");
+
+            Task.Run(async () =>
+            {
+                bool canConnected = CanGetSatIdFromMySql();
+                DateTime preTime = dto.StartTime;
+                int formatFlag;
+                if (string.IsNullOrWhiteSpace(dto.DateDirFormat))
+                {
+                    //没有日期目录,处理完目录中的数据后停止任务
+                    formatFlag = 0;
+                }
+                else if (dto.DateDirFormat.ToLower().EndsWith("dd"))
+                {
+                    //处理完一个目录后跳转到第二天的目录
+                    formatFlag = 1;
+                }
+                else if (dto.DateDirFormat.ToUpper().EndsWith("HH"))
+                {
+                    //处理完一个目录后跳转到下一个小时的目录
+                    formatFlag = 2;
+                }
+                else
+                {
+                    StopTask(dto.ID, EnumTaskStopType.Error, $"执行异常,不支持的日期目录格式");
+                    return;
+                }
+
+                while (!cts.IsCancellationRequested && preTime <= dto.EndTime)
+                {
+                    string filesDir = dto.CapDir;
+                    try
+                    {
+                        if (formatFlag != 0)
+                        {
+                            filesDir = Path.Combine(dto.CapDir, $"{preTime.ToString(dto.DateDirFormat)}");//yyyyMMdd
+                        }
+
+                        IEnumerable<string> files;
+                        if (!Directory.Exists(filesDir))
+                        {
+                            LogHelper.Info($"【任务{dto.ID}】目录[{filesDir}]不存在,跳过此目录");
+                            ResetTime(formatFlag, ref preTime);
+                            continue;
+                        }
+                        LogHelper.Info($"【任务{dto.ID}】正在处理[{filesDir}]目录中的数据...");
+                        files = Directory.EnumerateFiles(filesDir, "*.dat");
+                        if (!files.Any())
+                        {
+                            LogHelper.Info($"【任务{dto.ID}】目录[{filesDir}]中没有文件,跳过此目录");
+                            ResetTime(formatFlag, ref preTime);
+                            continue;
+                        }
+
+                        IOrderedEnumerable<IGrouping<DateTime, HistoryFile>> groups = null;
+                        groups = files.Select(f => FileToHistoryFile(dto, f, canConnected)).GroupBy(m => m.CapTime).OrderBy(m => m.Key);
+                        foreach (var item in groups)
+                        {
+                            if (cts.IsCancellationRequested) break;
+
+                            var xdgbInfos = item.GroupBy(m => m.XdIndex);
+                            foreach (var xdInfos in xdgbInfos)
+                            {
+                                var finfos = xdInfos.ToList();
+                                var capTime = finfos.First().CapTime;
+                                if (capTime < dto.StartTime) continue;
+                                if (capTime > dto.EndTime) break;
+                                if (finfos.Count < 3)
+                                {
+                                    LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻文件数量只有{finfos.Count}个,跳过此组数据");
+                                    continue;
+                                }
+                                //超短波信号
+                                var dinfo = finfos.FirstOrDefault(m => m.Ch == 1);
+                                if (dinfo == null)
+                                {
+                                    LogHelper.Warning($"【任务{dto.ID}】{capTime:yyyyMMddHHmmss}时刻未找到超短波信号ch1文件,跳过此组数据");
+                                    continue;
+                                }
+                                var taskSig = dto.Sigs.FirstOrDefault(p => p.FreqUp == dinfo.FreqHz);
+                                if (taskSig == null)
+                                {
+                                    continue;//跳过不是任务处理的频点
+                                }
+                                //主星
+                                var minfo = finfos.FirstOrDefault(m => m.Ch == 2);
+                                if (minfo == null)
+                                {
+                                    LogHelper.Warning($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6}],{capTime:yyyyMMddHHmmss}时刻未找到主星信号ch2文件,跳过此组数据");
+                                    continue;
+                                }
+                                //邻1
+                                var ninfo = finfos.FirstOrDefault(m => m.Ch == 3);
+                                if (ninfo == null)
+                                {
+                                    LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6}],{capTime:yyyyMMddHHmmss}时刻未找到邻星信号ch3文件,跳过此组数据");
+                                    continue;
+                                }
+                                try
+                                {
+                                    var delay1 = taskSig.SigDelay.FirstOrDefault(p => p.SatInfoSatCode == minfo.SatId)?.Delay;
+                                    var delay2 = taskSig.SigDelay.FirstOrDefault(p => p.SatInfoSatCode == ninfo.SatId)?.Delay;
+                                    if (delay1 == null) delay1 = 0;
+                                    if (delay2 == null) delay2 = 0;
+                                    LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6}],主星[{minfo.SatId}],转发时延{delay1}us");
+                                    LogHelper.Info($"【任务{dto.ID}】信号[{taskSig.FreqUp / 1e6}],邻星[{ninfo.SatId}],转发时延{delay2}us");
+                                    string mainFile = await HttpHelper.UploadFileAsync(minfo.FilePath, baseUrl + "File/UploadFileAsync", token: cts.Token);//主星文件
+                                    string adjaFile = await HttpHelper.UploadFileAsync(ninfo.FilePath, baseUrl + "File/UploadFileAsync", token: cts.Token);//邻星文件
+                                    string cdbFile = await HttpHelper.UploadFileAsync(dinfo.FilePath, baseUrl + "File/UploadFileAsync", token: cts.Token);//超短文件
+
+                                    DetectDto detectDto = new DetectDto()
+                                    {
+                                        file1 = cdbFile,//11局使用上行泄露信号进行检测
+                                        dmcType = taskSig.SigType,//上行信号检测目前的算法只能使用基于能量的KY或IBS检测
+                                        fsHz = minfo.FsHz,
+                                    };
+                                    detectDto.dmcType = detectDto.dmcType & ~EnumSigCheckTypeDto.DAMA;//DAMA不支持上行信号检测,在这里移除掉
+                                    if (detectDto.dmcType == EnumSigCheckTypeDto.DAMA)
+                                    {
+                                        LogHelper.Warning($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},上行信号不支持DAMA检测,请使用能量检测");
+                                        continue;
+                                    }
+                                    var deteResp = await HttpHelper.PostRequestAsync<List<DetectResDto>>(baseUrl + "DetectCg/DetectCalc", detectDto, token: cts.Token);
+                                    if (deteResp.code != 200)
+                                    {
+                                        LogHelper.Error($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻信号检测出错.{deteResp.msg}");
+                                        continue;
+                                    }
+                                    LogHelper.Info($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻信号检测完成,共{deteResp.data.Count}个时隙");
+                                    var smps = deteResp.data.Select(m => new SmpPosition(m.Start, m.Length)).ToList();//怎么补0?
+                                    var cgDto = new CpuCgMultiDto()
+                                    {
+                                        dtCenter = 260000,
+                                        dtRange = 50000,
+                                        file1 = cdbFile,
+                                        file2 = mainFile,
+                                        samplingRate = minfo.FsHz,
+                                        smpPositions = smps,
+                                        snrThreshold = 15,
+                                    };
+                                    var result1 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
+                                    if (result1.code != 200)
+                                    {
+                                        LogHelper.Error($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻主星超短CPU参估出错.{result1.msg}");
+                                        continue;
+                                    }
+                                    LogHelper.Info($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻主星超短CPU参估完成.");
+                                    cgDto = new CpuCgMultiDto()
+                                    {
+                                        dtCenter = 260000,
+                                        dtRange = 50000,
+                                        file1 = cdbFile,
+                                        file2 = adjaFile,
+                                        samplingRate = minfo.FsHz,
+                                        smpPositions = smps,
+                                        snrThreshold = 15,
+                                    };
+                                    var result2 = await HttpHelper.PostRequestAsync<List<CpuCgResDto>>(baseUrl + "DetectCg/CpuCgMultiCalc", cgDto, token: cts.Token);
+                                    if (result2.code != 200)
+                                    {
+                                        LogHelper.Error($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻邻星超短CPU参估出错.{result2.msg}");
+                                        continue;
+                                    }
+                                    LogHelper.Info($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻邻星超短CPU参估完成");
+                                    var data1 = result1.data;
+                                    var data2 = result2.data;
+                                    if (data1.Count != data2.Count || data1.Count != deteResp.data.Count)
+                                    {
+                                        LogHelper.Error($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻参估结果个数和检测结果个数不匹配");
+                                        continue;
+                                    }
+                                    for (int i = 0; i < data1.Count; i++)
+                                    {
+                                        try
+                                        {
+                                            if (cts.IsCancellationRequested) break;
+
+
+
+                                            X2D1NoXlNoParlPosDto x2D1 = new X2D1NoXlNoParlPosDto()
+                                            {
+                                                TaskID = dto.ID,
+                                                SigTime = minfo.CapTime.AddSeconds(data1[i].Smpstart / minfo.FsHz),
+                                                MainCode = minfo.SatId,
+                                                AdjaCode = ninfo.SatId,
+                                                //卫星转发某些频点可能有时延,无参定位由于不能抵消需要减去这个时延
+                                                SxDto = data1[i].Dt * posDtoFactor - data2[i].Dt * posDtoFactor - delay1.Value + delay2.Value,
+                                                SxDfo = data1[i].Df,
+                                                SxSnr = data1[i].Snr,
+                                                XdDto = data1[i].Dt * posDtoFactor - delay1.Value,
+                                                XdDfo = data2[i].Df,
+                                                XdSnr = data2[i].Snr,
+                                                SatTxLon = dto.CapLon,
+                                                SatTxLat = dto.CapLat,
+                                                CdbTxLon = dto.CapLon,
+                                                CdbTxLat = dto.CapLat,
+                                                FreqDown = minfo.FreqHz,
+                                                FreqUp = dinfo.FreqHz,
+                                                CheckRes = new CheckResDto()
+                                                {
+                                                    FileName = Path.GetFileName(dinfo.FilePath),
+                                                    ModRate = deteResp.data[i].ModRate,
+                                                    ModType = deteResp.data[i].ModType,
+                                                    SmpCount = deteResp.data[i].Length,
+                                                    SmpStart = deteResp.data[i].Start,
+                                                    UserName = deteResp.data[i].UserName,
+                                                    PosCheckType = deteResp.data[i].DmcType.GetEnumByDisplayName<EnumPosCheckTypeDto>(),
+                                                }
+                                            };
+                                            var result = await HttpHelper.PostRequestAsync<PosResDto>(baseUrl + "Pos/PosX2D1NoXlNoParAsync", x2D1);
+                                            if (result.code != 200)
+                                            {
+                                                LogHelper.Error($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻时隙位置{data1[i].Smpstart}定位异常.{result.msg}");
+                                            }
+                                        }
+                                        catch (Exception ex)
+                                        {
+                                            LogHelper.Error($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻时隙位置{data1[i].Smpstart}定位异常", ex);
+                                        }
+                                    }
+                                    LogHelper.Info($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻定位完成");
+
+                                }
+                                catch (Exception ex)
+                                {
+                                    LogHelper.Error($"【任务{dto.ID}】信号{taskSig.FreqUp / 1e6:f3},{capTime:yyyyMMddHHmmss}时刻文件处理异常", ex);
+                                    continue;
+                                }
+
+                            }
+
+
+                        }
+                        ResetTime(formatFlag, ref preTime);
+                        LogHelper.Info($"【任务{dto.ID}】目录[{filesDir}]中的数据处理完成");
+                    }
+                    catch (Exception ex)
+                    {
+                        LogHelper.Error($"【任务{dto.ID}】目录[{filesDir}]中的数据处理出错,跳过此目录", ex);
+                        ResetTime(formatFlag, ref preTime);
+                    }
+                }
+                StopTask(dto.ID, EnumTaskStopType.Properly, "数据处理完成,任务结束");
+            }, cts.Token);
+        }
+
+        /// <summary>
+        /// 启动实时任务
+        /// </summary>
+        /// <param name="dto"></param>
+        public void StarRealAsync(X2D1NoRefTaskHandleDto dto)
         {
             cts = new CancellationTokenSource();
             if (!Directory.Exists(dto.CapDir))
@@ -371,7 +643,7 @@ namespace X2D1NoRefTaskServer.Service
             return historyFile;
         }
 
-        int GetSatId(double freqdownMHz)
+        private int GetSatId(double freqdownMHz)
         {
             int satId = 0;
             string sql = $"select 卫星ID from freguencysatid where 下行 = '{freqdownMHz}'and 洋区 = 'I' LIMIT 1";
@@ -397,7 +669,7 @@ namespace X2D1NoRefTaskServer.Service
             }
             return satId;
         }
-        bool CanGetSatIdFromMySql()
+        private bool CanGetSatIdFromMySql()
         {
             string sql = $"select 卫星ID from freguencysatid where 下行 = '{0}'and 洋区 = 'I' LIMIT 1";
             try
@@ -410,7 +682,7 @@ namespace X2D1NoRefTaskServer.Service
                 return false;
             }
         }
-        void StopTask(int taskID, EnumTaskStopType type, string stopReason)
+        private void StopTask(int taskID, EnumTaskStopType type, string stopReason)
         {
             if (type == EnumTaskStopType.Properly)
             {
@@ -428,6 +700,10 @@ namespace X2D1NoRefTaskServer.Service
                 return;
             }
         }
+
+        /// <summary>
+        /// 停止任务
+        /// </summary>
         public void Stop()
         {
             cts?.Cancel();